[jOOQ/jOOQ#15980] Regression in PostgreSQL query using 'x' = ANY (ARRAY

[(SELECT ARRAY ['x'])]) style quantified comparison predicate on multi
dimensional arrays

This includes:

- [jOOQ/jOOQ#15982] Comparison predicates and quantified comparison
predicates should hint array type to org.jooq.impl.Array for empty
expression array casts
This commit is contained in:
Lukas Eder 2023-12-22 13:57:36 +01:00
parent edb209c5ab
commit 1fdb63b6fd
4 changed files with 23 additions and 3 deletions

View File

@ -46,6 +46,7 @@ import static org.jooq.impl.Cast.renderCastIf;
import static org.jooq.impl.Keywords.K_ARRAY;
import static org.jooq.impl.Keywords.K_INT;
import static org.jooq.impl.Names.N_ARRAY;
import static org.jooq.impl.Tools.ExtendedDataKey.DATA_EMPTY_ARRAY_BASE_TYPE;
import java.util.Collection;
import java.util.Set;
@ -107,7 +108,14 @@ final class Array<T> extends AbstractField<T[]> implements QOM.Array<T> {
break;
}
},
c -> c.visit(K_INT).sql("[]"),
c -> {
DataType<?> type = (DataType<?>) c.data(DATA_EMPTY_ARRAY_BASE_TYPE);
if (type != null && !type.isOther())
c.sql(type.getCastTypeName(ctx.configuration())).sql("[]");
else
c.visit(K_INT).sql("[]");
},
() -> fields.fields.length == 0 && REQUIRES_CAST.contains(ctx.dialect())
);

View File

@ -151,6 +151,10 @@ implements
else if (arg1 instanceof Array && ((Array<?>) arg1).fields.fields.length == 0)
ctx.data(ExtendedDataKey.DATA_EMPTY_ARRAY_BASE_TYPE, arg2.getDataType().getArrayComponentDataType(), c -> acceptDefault.apply(c, arg1, arg2));
else if (arg2 instanceof Array && ((Array<?>) arg2).fields.fields.length == 0)
ctx.data(ExtendedDataKey.DATA_EMPTY_ARRAY_BASE_TYPE, arg1.getDataType().getArrayComponentDataType(), c -> acceptDefault.apply(c, arg1, arg2));
else
acceptDefault.apply(ctx, arg1, arg2);
}

View File

@ -179,8 +179,11 @@ implements
// [#9224] Special case when a SQL dialect actually supports quantified
// arrays, such as x = any(?::int[]) in PostgreSQL
if (quantifiedArrayParam && SUPPORTS_QUANTIFIED_ARRAYS.contains(ctx.dialect()) && !emulateOperator) {
accept1(ctx, arg1, op, arg2);
if ((quantifiedArrayParam || quantifiedArray) && SUPPORTS_QUANTIFIED_ARRAYS.contains(ctx.dialect()) && !emulateOperator) {
if (quantifiedArray && ((Array) ((QOM.QuantifiedArray<?>) arg2).$arg2()).fields.fields.length == 0)
ctx.data(DATA_EMPTY_ARRAY_BASE_TYPE, arg1.getDataType(), c -> accept1(c, arg1, op, arg2));
else
accept1(ctx, arg1, op, arg2);
}
else if (quantifiedArrayParam || quantifiedArray) {
QOM.QuantifiedArray<?> a = (org.jooq.impl.QOM.QuantifiedArray<?>) arg2;

View File

@ -966,6 +966,11 @@ final class Tools {
*/
DATA_RENDER_TABLE(true, null, 0),
/**
* [#15982] The base type of an empty array in the current scope.
*/
DATA_EMPTY_ARRAY_BASE_TYPE
;
private final boolean resetInSubqueryScope;