Странный перевод запроса jOOQ для массива содержит функцию

У меня есть следующий тип в моей базе данных PostgreSQL:

myoptions text[]

Я использую конвертер jOOQ, так что у меня есть соответствующий тип Set в моей записи:

Set<String> myoptions

В моем запросе у меня есть следующее условие:

c.MYOPTIONS.contains(Sets.newHashSet("option1"))

который переводится в SQL следующим образом:

cast("c"."myoptions" as varchar) like ('%' || '[option1]' || '%') escape '!'

Это нормальное поведение?

Я хотел бы иметь что-то вроде:

c.myoptions @> ARRAY['option1']

or

'option1' = ANY(c.myoptions)

Заранее спасибо за помощь


person Manu    schedule 16.10.2016    source источник


Ответы (2)


jOOQ в настоящее время (начиная с версии 3.8) не распознает ваш пользовательский тип данных как тип данных массива в PostgreSQL, поэтому срабатывает поведение по умолчанию Field.contains(), то есть то, которое обрабатывает все значения как строки.

Для этого я создал запрос функции #5602. В качестве обходного пути вам, возможно, придется создать свой собственный, используя простой SQL :

public static <T, C extends Collection<T>> Condition contains(
    Field<? extends C> left, 
    C right
) {
    return DSL.condition("{0} @> {1}::text[]", left, DSL.val(right, left.getDataType()));
}

... который вы затем можете использовать как таковой:

contains(c.MYOPTIONS, Sets.newHashSet("option1"))
person Lukas Eder    schedule 19.10.2016
comment
Спасибо за вашу помощь. Не могли бы вы рассказать мне, как использовать вашу статическую функцию? - person Manu; 22.10.2016
comment
Спасибо, но 2 типа несовместимы, теперь у меня есть следующая ошибка: Неправильный 1-й тип аргумента. Найдено: 'org.jooq.TableField‹CopyRecord,java.util.Set‹java.lang.String››', требуется: 'org.jooq.Field‹? расширяет C›' - person Manu; 23.10.2016
comment
@Manu: извините, мой ответ был совершенно неправильным ... Пожалуйста, проверьте обновление. Первый аргумент по-прежнему является ссылкой на столбец, тогда как вторым аргументом должен быть тот Set<String>, который вы использовали изначально, а не массив. - person Lukas Eder; 23.10.2016
comment
Большое спасибо еще раз. Теперь у меня проблема с приведением типа: PSQLException: ОШИБКА: оператор не существует: text[] @› character Variing[] --- Потому что он генерирует следующий SQL: (c.myoptions @› ?::varchar[]) - person Manu; 23.10.2016
comment
Любая идея сделать общий бросок? Заранее спасибо. - person Manu; 25.10.2016
comment
@Manu: Извините, я сейчас в дороге. Вернемся к этому в ближайшее время. - person Lukas Eder; 25.10.2016
comment
@Manu: извините, я не могу думать ни о чем, кроме явного приведения значения обратно к ::text[] прямо сейчас. Вероятно, существует более глубокая проблема с тем фактом, что jOOQ обрабатывает все строки как varchar в PostgreSQL, а не как text, но я не уверен, что это все еще разумно обсуждать в контексте этого вопроса. - person Lukas Eder; 28.10.2016
comment
Ok ! спасибо за вашу помощь и, конечно же, большое спасибо за jOOQ! - person Manu; 01.11.2016

Пожалуйста, попробуйте следующее решение. Сработало в моем случае.

select.where(ARRAY_FIELD.contains(DSL.cast(DSL.array(VALUE), ARRAY_FIELD.getDataType())));
person Arnold Krutolevich    schedule 13.02.2018
comment
Это решило следующую ошибку для меня: Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts. - person Patrick Boos; 16.10.2019