diff --git a/jOOQ/src/main/java/org/jooq/impl/AsteriskImpl.java b/jOOQ/src/main/java/org/jooq/impl/AsteriskImpl.java index b30e1473db..c06201a404 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AsteriskImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/AsteriskImpl.java @@ -39,6 +39,7 @@ package org.jooq.impl; // ... // ... +import static org.jooq.SQLDialect.CLICKHOUSE; import static org.jooq.SQLDialect.DERBY; import static org.jooq.SQLDialect.DUCKDB; import static org.jooq.SQLDialect.FIREBIRD; @@ -74,7 +75,7 @@ import org.jooq.impl.QOM.UnmodifiableList; final class AsteriskImpl extends AbstractQueryPart implements Asterisk { static final Lazy INSTANCE = Lazy.of(() -> new AsteriskImpl(new QueryPartList<>())); static final Set SUPPORT_NATIVE_EXCEPT = SQLDialect.supportedBy(H2); - static final Set NO_SUPPORT_UNQUALIFIED_COMBINED = SQLDialect.supportedBy(DERBY, FIREBIRD, HSQLDB, MARIADB, MYSQL); + static final Set NO_SUPPORT_UNQUALIFIED_COMBINED = SQLDialect.supportedBy(CLICKHOUSE, DERBY, FIREBIRD, HSQLDB, MARIADB, MYSQL); diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java index 1cb95f3cbe..45a0a53cb2 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java @@ -3969,7 +3969,7 @@ public class DefaultBinding implements Binding { } @Override - void sqlBind0(BindingSQLContext ctx, Record value) throws SQLException { + final void sqlBind0(BindingSQLContext ctx, Record value) throws SQLException { Cast.renderCastIf(ctx.render(), c -> super.sqlBind0(ctx, value), c -> pgRenderRecordCast(ctx.render()), @@ -4105,7 +4105,11 @@ public class DefaultBinding implements Binding { result = DefaultResultBinding.readMultiset(ctx, row, type.getType(), s -> s != null && (s.startsWith("[") || s.startsWith("{")) ? "[" + s + "]" : null, s -> s != null && (s.startsWith("<")) ? "" + s + "" : null, - s -> s instanceof Struct x ? asList(x) : null + s -> s instanceof Struct x + ? asList(x) + : s instanceof List l + ? asList(l) + : null ); return isEmpty(result) ? null : result.get(0); @@ -4416,7 +4420,7 @@ public class DefaultBinding implements Binding { throw new UnsupportedOperationException("Multiset emulation not yet supported: " + emulation); } - static Result readMultisetList(Scope ctx, AbstractRow row, Class recordType, List l) throws SQLException { + static final Result readMultisetList(Scope ctx, AbstractRow row, Class recordType, List l) throws SQLException { return new ListHandler<>(ctx.dsl(), row, recordType).read(l); } diff --git a/jOOQ/src/main/java/org/jooq/impl/JSONArray.java b/jOOQ/src/main/java/org/jooq/impl/JSONArray.java index 173996c68f..52d617007a 100644 --- a/jOOQ/src/main/java/org/jooq/impl/JSONArray.java +++ b/jOOQ/src/main/java/org/jooq/impl/JSONArray.java @@ -210,7 +210,7 @@ implements // [#7539] ARRAY types can't mix data types, so use TUPLE for degrees > 1 if (fields.size() > 1) - ctx.visit(function(N_toJSONString, getDataType(), function(N_TUPLE, OTHER, fields.toArray(EMPTY_FIELD)))); + ctx.visit(function(N_toJSONString, getDataType(), function(N_TUPLE, OTHER, map(fields, e -> JSONEntryImpl.jsonCast(ctx, e), Field[]::new)))); else ctx.visit(function(N_toJSONString, getDataType(), array(fields))); diff --git a/jOOQ/src/main/java/org/jooq/impl/JSONEntryImpl.java b/jOOQ/src/main/java/org/jooq/impl/JSONEntryImpl.java index 32fe5cf235..529c5c3d1d 100644 --- a/jOOQ/src/main/java/org/jooq/impl/JSONEntryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/JSONEntryImpl.java @@ -238,6 +238,12 @@ final class JSONEntryImpl extends AbstractQueryPart implements JSONEntry, break; + case CLICKHOUSE: + if (isType(type, Boolean.class)) + return field.cast(BOOLEAN); + + break; + case SQLITE: if (isType(type, Boolean.class)) return function(N_JSON, SQLDataType.JSON, booleanCase(field)); diff --git a/jOOQ/src/main/java/org/jooq/impl/JSONObject.java b/jOOQ/src/main/java/org/jooq/impl/JSONObject.java index 2bf1a802e5..fef6264dc7 100644 --- a/jOOQ/src/main/java/org/jooq/impl/JSONObject.java +++ b/jOOQ/src/main/java/org/jooq/impl/JSONObject.java @@ -245,9 +245,15 @@ implements } case CLICKHOUSE: { - ctx.visit(function(N_toJSONString, getDataType(), function(N_MAP, OTHER, - flatMap(entries, e -> Arrays.>asList(e.key(), e.value())).toArray(EMPTY_FIELD) - ))); + if (entries.isEmpty()) + ctx.visit(function(N_toJSONString, getDataType(), function(N_MAP, OTHER))); + else if (entries.size() == 1) + ctx.visit(toJSONString(ctx, getDataType(), entries.get(0))); + else + ctx.visit(function(N_jsonMergePatch, getDataType(), + map(entries, e -> toJSONString(ctx, getDataType(), e), Field[]::new) + )); + break; } @@ -273,6 +279,12 @@ implements } } + static final Field toJSONString(Context ctx, DataType t, JSONEntry e) { + return function(N_toJSONString, t, function(N_MAP, OTHER, + e.key(), JSONEntryImpl.jsonCast(ctx, e.value()) + )); + } + static final Field absentOnNullIf( BooleanSupplier test, Function1, Field> e, diff --git a/jOOQ/src/main/java/org/jooq/impl/ListHandler.java b/jOOQ/src/main/java/org/jooq/impl/ListHandler.java index 09de3df1b9..7c2538ea13 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ListHandler.java +++ b/jOOQ/src/main/java/org/jooq/impl/ListHandler.java @@ -72,8 +72,14 @@ final class ListHandler { for (Object o : list) result.add(newRecord(true, recordType, row, ctx.configuration()).operate(r -> { - if (o instanceof Struct s) { - Object[] attributes = s.getAttributes(); + Object[] attributes = + o instanceof Struct s + ? s.getAttributes() + : o instanceof List l + ? l.toArray() + : null; + + if (attributes != null) { // [#13400] Recurse for nested MULTISET or ROW types for (int i = 0; i < attributes.length && i < row.size(); i++) { diff --git a/jOOQ/src/main/java/org/jooq/impl/Names.java b/jOOQ/src/main/java/org/jooq/impl/Names.java index f39ed698c6..dd8b5fc328 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Names.java +++ b/jOOQ/src/main/java/org/jooq/impl/Names.java @@ -180,6 +180,7 @@ final class Names { static final Name N_JSON_TYPE = systemName("json_type"); static final Name N_JSON_UNQUOTE = systemName("json_unquote"); static final Name N_JSON_VALUE = systemName("json_value"); + static final Name N_jsonMergePatch = systemName("jsonMergePatch"); static final Name N_LAG = systemName("lag"); static final Name N_lagInFrame = systemName("lagInFrame"); static final Name N_LAST_VALUE = systemName("last_value"); diff --git a/jOOQ/src/main/java/org/jooq/impl/SelectIsNull.java b/jOOQ/src/main/java/org/jooq/impl/SelectIsNull.java index d88ea0a8e4..8527907a54 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SelectIsNull.java +++ b/jOOQ/src/main/java/org/jooq/impl/SelectIsNull.java @@ -42,6 +42,7 @@ package org.jooq.impl; // ... // ... // ... +import static org.jooq.SQLDialect.CLICKHOUSE; // ... import static org.jooq.SQLDialect.CUBRID; // ... @@ -96,7 +97,7 @@ import org.jooq.Table; */ final class SelectIsNull extends AbstractCondition implements QOM.SelectIsNull { - static final Set EMULATE_NULL_QUERY = SQLDialect.supportedBy(CUBRID, DERBY, DUCKDB, FIREBIRD, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, TRINO, YUGABYTEDB); + static final Set EMULATE_NULL_QUERY = SQLDialect.supportedBy(CLICKHOUSE, CUBRID, DERBY, DUCKDB, FIREBIRD, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE, TRINO, YUGABYTEDB); final Select select; diff --git a/jOOQ/src/main/java/org/jooq/impl/SetCatalog.java b/jOOQ/src/main/java/org/jooq/impl/SetCatalog.java index 699900482c..13700d80c6 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SetCatalog.java +++ b/jOOQ/src/main/java/org/jooq/impl/SetCatalog.java @@ -108,6 +108,7 @@ implements + case CLICKHOUSE: case DERBY: case DUCKDB: case H2: diff --git a/jOOQ/src/main/java/org/jooq/impl/SetSchema.java b/jOOQ/src/main/java/org/jooq/impl/SetSchema.java index 476841f2f4..484b0b6256 100644 --- a/jOOQ/src/main/java/org/jooq/impl/SetSchema.java +++ b/jOOQ/src/main/java/org/jooq/impl/SetSchema.java @@ -107,6 +107,7 @@ implements + case CLICKHOUSE: case DUCKDB: case MARIADB: case MYSQL: diff --git a/jOOQ/src/main/java/org/jooq/impl/UuidToBin.java b/jOOQ/src/main/java/org/jooq/impl/UuidToBin.java index 83a8142a4a..5e740d2724 100644 --- a/jOOQ/src/main/java/org/jooq/impl/UuidToBin.java +++ b/jOOQ/src/main/java/org/jooq/impl/UuidToBin.java @@ -119,7 +119,7 @@ implements case CLICKHOUSE: - ctx.visit(function(N_UUIDStringToNum, BINARY(16), uuid)); + ctx.visit(function(N_UUIDStringToNum, BINARY(16), DSL.cast(uuid, VARCHAR))); break;