diff --git a/jOOQ/src/main/java/org/jooq/DataType.java b/jOOQ/src/main/java/org/jooq/DataType.java index a377ef4642..172d460600 100644 --- a/jOOQ/src/main/java/org/jooq/DataType.java +++ b/jOOQ/src/main/java/org/jooq/DataType.java @@ -1469,4 +1469,18 @@ public interface DataType extends Named { * Whether this data type is a UUID type. */ boolean isUUID(); + + /** + * Whether this data type is an OTHER type. + *

+ * The {@link SQLDataType#OTHER} type maps any unknown data types to a jOOQ + * {@link DataType}. This includes unknown vendor specific types as well as + * unknown user defined types which do not have any custom {@link Converter} + * or {@link Binding} attached. The type may still be usable with the jOOQ + * API, but jOOQ's behaviour may not be well defined. Please note that any + * future minor release may add support for a vendor specific type, meaning + * the type loses its "otherness." + */ + boolean isOther(); + } diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractDataType.java b/jOOQ/src/main/java/org/jooq/impl/AbstractDataType.java index 25346f5acf..4b7119f80a 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractDataType.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractDataType.java @@ -953,6 +953,11 @@ implements return tType0() == UUID.class; } + @Override + public final boolean isOther() { + return getType() == Object.class; + } + @Override public final void accept(Context ctx) { switch (ctx.family()) { diff --git a/jOOQ/src/main/java/org/jooq/impl/JSONEntryImpl.java b/jOOQ/src/main/java/org/jooq/impl/JSONEntryImpl.java index 595d63aeb7..8280408575 100644 --- a/jOOQ/src/main/java/org/jooq/impl/JSONEntryImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/JSONEntryImpl.java @@ -289,7 +289,7 @@ final class JSONEntryImpl extends AbstractQueryPart implements JSONEntry, case POSTGRES: case YUGABYTEDB: if (field instanceof Param) - if (field.getType() != Object.class) + if (field.getDataType().isOther()) return field.cast(field.getDataType()); else return field.cast(VARCHAR); diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index 9e28c1e221..3824728834 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -7868,7 +7868,6 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { return c; else if (part instanceof Field f) { DataType dataType = f.getDataType(); - Class type = dataType.getType(); if (dataType.isBoolean()) return condition(f); @@ -7878,7 +7877,7 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { return f.ne(zero()); // [#7266] Support parsing column references as predicates - else if (type == Object.class && (part instanceof TableFieldImpl || part instanceof Val)) + else if (dataType.isOther() && (part instanceof TableFieldImpl || part instanceof Val)) return condition((Field) part); else throw expected("Boolean field"); diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index 489fa81864..9ea9373706 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -6024,7 +6024,7 @@ final class Tools { // [#15048] User defined types may need quoting, etc. - else if (type.getType() == Object.class && !(type instanceof BuiltInDataType)) + else if (type.isOther() && !(type instanceof BuiltInDataType)) ctx.visit(type.getQualifiedName()); else ctx.sql(typeName); diff --git a/jOOQ/src/main/java/org/jooq/impl/Values.java b/jOOQ/src/main/java/org/jooq/impl/Values.java index 73ee239cfd..37b216f875 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Values.java +++ b/jOOQ/src/main/java/org/jooq/impl/Values.java @@ -180,11 +180,11 @@ implements for (int i = 0; i < types.length; i++) { types[i] = rows[0].dataType(i); - if (types[i].getType() == Object.class) { + if (types[i].isOther()) { for (int j = 1; j < rows.length; j++) { DataType type = rows[j].dataType(i); - if (type.getType() != Object.class) { + if (!type.isOther()) { types[i] = type; continue typeLoop; } @@ -212,7 +212,7 @@ implements Field[] result = new Field[row.size()]; for (int i = 0; i < result.length; i++) - if (nullLiteralOrUntypedNullBind(ctx, row.field(i)) && rowType()[i].getType() != Object.class) + if (nullLiteralOrUntypedNullBind(ctx, row.field(i)) && !rowType()[i].isOther()) result[i] = row.field(i).cast(rowType()[i]); else result[i] = row.field(i); @@ -226,7 +226,7 @@ implements private final boolean nullLiteralOrUntypedNullBind(Context ctx, Field field) { return isVal(field) && ((Val) field).getValue() == null - && (((Val) field).isInline(ctx) || field.getType() == Object.class) + && (((Val) field).isInline(ctx) || field.getDataType().isOther()) || field instanceof NullCondition; }