diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java
index 83d1961b71..72ecfea1be 100644
--- a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java
+++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java
@@ -2613,18 +2613,18 @@ public class JavaGenerator extends AbstractGenerator {
final TypedElementDefinition> t = (TypedElementDefinition>) column;
final JavaTypeResolver r = resolver(out, Mode.RECORD);
- final boolean isUDT = t.getType(r).isUDT();
+ final boolean isUDTOrTable = t.getType(r).isUDT() || t.getType(r).isTable();
final boolean isArray = t.getType(r).isArray();
- final boolean isUDTArray = t.getType(r).isUDTArray();
+ final boolean isUDTOrTableArray = t.getType(r).isUDTArray() || t.getType(r).isTableArray();
final ArrayDefinition array = database.getArray(t.getType(r).getSchema(), t.getType(r).getQualifiedUserType());
final String indexTypeFull = array == null || array.getIndexType() == null ? null : getJavaType(array.getIndexType(resolver(out)), out);
final boolean isArrayOfUDTs = isArrayOfUDTs(t, r, Mode.RECORD);
final boolean isConverted = t.getType(r).getConverter() != null || t.getType(r).getBinding() != null;
- final String udtType = (isUDT || isArray)
+ final String udtType = (isUDTOrTable || isArray)
? out.ref(getJavaType(t.getType(r), out, Mode.RECORD))
: "";
- final String udtArrayElementType = isUDTArray
+ final String udtArrayElementType = isUDTOrTableArray
? out.ref(database.getArray(t.getType(r).getSchema(), t.getType(r).getQualifiedUserType()).getElementType(r).getJavaType(r))
: isArrayOfUDTs
? out.ref(getArrayBaseType(t.getType(r).getJavaType(r)))
@@ -2632,7 +2632,7 @@ public class JavaGenerator extends AbstractGenerator {
if (kotlin) {
if (pojoArgument)
- if (isUDTArray)
+ if (isUDTOrTableArray)
out.println("this.%s = value.%s?.let { %s(it.map { it?.let { %s(it) } }) }",
getStrategy().getJavaMemberName(column, Mode.POJO),
getStrategy().getJavaMemberName(column, Mode.POJO),
@@ -2643,7 +2643,7 @@ public class JavaGenerator extends AbstractGenerator {
getStrategy().getJavaMemberName(column, Mode.POJO),
getStrategy().getJavaMemberName(column, Mode.POJO),
udtArrayElementType);
- else if (isUDT && !isConverted || isArray)
+ else if (isUDTOrTable && !isConverted || isArray)
out.println("this.%s = value.%s?.let { %s(it) }",
getStrategy().getJavaMemberName(column, Mode.POJO),
getStrategy().getJavaMemberName(column, Mode.POJO),
@@ -2665,7 +2665,7 @@ public class JavaGenerator extends AbstractGenerator {
// In Scala, the setter call can be ambiguous, e.g. when using KeepNamesGeneratorStrategy
else if (scala) {
if (pojoArgument)
- if (isUDTArray)
+ if (isUDTOrTableArray)
out.println("this.%s(if (value.%s == null) null else new %s(value.%s.stream().map { it => new %s(it) }.collect(%s.toList())))",
getStrategy().getJavaSetterName(column, Mode.POJO),
getStrategy().getJavaGetterName(column, Mode.POJO),
@@ -2679,7 +2679,7 @@ public class JavaGenerator extends AbstractGenerator {
getStrategy().getJavaGetterName(column, Mode.POJO),
getStrategy().getJavaGetterName(column, Mode.POJO),
udtArrayElementType);
- else if (isUDT && !isConverted || isArray)
+ else if (isUDTOrTable && !isConverted || isArray)
out.println("this.%s(if (value.%s == null) null else new %s(value.%s))",
getStrategy().getJavaSetterName(column, Mode.RECORD),
getStrategy().getJavaGetterName(column, Mode.POJO),
@@ -2702,7 +2702,7 @@ public class JavaGenerator extends AbstractGenerator {
? getStrategy().getJavaMemberName(column, Mode.POJO)
: getStrategy().getJavaGetterName(column, Mode.POJO);
- if (isUDTArray) {
+ if (isUDTOrTableArray) {
if (indexTypeFull == null) {
out.println("%s(value.%s() == null ? null : new %s(value.%s().stream().map(%s::new).collect(%s.toList())));",
getStrategy().getJavaSetterName(column, Mode.RECORD),
@@ -2741,7 +2741,7 @@ public class JavaGenerator extends AbstractGenerator {
brackets
);
}
- else if (isUDT && !isConverted || isArray) {
+ else if (isUDTOrTable && !isConverted || isArray) {
out.println("%s(value.%s() == null ? null : new %s(value.%s()));",
getStrategy().getJavaSetterName(column, Mode.RECORD),
getterName,
@@ -2842,15 +2842,15 @@ public class JavaGenerator extends AbstractGenerator {
final String typeFull = getJavaType(column.getType(resolver(out)), out);
final String type = out.ref(typeFull);
final String name = column.getQualifiedOutputName();
- final boolean isUDT = column.getType(resolver(out)).isUDT();
+ final boolean isUDTOrTable = column.getType(resolver(out)).isUDT() || column.getType(resolver(out)).isTable();
final boolean isArray = column.getType(resolver(out)).isArray();
- final boolean override = generateInterfaces() && !generateImmutableInterfaces() && !isUDT
+ final boolean override = generateInterfaces() && !generateImmutableInterfaces() && !isUDTOrTable
|| column instanceof AttributeDefinition && ((AttributeDefinition) column).getContainer().isInTypeHierarchy()
|| !kotlin && getStrategy().getJavaSetterOverride(column, Mode.RECORD)
|| kotlin && getStrategy().getJavaMemberOverride(column, Mode.RECORD);
// We cannot have covariant setters for arrays because of type erasure
- if (!(generateInterfaces() && (isArray || isUDT))) {
+ if (!(generateInterfaces() && (isArray || isUDTOrTable))) {
if (!kotlin && !printDeprecationIfUnknownType(out, typeFull))
out.javadoc("Setter for %s.[[before= ][%s]]", name, list(escapeEntities(comment(column))));
@@ -2890,7 +2890,7 @@ public class JavaGenerator extends AbstractGenerator {
}
// [#3117] Avoid covariant setters for UDTs when generating interfaces
- if (generateInterfaces() && (isUDT || isArray)) {
+ if (generateInterfaces() && (isUDTOrTable || isArray)) {
final String columnTypeFull = getJavaType(column.getType(resolver(out, Mode.DEFAULT)), out, Mode.DEFAULT);
final String columnTypeInterface = out.ref(getJavaType(column.getType(resolver(out, Mode.INTERFACE)), out, Mode.INTERFACE));
final UDTDefinition udt = column.getDatabase().getUDT(column.getSchema(), column.getType().getUserType());
@@ -2898,7 +2898,7 @@ public class JavaGenerator extends AbstractGenerator {
if (!printDeprecationIfUnknownType(out, columnTypeFull))
out.javadoc("Setter for %s.[[before= ][%s]]", name, list(escapeEntities(comment(column))));
- if (!generateImmutableInterfaces() || udt.isInTypeHierarchy())
+ if (!generateImmutableInterfaces() || udt != null && udt.isInTypeHierarchy())
out.override();
if (scala) {
@@ -2938,12 +2938,12 @@ public class JavaGenerator extends AbstractGenerator {
final String typeFull = getJavaType(column.getType(resolver(out)), out);
final String type = out.ref(typeFull);
final String recordTypeFull = getJavaType(column.getType(resolver(out, Mode.RECORD)), out, Mode.RECORD);
- final boolean isUDT = column.getType(resolver(out)).isUDT();
- final boolean isUDTArray = column.getType(resolver(out)).isUDTArray();
+ final boolean isUDTOrTable = column.getType(resolver(out)).isUDT() || column.getType(resolver(out)).isTable();
+ final boolean isUDTOrTableArray = column.getType(resolver(out)).isUDTArray() || column.getType(resolver(out)).isTableArray();
final boolean isArray = column.getType(resolver(out)).isArray();
final boolean isArrayOfUDTs = isArrayOfUDTs(column, resolver(out, RECORD), RECORD);
- if (generateInterfaces() && (isUDT || isArray)) {
+ if (generateInterfaces() && (isUDTOrTable || isArray)) {
final String typeInterface = out.ref(getJavaType(column.getType(resolver(out, Mode.INTERFACE)), out, Mode.INTERFACE));
final UDTDefinition udt = column.getDatabase().getUDT(column.getSchema(), column.getType().getUserType());
@@ -2956,7 +2956,7 @@ public class JavaGenerator extends AbstractGenerator {
out.println("else if (%s.isInstanceOf[%s])", member, type);
out.println("return %s.asInstanceOf[%s]", member, type);
- if (isUDT && udt != null)
+ if (isUDTOrTable && udt != null)
generateRecordSetterSubtypeChecks0(out, index, column, udt);
}
@@ -2968,7 +2968,7 @@ public class JavaGenerator extends AbstractGenerator {
out.println("return %s.map(u => new %s(%s))", member, columnBaseTypeName, udtInterfaceGetterCalls(udt, "u"));
}
else
- out.println("return new %s(%s)", out.ref(recordTypeFull), udtInterfaceGetterCalls(udt, member));
+ out.println("return new %s(%s)", out.ref(recordTypeFull), udt != null ? udtInterfaceGetterCalls(udt, member) : member);
out.println("}");
}
@@ -2981,7 +2981,7 @@ public class JavaGenerator extends AbstractGenerator {
out.println("if (%s == null)", member);
out.println("return null;");
- if (isUDT) {
+ if (isUDTOrTable) {
if (!isArrayOfUDTs) {
out.println("else if (%s instanceof %s)", member, type);
out.println("return (%s) %s;", type, member);
@@ -2998,7 +2998,7 @@ public class JavaGenerator extends AbstractGenerator {
out.println("return %s.of(%s).map(u -> new %s(%s)).toArray(%s[]::new);", Stream.class, member, columnBaseTypeName, udtInterfaceGetterCalls(udt, "u"), columnBaseTypeName);
}
else
- out.println("return new %s(%s);", out.ref(recordTypeFull), udtInterfaceGetterCalls(udt, member));
+ out.println("return new %s(%s);", out.ref(recordTypeFull), udt != null ? udtInterfaceGetterCalls(udt, member) : member);
}
else if (isArray) {
final ArrayDefinition array = database.getArray(column.getType(resolver(out)).getSchema(), column.getType(resolver(out)).getQualifiedUserType());
@@ -3010,7 +3010,7 @@ public class JavaGenerator extends AbstractGenerator {
out.println();
out.println("for (%s i : %s)", componentTypeInterface, member);
- if (isUDTArray)
+ if (isUDTOrTableArray)
out.println("a.add(i.into(new %s()));", componentType);
else
out.println("a.add(i);", componentType);
@@ -6167,10 +6167,10 @@ public class JavaGenerator extends AbstractGenerator {
final Definition column = embeddablesAndUnreplacedColumns.get(i);
if (column instanceof TypedElementDefinition> t) {
- final boolean isUDT = t.getType(resolver(out)).isUDT();
- final boolean isUDTArray = t.getType(resolver(out)).isUDTArray();
+ final boolean isUDTOrTable = t.getType(resolver(out)).isUDT() || t.getType(resolver(out)).isTable();
+ final boolean isUDTOrTableArray = t.getType(resolver(out)).isUDTArray() || t.getType(resolver(out)).isTableArray();
- if (isUDT || isUDTArray) {
+ if (isUDTOrTable || isUDTOrTableArray) {
if (!hasUdts) {
hasUdts = true;
out.println();
@@ -6278,6 +6278,8 @@ public class JavaGenerator extends AbstractGenerator {
if (column instanceof TypedElementDefinition> e) {
if (e.getType().isUDT())
return e.getDatabase().getUDT(e.getSchema(), e.getType().getQualifiedUserType());
+ else if (e.getType().isTable())
+ return e.getDatabase().getTable(e.getSchema(), e.getType().getQualifiedUserType());
}
@@ -6692,13 +6694,14 @@ public class JavaGenerator extends AbstractGenerator {
final String columnTypeFull = getJavaType(column.getType(resolver(out, Mode.POJO)), out, Mode.POJO);
final String columnType = out.ref(columnTypeFull);
final String columnMember = getStrategy().getJavaMemberName(column, Mode.POJO);
- final boolean isUDT = column.getType(resolver(out)).isUDT();
- final boolean isUDTArray = column.getType(resolver(out)).isUDTArray();
+ final boolean isUDTOrTable = column.getType(resolver(out)).isUDT() || column.getType(resolver(out)).isTable();
+ final boolean isUDTOrTableArray = column.getType(resolver(out)).isUDTArray() || column.getType(resolver(out)).isTableArray();
final boolean isArrayOfUDTs = isArrayOfUDTs(column, resolver(out, POJO), POJO);
- if (generateInterfaces() && (isUDT || isUDTArray)) {
+ if (generateInterfaces() && (isUDTOrTable || isUDTOrTableArray)) {
final String columnTypeInterface = out.ref(getJavaType(column.getType(resolver(out, Mode.INTERFACE)), out, Mode.INTERFACE));
final UDTDefinition udt = column.getDatabase().getUDT(column.getSchema(), column.getType().getUserType());
+ final Definition udtOrTable = udt != null ? udt : column.getDatabase().getTable(column.getSchema(), column.getType().getUserType());
if (scala) {
out.println();
@@ -6706,13 +6709,13 @@ public class JavaGenerator extends AbstractGenerator {
out.println("if (%s == null)", columnMember);
out.println("return null");
- if (isUDT && supportPojoInheritance())
+ if (isUDTOrTable && supportPojoInheritance() && udt != null)
generatePojoSetterSubtypeChecks0(out, index, column, udt);
out.println("else");
if (isArrayOfUDTs) {
- final String columnBaseTypeName = out.ref(getStrategy().getFullJavaClassName(udt, Mode.POJO));
+ final String columnBaseTypeName = out.ref(getStrategy().getFullJavaClassName(udtOrTable, Mode.POJO));
out.println("return %s.map(u => new %s(u))", columnMember, columnBaseTypeName);
}
@@ -6733,21 +6736,21 @@ public class JavaGenerator extends AbstractGenerator {
out.println("if (%s == null)", columnMember);
out.println("return null;");
- if (isUDT) {
- if (supportPojoInheritance())
+ if (isUDTOrTable) {
+ if (supportPojoInheritance() && udt != null)
generatePojoSetterSubtypeChecks0(out, index, column, udt);
out.println("else");
if (isArrayOfUDTs) {
- final String columnBaseTypeName = out.ref(getStrategy().getFullJavaClassName(udt, Mode.POJO));
+ final String columnBaseTypeName = out.ref(getStrategy().getFullJavaClassName(udtOrTable, Mode.POJO));
out.println("return %s.of(%s).map(u -> new %s(%s)).toArray(%s[]::new);", Stream.class, columnMember, columnBaseTypeName, udtInterfaceGetterCalls(udt, "u"), columnBaseTypeName);
}
else
- out.println("return new %s(%s);", columnType, udtInterfaceGetterCalls(udt, columnMember));
+ out.println("return new %s(%s);", columnType, udt != null ? udtInterfaceGetterCalls(udt, columnMember) : columnMember);
}
- else if (isUDTArray) {
+ else if (isUDTOrTableArray) {
final ArrayDefinition array = database.getArray(column.getType(resolver(out)).getSchema(), column.getType(resolver(out)).getQualifiedUserType());
final String componentType = out.ref(getJavaType(array.getElementType(resolver(out, Mode.POJO)), out, Mode.POJO));
final String componentTypeInterface = out.ref(getJavaType(array.getElementType(resolver(out, Mode.INTERFACE)), out, Mode.INTERFACE));
@@ -6781,13 +6784,13 @@ public class JavaGenerator extends AbstractGenerator {
final String columnSetterReturnType = generateFluentSetters() ? className : tokenVoid;
final String columnSetter = getStrategy().getJavaSetterName(column, Mode.POJO);
final String columnMember = getStrategy().getJavaMemberName(column, Mode.POJO);
- final boolean isUDT = column.getType(resolver(out)).isUDT();
+ final boolean isUDTOrTable = column.getType(resolver(out)).isUDT() || column.getType(resolver(out)).isTable();
final boolean isArray = column.getType(resolver(out)).isArray();
final String name = column.getQualifiedOutputName();
- final boolean override = generateInterfaces() && !generateImmutableInterfaces() && !isUDT;
+ final boolean override = generateInterfaces() && !generateImmutableInterfaces() && !isUDTOrTable;
// We cannot have covariant setters for arrays because of type erasure
- if (!(generateInterfaces() && (isArray || isUDT))) {
+ if (!(generateInterfaces() && (isArray || isUDTOrTable))) {
if (!printDeprecationIfUnknownType(out, columnTypeFull))
out.javadoc("Setter for %s.[[before= ][%s]]", name, list(escapeEntities(comment(column))));
@@ -6815,7 +6818,7 @@ public class JavaGenerator extends AbstractGenerator {
}
// [#3117] To avoid covariant setters on POJOs, we need to generate two setter overloads
- if (generateInterfaces() && (isUDT || isArray)) {
+ if (generateInterfaces() && (isUDTOrTable || isArray)) {
final String columnTypeInterface = out.ref(getJavaType(column.getType(resolver(out, Mode.INTERFACE)), out, Mode.INTERFACE));
out.println();
@@ -11032,12 +11035,14 @@ public class JavaGenerator extends AbstractGenerator {
final String getter = parameter == procedure.getReturnValue()
? "getReturnValue"
: getStrategy().getJavaGetterName(parameter, Mode.DEFAULT);
- final boolean isUDT = parameter.getType(resolver(out)).isUDT();
+ final boolean isUDTOrTable =
+ parameter.getType(resolver(out)).isUDT()
+ || parameter.getType(resolver(out)).isTable();
if (instance) {
// [#3117] Avoid funny call-site ambiguity if this is a UDT that is implemented by an interface
- if (generateInterfaces() && isUDT) {
+ if (generateInterfaces() && isUDTOrTable) {
final String columnTypeInterface = out.ref(getJavaType(parameter.getType(resolver(out, Mode.INTERFACE)), out, Mode.INTERFACE));
if (scala)
@@ -11792,9 +11797,11 @@ public class JavaGenerator extends AbstractGenerator {
// Check for Oracle-style VARRAY types
else if (db.getArray(schema, u) != null) {
- boolean udtArray = db.getArray(schema, u).getElementType(resolver(out)).isUDT();
+ boolean udtOrTableArray =
+ db.getArray(schema, u).getElementType(resolver(out)).isUDT()
+ || db.getArray(schema, u).getElementType(resolver(out)).isTable();
- if (udtMode == Mode.POJO || (udtMode == Mode.INTERFACE && !udtArray)) {
+ if (udtMode == Mode.POJO || (udtMode == Mode.INTERFACE && !udtOrTableArray)) {
if (scala)
type = "java.util.List[" + getJavaType(db.getArray(schema, u).getElementType(resolver(out, udtMode)), out, udtMode) + "]";
else
diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/DataTypeDefinition.java b/jOOQ-meta/src/main/java/org/jooq/meta/DataTypeDefinition.java
index 2f552d6998..d812ffbd6b 100644
--- a/jOOQ-meta/src/main/java/org/jooq/meta/DataTypeDefinition.java
+++ b/jOOQ-meta/src/main/java/org/jooq/meta/DataTypeDefinition.java
@@ -178,6 +178,11 @@ public interface DataTypeDefinition {
*/
boolean isUDT();
+ /**
+ * Whether this data type represents a table type.
+ */
+ boolean isTable();
+
/**
* Whether this data type represents an array producing an
* {@link ArrayRecord}.
@@ -190,6 +195,12 @@ public interface DataTypeDefinition {
*/
boolean isUDTArray();
+ /**
+ * Whether this data type represents an array producing an
+ * {@link ArrayRecord} of table types.
+ */
+ boolean isTableArray();
+
/**
* Whether this data type is a NUMBER type without precision and scale.
*/
diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/DefaultDataTypeDefinition.java b/jOOQ-meta/src/main/java/org/jooq/meta/DefaultDataTypeDefinition.java
index 8f549c3c60..09a1791074 100644
--- a/jOOQ-meta/src/main/java/org/jooq/meta/DefaultDataTypeDefinition.java
+++ b/jOOQ-meta/src/main/java/org/jooq/meta/DefaultDataTypeDefinition.java
@@ -297,6 +297,15 @@ public class DefaultDataTypeDefinition implements DataTypeDefinition {
return getDatabase().getUDT(schema, userType) != null;
}
+ @Override
+ public final boolean isTable() {
+ if (userType == null)
+ return false;
+
+ // [#19247] In PostgreSQL, tables expose types that can be used as UDTs as well in SQL
+ return getDatabase().getTable(schema, userType) != null;
+ }
+
@Override
public final boolean isArray() {
if (userType == null)
@@ -310,6 +319,11 @@ public class DefaultDataTypeDefinition implements DataTypeDefinition {
return isArray() && getDatabase().getArray(schema, userType).getElementType(new DefaultJavaTypeResolver()).isUDT();
}
+ @Override
+ public final boolean isTableArray() {
+ return isArray() && getDatabase().getArray(schema, userType).getElementType(new DefaultJavaTypeResolver()).isTable();
+ }
+
@Override
public final String getType() {
return type;