From c06dc86c429527e1dd5e5c49a0157f2e94c0cf4a Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Wed, 13 Mar 2024 10:29:15 +0100 Subject: [PATCH] [jOOQ/jOOQ#10695] [jOOQ/jOOQ16179] Quantified comparison fixes This includes: - [jOOQ/jOOQ#10695] ANY clause does not generate correct SQL for forced-type fields - [jOOQ/jOOQ#16179] QuantifiedSelect wrapping array doesn't correctly convert array component types - [jOOQ/jOOQ#16439] Ignored test for quantified comparisons of array types --- jOOQ/src/main/java/org/jooq/DataType.java | 2 +- jOOQ/src/main/java/org/jooq/impl/EqQuantified.java | 2 +- jOOQ/src/main/java/org/jooq/impl/GeQuantified.java | 2 +- jOOQ/src/main/java/org/jooq/impl/GtQuantified.java | 2 +- jOOQ/src/main/java/org/jooq/impl/LeQuantified.java | 2 +- .../org/jooq/impl/LegacyConvertedDataType.java | 1 + jOOQ/src/main/java/org/jooq/impl/LtQuantified.java | 2 +- jOOQ/src/main/java/org/jooq/impl/NeQuantified.java | 2 +- .../main/java/org/jooq/impl/QuantifiedArray.java | 8 +++++--- jOOQ/src/main/java/org/jooq/impl/Tools.java | 14 ++++++++++++++ jOOQ/src/main/java/org/jooq/impl/Val.java | 4 ++-- 11 files changed, 29 insertions(+), 12 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/DataType.java b/jOOQ/src/main/java/org/jooq/DataType.java index 32fc0bb913..35d6b67b2e 100644 --- a/jOOQ/src/main/java/org/jooq/DataType.java +++ b/jOOQ/src/main/java/org/jooq/DataType.java @@ -211,7 +211,7 @@ public interface DataType extends Named { * A convenient short for form {@link #getArrayDataType()} for DSL usage */ @NotNull - @Support({ DUCKDB, H2, HSQLDB, POSTGRES, TRINO, YUGABYTEDB }) + @Support({ CLICKHOUSE, DUCKDB, H2, HSQLDB, POSTGRES, TRINO, YUGABYTEDB }) DataType array() throws DataTypeException; /** diff --git a/jOOQ/src/main/java/org/jooq/impl/EqQuantified.java b/jOOQ/src/main/java/org/jooq/impl/EqQuantified.java index d724d29281..ef6e17f0a8 100644 --- a/jOOQ/src/main/java/org/jooq/impl/EqQuantified.java +++ b/jOOQ/src/main/java/org/jooq/impl/EqQuantified.java @@ -81,7 +81,7 @@ implements ) { this.arg1 = nullSafeNotNull(arg1, (DataType) OTHER); - this.arg2 = arg2; + this.arg2 = nullSafeQuantifiedSelect(arg2, arg1.getDataType()); } // ------------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/impl/GeQuantified.java b/jOOQ/src/main/java/org/jooq/impl/GeQuantified.java index 697f690738..5da1bb6be0 100644 --- a/jOOQ/src/main/java/org/jooq/impl/GeQuantified.java +++ b/jOOQ/src/main/java/org/jooq/impl/GeQuantified.java @@ -81,7 +81,7 @@ implements ) { this.arg1 = nullSafeNotNull(arg1, (DataType) OTHER); - this.arg2 = arg2; + this.arg2 = nullSafeQuantifiedSelect(arg2, arg1.getDataType()); } // ------------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/impl/GtQuantified.java b/jOOQ/src/main/java/org/jooq/impl/GtQuantified.java index 6b92d75964..942ab64ec9 100644 --- a/jOOQ/src/main/java/org/jooq/impl/GtQuantified.java +++ b/jOOQ/src/main/java/org/jooq/impl/GtQuantified.java @@ -81,7 +81,7 @@ implements ) { this.arg1 = nullSafeNotNull(arg1, (DataType) OTHER); - this.arg2 = arg2; + this.arg2 = nullSafeQuantifiedSelect(arg2, arg1.getDataType()); } // ------------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/impl/LeQuantified.java b/jOOQ/src/main/java/org/jooq/impl/LeQuantified.java index 884b11eade..afcbb1623e 100644 --- a/jOOQ/src/main/java/org/jooq/impl/LeQuantified.java +++ b/jOOQ/src/main/java/org/jooq/impl/LeQuantified.java @@ -81,7 +81,7 @@ implements ) { this.arg1 = nullSafeNotNull(arg1, (DataType) OTHER); - this.arg2 = arg2; + this.arg2 = nullSafeQuantifiedSelect(arg2, arg1.getDataType()); } // ------------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/impl/LegacyConvertedDataType.java b/jOOQ/src/main/java/org/jooq/impl/LegacyConvertedDataType.java index 6799c06deb..ecd2d8f656 100644 --- a/jOOQ/src/main/java/org/jooq/impl/LegacyConvertedDataType.java +++ b/jOOQ/src/main/java/org/jooq/impl/LegacyConvertedDataType.java @@ -153,6 +153,7 @@ final class LegacyConvertedDataType extends DefaultDataType { static final boolean isInstance(DataType t) { return t instanceof LegacyConvertedDataType + || t instanceof ArrayDataType && isInstance(((ArrayDataType) t).getArrayComponentDataType()) || t instanceof DataTypeProxy && isInstance(((DataTypeProxy) t).type()); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/LtQuantified.java b/jOOQ/src/main/java/org/jooq/impl/LtQuantified.java index ec524918b0..354ce79b56 100644 --- a/jOOQ/src/main/java/org/jooq/impl/LtQuantified.java +++ b/jOOQ/src/main/java/org/jooq/impl/LtQuantified.java @@ -81,7 +81,7 @@ implements ) { this.arg1 = nullSafeNotNull(arg1, (DataType) OTHER); - this.arg2 = arg2; + this.arg2 = nullSafeQuantifiedSelect(arg2, arg1.getDataType()); } // ------------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/impl/NeQuantified.java b/jOOQ/src/main/java/org/jooq/impl/NeQuantified.java index aa058476a9..eb520d2f4b 100644 --- a/jOOQ/src/main/java/org/jooq/impl/NeQuantified.java +++ b/jOOQ/src/main/java/org/jooq/impl/NeQuantified.java @@ -81,7 +81,7 @@ implements ) { this.arg1 = nullSafeNotNull(arg1, (DataType) OTHER); - this.arg2 = arg2; + this.arg2 = nullSafeQuantifiedSelect(arg2, arg1.getDataType()); } // ------------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/impl/QuantifiedArray.java b/jOOQ/src/main/java/org/jooq/impl/QuantifiedArray.java index 1e5bd530e8..f5a20d5263 100644 --- a/jOOQ/src/main/java/org/jooq/impl/QuantifiedArray.java +++ b/jOOQ/src/main/java/org/jooq/impl/QuantifiedArray.java @@ -48,6 +48,7 @@ import static org.jooq.impl.Tools.visitSubquery; import org.jooq.Configuration; import org.jooq.Context; +import org.jooq.DataType; import org.jooq.Field; import org.jooq.Function2; import org.jooq.Param; @@ -154,13 +155,14 @@ implements // use nested derived tables with UNION ALL if (array instanceof Param) { Object[] values0 = ((Param) array).getValue(); - + DataType type = (DataType) array.getDataType().getArrayComponentDataType(); Select> select = null; + for (Object value : values0) if (select == null) - select = select(val(value)); + select = select(val(value, type)); else - select = select.unionAll(select(val(value))); + select = select.unionAll(select(val(value, type))); return select; } diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index 16aabfbeaa..ff5c0b1736 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -7502,6 +7502,20 @@ final class Tools { : convertVal(field, type); } + @SuppressWarnings("unchecked") + static final > QuantifiedSelect> nullSafeQuantifiedSelect(QuantifiedSelect> s, DataType type) { + if (s instanceof QuantifiedArray) { + QuantifiedArray a = (QuantifiedArray) s; + Field a1 = a.array; + Field a2 = convertVal(a1, type.array()); + + if (a1 != a2) { + return (QuantifiedArray) a.$array(a2); + } + } + return s; + } + /** * In very rare cases, we want {@link #nullSafe(Field, DataType)} behaviour * but only for null values. diff --git a/jOOQ/src/main/java/org/jooq/impl/Val.java b/jOOQ/src/main/java/org/jooq/impl/Val.java index 027b538d9e..1e54538c44 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Val.java +++ b/jOOQ/src/main/java/org/jooq/impl/Val.java @@ -170,14 +170,14 @@ final class Val extends AbstractParam implements UEmpty { } final Val convertTo0(DataType type) { - Val w = new Val<>(type.convert(getValue()), type, inferredDataType, getParamName()); + Val w = new Val<>(type.convert(getValue()), type, LegacyConvertedDataType.isInstance(type) || type.isOther(), getParamName()); w.setInline0(isInline()); return w; } @Override public void accept(Context ctx) { - + // [#16090] [#16425] Inferred user types shouldn't rely on static type registry if (inferredDataType) DefaultDataType.check(getDataType());