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 088b8103b6..6390f3951c 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java @@ -1451,6 +1451,9 @@ public class JavaGenerator extends AbstractGenerator { for (TableDefinition table : database.getTables(schema)) { try { + if (table.isTableValuedFunction() && table.getReferencedTable() != table) + continue; + generateRecord(table); } catch (Exception e) { @@ -5984,7 +5987,7 @@ public class JavaGenerator extends AbstractGenerator { final String tableId = scala ? out.ref(getStrategy().getFullJavaIdentifier(table), 2) : getStrategy().getJavaIdentifier(table); - final String recordType = out.ref(getStrategy().getFullJavaClassName(table, Mode.RECORD)); + final String recordType = out.ref(getStrategy().getFullJavaClassName(table.getReferencedTable(), Mode.RECORD)); final String classExtends = out.ref(getStrategy().getJavaClassExtends(table, Mode.DEFAULT)); final List interfaces = out.ref(getStrategy().getJavaClassImplements(table, Mode.DEFAULT)); final String schemaId = out.ref(getStrategy().getFullJavaIdentifier(schema), 2); @@ -8985,7 +8988,7 @@ public class JavaGenerator extends AbstractGenerator { return; } - final String recordClassName = out.ref(getStrategy().getFullJavaClassName(function, Mode.RECORD)); + final String recordClassName = out.ref(getStrategy().getFullJavaClassName(function.getReferencedTable(), Mode.RECORD)); // [#3456] Local variables should not collide with actual function arguments final String configurationArgument = disambiguateJavaMemberName(function.getParameters(), "configuration"); @@ -9038,8 +9041,8 @@ public class JavaGenerator extends AbstractGenerator { .println("}"); } - protected void printRecordTypeMethod(JavaWriter out, Definition definition) { - final String className = out.ref(getStrategy().getFullJavaClassName(definition, Mode.RECORD)); + protected void printRecordTypeMethod(JavaWriter out, Definition tableOrUDT) { + final String className = out.ref(getStrategy().getFullJavaClassName(tableOrUDT instanceof TableDefinition ? ((TableDefinition) tableOrUDT).getReferencedTable() : tableOrUDT, Mode.RECORD)); out.javadoc("The class holding records for this type"); diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/AbstractTableDefinition.java b/jOOQ-meta/src/main/java/org/jooq/meta/AbstractTableDefinition.java index 8f01d8d378..5669be47cd 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/AbstractTableDefinition.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/AbstractTableDefinition.java @@ -55,24 +55,36 @@ import org.jooq.TableOptions.TableType; * @author Lukas Eder */ public abstract class AbstractTableDefinition -extends AbstractElementContainerDefinition -implements TableDefinition { +extends + AbstractElementContainerDefinition +implements + TableDefinition +{ private List parameters; private TableDefinition parentTable; private final List childTables; private final TableType tableType; + private final SchemaDefinition referencedSchema; + private final String referencedName; + private TableDefinition referencedTable; public AbstractTableDefinition(SchemaDefinition schema, String name, String comment) { this(schema, name, comment, TableType.TABLE, null); } public AbstractTableDefinition(SchemaDefinition schema, String name, String comment, TableType tableType, String source) { + this(schema, name, comment, tableType, source, null, null); + } + + public AbstractTableDefinition(SchemaDefinition schema, String name, String comment, TableType tableType, String source, SchemaDefinition referencedSchema, String referencedName) { super(schema, null, name, comment, source); this.parentTable = null; this.childTables = new ArrayList<>(); this.tableType = tableType; + this.referencedSchema = referencedSchema; + this.referencedName = referencedName; } @Override @@ -229,6 +241,19 @@ implements TableDefinition { return tableType == TableType.FUNCTION; } + @Override + public final TableDefinition getReferencedTable() { + if (referencedTable == null) { + if (referencedSchema != null) + referencedTable = getDatabase().getTable(referencedSchema, referencedName); + + if (referencedTable == null) + referencedTable = this; + } + + return referencedTable; + } + @Override protected List getElements0() throws SQLException { return null; diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/TableDefinition.java b/jOOQ-meta/src/main/java/org/jooq/meta/TableDefinition.java index e4af5b9f11..1566863c51 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/TableDefinition.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/TableDefinition.java @@ -43,6 +43,8 @@ import java.util.List; import org.jooq.Record; import org.jooq.Table; +import org.jetbrains.annotations.NotNull; + /** * The definition of a table or view. * @@ -73,6 +75,7 @@ public interface TableDefinition extends Definition { /** * Whether this table is a synthetic table (e.g. a synthetic view). */ + @Override boolean isSynthetic(); /** @@ -176,4 +179,22 @@ public interface TableDefinition extends Definition { */ boolean isTableValuedFunction(); + /** + * The referenced table type, if this {@link #isTableValuedFunction()}. + *

+ * This returns: + *

    + *
  • this, if {@link #isTableValuedFunction()} == + * false
  • + *
  • this, if {@link #isTableValuedFunction()} == + * true but the table valued function doesn't reference a table + * type
  • + *
  • Another table, if {@link #isTableValuedFunction()} == + * true and the table valued function references a table + * type
  • + *
+ */ + @NotNull + TableDefinition getReferencedTable(); + } diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/postgres/PostgresDatabase.java b/jOOQ-meta/src/main/java/org/jooq/meta/postgres/PostgresDatabase.java index 4d75cc4811..aa1cc4fbdb 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/postgres/PostgresDatabase.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/postgres/PostgresDatabase.java @@ -126,6 +126,7 @@ import org.jooq.Record1; import org.jooq.Record12; import org.jooq.Record5; import org.jooq.Record6; +import org.jooq.Record8; import org.jooq.Result; import org.jooq.ResultQuery; import org.jooq.SQLDialect; @@ -466,8 +467,8 @@ public class PostgresDatabase extends AbstractDatabase implements ResultQueryDat List result = new ArrayList<>(); Map map = new HashMap<>(); - Select> empty = - select(inline(""), inline(""), inline(""), inline(""), inline(""), inline("")) + Select> empty = + select(inline(""), inline(""), inline(""), inline(""), inline(""), inline(""), inline(""), inline("")) .where(falseCondition()); for (Record record : create() @@ -480,7 +481,9 @@ public class PostgresDatabase extends AbstractDatabase implements ResultQueryDat PG_DESCRIPTION.DESCRIPTION, when(TABLES.TABLE_TYPE.eq(inline("VIEW")), inline(TableType.VIEW.name())) .else_(inline(TableType.TABLE.name())).as("table_type"), - VIEWS.VIEW_DEFINITION) + VIEWS.VIEW_DEFINITION, + inline("").as(ROUTINES.TYPE_UDT_SCHEMA), + inline("").as(ROUTINES.TYPE_UDT_NAME)) .from(TABLES) .join(PG_CLASS) .on(PG_CLASS.RELNAME.eq(TABLES.TABLE_NAME)) @@ -516,6 +519,8 @@ public class PostgresDatabase extends AbstractDatabase implements ResultQueryDat field("{0}::varchar", PG_CLASS.RELNAME.getDataType(), PG_CLASS.RELNAME), PG_DESCRIPTION.DESCRIPTION, inline(TableType.MATERIALIZED_VIEW.name()).as("table_type"), + inline(""), + inline(""), inline("")) .from(PG_CLASS) .leftOuterJoin(PG_DESCRIPTION) @@ -534,7 +539,9 @@ public class PostgresDatabase extends AbstractDatabase implements ResultQueryDat ROUTINES.SPECIFIC_NAME, inline(""), inline(TableType.FUNCTION.name()).as("table_type"), - inline("")) + inline(""), + ROUTINES.TYPE_UDT_SCHEMA, + ROUTINES.TYPE_UDT_NAME) .from(ROUTINES) .join(PG_PROC).on(PG_PROC.pgNamespace().NSPNAME.eq(ROUTINES.SPECIFIC_SCHEMA)) .and(PG_PROC.PRONAME.concat("_").concat(PG_PROC.OID).eq(ROUTINES.SPECIFIC_NAME)) @@ -556,17 +563,26 @@ public class PostgresDatabase extends AbstractDatabase implements ResultQueryDat source = "create view \"" + name + "\" as " + source; switch (tableType) { - case FUNCTION: - result.add(new PostgresTableValuedFunction(schema, name, record.get(ROUTINES.SPECIFIC_NAME), comment)); + case FUNCTION: { + result.add(new PostgresTableValuedFunction( + schema, name, + record.get(ROUTINES.SPECIFIC_NAME), + comment, null, + getSchema(record.get(ROUTINES.TYPE_UDT_SCHEMA)), + record.get(ROUTINES.TYPE_UDT_NAME) + )); break; - case MATERIALIZED_VIEW: + } + case MATERIALIZED_VIEW: { result.add(new PostgresMaterializedViewDefinition(schema, name, comment)); break; - default: + } + default: { PostgresTableDefinition t = new PostgresTableDefinition(schema, name, comment, tableType, source); result.add(t); map.put(name(schema.getName(), name), t); break; + } } } diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/postgres/PostgresTableValuedFunction.java b/jOOQ-meta/src/main/java/org/jooq/meta/postgres/PostgresTableValuedFunction.java index c9273a101b..7b25f2ee8f 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/postgres/PostgresTableValuedFunction.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/postgres/PostgresTableValuedFunction.java @@ -41,7 +41,6 @@ package org.jooq.meta.postgres; import static org.jooq.impl.DSL.coalesce; import static org.jooq.impl.DSL.field; import static org.jooq.impl.DSL.inline; -import static org.jooq.impl.DSL.lateral; import static org.jooq.impl.DSL.name; import static org.jooq.impl.DSL.nvl; import static org.jooq.impl.DSL.partitionBy; @@ -49,18 +48,16 @@ import static org.jooq.impl.DSL.row; import static org.jooq.impl.DSL.rowNumber; import static org.jooq.impl.DSL.select; import static org.jooq.impl.DSL.substring; -import static org.jooq.impl.DSL.trueCondition; -import static org.jooq.impl.DSL.values; import static org.jooq.impl.DSL.when; import static org.jooq.meta.postgres.PostgresRoutineDefinition.pNumericPrecision; import static org.jooq.meta.postgres.information_schema.Tables.COLUMNS; import static org.jooq.meta.postgres.information_schema.Tables.PARAMETERS; import static org.jooq.meta.postgres.information_schema.Tables.ROUTINES; -import static org.jooq.meta.postgres.pg_catalog.Tables.*; +import static org.jooq.meta.postgres.pg_catalog.Tables.PG_ATTRIBUTE; +import static org.jooq.meta.postgres.pg_catalog.Tables.PG_CLASS; import static org.jooq.meta.postgres.pg_catalog.Tables.PG_PROC; import static org.jooq.meta.postgres.pg_catalog.Tables.PG_TYPE; import static org.jooq.tools.StringUtils.defaultString; -import static org.jooq.util.postgres.PostgresDSL.oid; import java.sql.SQLException; import java.util.ArrayList; @@ -69,7 +66,6 @@ import java.util.List; import org.jooq.Field; import org.jooq.Record; import org.jooq.TableOptions.TableType; -import org.jooq.meta.AbstractDatabase; import org.jooq.meta.AbstractTableDefinition; import org.jooq.meta.ColumnDefinition; import org.jooq.meta.DataTypeDefinition; @@ -77,12 +73,12 @@ import org.jooq.meta.DefaultColumnDefinition; import org.jooq.meta.DefaultDataTypeDefinition; import org.jooq.meta.ParameterDefinition; import org.jooq.meta.SchemaDefinition; +import org.jooq.meta.TableDefinition; import org.jooq.meta.postgres.information_schema.tables.Columns; import org.jooq.meta.postgres.information_schema.tables.Parameters; import org.jooq.meta.postgres.information_schema.tables.Routines; import org.jooq.meta.postgres.pg_catalog.tables.PgAttribute; import org.jooq.meta.postgres.pg_catalog.tables.PgClass; -import org.jooq.meta.postgres.pg_catalog.tables.PgNamespace; import org.jooq.meta.postgres.pg_catalog.tables.PgProc; import org.jooq.meta.postgres.pg_catalog.tables.PgType; @@ -99,7 +95,11 @@ public class PostgresTableValuedFunction extends AbstractTableDefinition { } public PostgresTableValuedFunction(SchemaDefinition schema, String name, String specificName, String comment, String source) { - super(schema, name, comment, TableType.FUNCTION, source); + this(schema, name, specificName, comment, source, null, null); + } + + public PostgresTableValuedFunction(SchemaDefinition schema, String name, String specificName, String comment, String source, SchemaDefinition referencedSchema, String referencedName) { + super(schema, name, comment, TableType.FUNCTION, source, referencedSchema, referencedName); this.routine = new PostgresRoutineDefinition(schema.getDatabase(), schema.getInputName(), name, specificName); this.specificName = specificName;