[jOOQ/jOOQ#5405] Generated SETOF table_type functions should reuse the

TableRecord type of the referenced table
This commit is contained in:
Lukas Eder 2022-11-25 12:03:01 +01:00
parent e86b9f2ef2
commit e21294cd29
5 changed files with 87 additions and 22 deletions

View File

@ -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<String> 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");

View File

@ -55,24 +55,36 @@ import org.jooq.TableOptions.TableType;
* @author Lukas Eder
*/
public abstract class AbstractTableDefinition
extends AbstractElementContainerDefinition<ColumnDefinition>
implements TableDefinition {
extends
AbstractElementContainerDefinition<ColumnDefinition>
implements
TableDefinition
{
private List<ParameterDefinition> parameters;
private TableDefinition parentTable;
private final List<TableDefinition> 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<ColumnDefinition> getElements0() throws SQLException {
return null;

View File

@ -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()}.
* <p>
* This returns:
* <ul>
* <li><code>this</code>, if {@link #isTableValuedFunction()} ==
* <code>false</code></li>
* <li><code>this</code>, if {@link #isTableValuedFunction()} ==
* <code>true</code> but the table valued function doesn't reference a table
* type</li>
* <li>Another table, if {@link #isTableValuedFunction()} ==
* <code>true</code> and the table valued function references a table
* type</li>
* </ul>
*/
@NotNull
TableDefinition getReferencedTable();
}

View File

@ -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<TableDefinition> result = new ArrayList<>();
Map<Name, PostgresTableDefinition> map = new HashMap<>();
Select<Record6<String, String, String, String, String, String>> empty =
select(inline(""), inline(""), inline(""), inline(""), inline(""), inline(""))
Select<Record8<String, String, String, String, String, String, String, String>> 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;
}
}
}

View File

@ -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;