[jOOQ/jOOQ#9483] Include sources of materialized views in PostgresDatabase::sources

This commit is contained in:
Lukas Eder 2023-09-18 14:49:19 +02:00
parent c84ed4bfcf
commit f58fc103ed
4 changed files with 55 additions and 12 deletions

View File

@ -55,6 +55,7 @@ import static org.jooq.impl.DSL.cast;
import static org.jooq.impl.DSL.coalesce;
import static org.jooq.impl.DSL.condition;
import static org.jooq.impl.DSL.count;
import static org.jooq.impl.DSL.currentCatalog;
import static org.jooq.impl.DSL.decode;
import static org.jooq.impl.DSL.falseCondition;
import static org.jooq.impl.DSL.field;
@ -137,6 +138,7 @@ import org.jooq.Result;
import org.jooq.ResultQuery;
import org.jooq.SQLDialect;
import org.jooq.Select;
import org.jooq.SelectOrderByStep;
import org.jooq.SortOrder;
import org.jooq.Table;
import org.jooq.TableField;
@ -188,6 +190,8 @@ import org.jooq.meta.postgres.pg_catalog.tables.PgInherits;
import org.jooq.meta.postgres.pg_catalog.tables.PgType;
import org.jooq.tools.JooqLogger;
import org.jetbrains.annotations.NotNull;
/**
* Postgres uses the ANSI default INFORMATION_SCHEMA, but unfortunately ships
* with a non-capitalised version of it: <code>information_schema</code>. Hence
@ -661,21 +665,46 @@ public class PostgresDatabase extends AbstractDatabase implements ResultQueryDat
@Override
public ResultQuery<Record4<String, String, String, String>> sources(List<String> schemas) {
return create()
.select(
Select<Record4<String, String, String, String>> s =
select(
VIEWS.TABLE_CATALOG,
VIEWS.TABLE_SCHEMA,
VIEWS.TABLE_NAME,
when(VIEWS.VIEW_DEFINITION.lower().like(inline("create%")), VIEWS.VIEW_DEFINITION)
.else_(inline("create view \"").concat(VIEWS.TABLE_NAME).concat(inline("\" as ")).concat(VIEWS.VIEW_DEFINITION)).as(VIEWS.VIEW_DEFINITION))
.from(VIEWS)
.where(VIEWS.TABLE_SCHEMA.in(schemas))
.orderBy(
VIEWS.TABLE_SCHEMA,
VIEWS.TABLE_NAME)
.from(VIEWS);
// [#9483] Some dialects include materialized views in the INFORMATION_SCHEMA.VIEWS view
if (!informationSchemaViewsContainsMaterializedViews()) {
s = s.unionAll(
select(
currentCatalog(),
PG_CLASS.pgNamespace().NSPNAME,
PG_CLASS.RELNAME,
inline("create materialized view \"").concat(PG_CLASS.RELNAME).concat(inline("\" as ")).concat(field("pg_get_viewdef({0})", VARCHAR, PG_CLASS.OID)))
.from(PG_CLASS)
.where(PG_CLASS.RELKIND.eq(inline("m")))
);
}
Table<?> t = s.asTable("t");
return create()
.select(
t.field(VIEWS.TABLE_CATALOG),
t.field(VIEWS.TABLE_SCHEMA),
t.field(VIEWS.TABLE_NAME),
t.field(VIEWS.VIEW_DEFINITION))
.from(t)
.where(t.field(VIEWS.TABLE_SCHEMA).in(schemas))
.orderBy(1, 2, 3)
;
}
protected boolean informationSchemaViewsContainsMaterializedViews() {
return false;
}
@Override
public ResultQuery<Record5<String, String, String, String, String>> comments(List<String> schemas) {
return null;

View File

@ -61,7 +61,7 @@ public final class TableOptions implements Serializable {
private static final TableOptions C_EXPRESSION = new TableOptions(TableType.EXPRESSION);
private static final TableOptions C_FUNCTION = new TableOptions(TableType.FUNCTION);
private static final TableOptions C_MATERIALIZED_VIEW = materializedView(null);
private static final TableOptions C_MATERIALIZED_VIEW = materializedView((String) null);
private static final TableOptions C_TABLE = new TableOptions(TableType.TABLE);
private static final TableOptions C_TEMPORARY = new TableOptions(TableType.TEMPORARY);
private static final TableOptions C_VIEW = view((String) null);
@ -204,6 +204,16 @@ public final class TableOptions implements Serializable {
return new TableOptions(TableType.MATERIALIZED_VIEW, select);
}
/**
* Create a new {@link TableOptions} object for a
* {@link TableType#MATERIALIZED_VIEW} of unknown content.
*/
@NotNull
public static final TableOptions materializedView(String source) {
return new TableOptions(TableType.MATERIALIZED_VIEW, source);
}
/**
* Create a new {@link TableOptions} object for a {@link TableType#EXPRESSION}.
*/

View File

@ -63,6 +63,7 @@ import static org.jooq.SQLDialect.SQLITE;
// ...
import static org.jooq.SQLDialect.TRINO;
import static org.jooq.SQLDialect.YUGABYTEDB;
import static org.jooq.TableOptions.TableType.MATERIALIZED_VIEW;
import static org.jooq.impl.AbstractNamed.findIgnoreCase;
import static org.jooq.impl.DSL.comment;
import static org.jooq.impl.DSL.condition;
@ -814,11 +815,14 @@ final class MetaImpl extends AbstractMeta {
};
private static final TableOptions tableOption(DSLContext ctx, MetaSchema schema, String tableName, TableType tableType) {
if (tableType == TableType.VIEW) {
if (tableType.isView()) {
String sql = M_SOURCES(ctx.dialect());
if (sql != null)
return TableOptions.view(schema.source(tableName));
if (tableType == MATERIALIZED_VIEW)
return TableOptions.materializedView(schema.source(tableName));
else
return TableOptions.view(schema.source(tableName));
}
return TableOptions.of(tableType);

View File

@ -260,10 +260,10 @@ final class MetaSQL {
M_SOURCES.put(HSQLDB, "select INFORMATION_SCHEMA.VIEWS.TABLE_CATALOG, INFORMATION_SCHEMA.VIEWS.TABLE_SCHEMA, INFORMATION_SCHEMA.VIEWS.TABLE_NAME, INFORMATION_SCHEMA.VIEWS.VIEW_DEFINITION from INFORMATION_SCHEMA.VIEWS where INFORMATION_SCHEMA.VIEWS.TABLE_SCHEMA in (cast(? as varchar(128))) order by INFORMATION_SCHEMA.VIEWS.TABLE_SCHEMA, INFORMATION_SCHEMA.VIEWS.TABLE_NAME");
M_SOURCES.put(MARIADB, "select information_schema.VIEWS.TABLE_CATALOG, information_schema.VIEWS.TABLE_SCHEMA, information_schema.VIEWS.TABLE_NAME, case when lower(information_schema.VIEWS.VIEW_DEFINITION) like 'create%' then information_schema.VIEWS.VIEW_DEFINITION else concat(concat(concat('create view `', information_schema.VIEWS.TABLE_NAME), '` as '), information_schema.VIEWS.VIEW_DEFINITION) end as VIEW_DEFINITION from information_schema.VIEWS where information_schema.VIEWS.TABLE_SCHEMA in (?) order by information_schema.VIEWS.TABLE_SCHEMA, information_schema.VIEWS.TABLE_NAME");
M_SOURCES.put(MYSQL, "select information_schema.VIEWS.TABLE_CATALOG, information_schema.VIEWS.TABLE_SCHEMA, information_schema.VIEWS.TABLE_NAME, case when lower(information_schema.VIEWS.VIEW_DEFINITION) like 'create%' then information_schema.VIEWS.VIEW_DEFINITION else concat(concat(concat('create view `', information_schema.VIEWS.TABLE_NAME), '` as '), information_schema.VIEWS.VIEW_DEFINITION) end as VIEW_DEFINITION from information_schema.VIEWS where information_schema.VIEWS.TABLE_SCHEMA in (?) order by information_schema.VIEWS.TABLE_SCHEMA, information_schema.VIEWS.TABLE_NAME");
M_SOURCES.put(POSTGRES, "select information_schema.views.table_catalog, information_schema.views.table_schema, information_schema.views.table_name, case when lower(information_schema.views.view_definition) like 'create%' then information_schema.views.view_definition else ((('create view \"' || information_schema.views.table_name) || '\" as ') || information_schema.views.view_definition) end as view_definition from information_schema.views where information_schema.views.table_schema in (?) order by information_schema.views.table_schema, information_schema.views.table_name");
M_SOURCES.put(POSTGRES, "select t.table_catalog, t.table_schema, t.table_name, t.view_definition from (select information_schema.views.table_catalog, information_schema.views.table_schema, information_schema.views.table_name, case when lower(information_schema.views.view_definition) like 'create%' then information_schema.views.view_definition else ((('create view \"' || information_schema.views.table_name) || '\" as ') || information_schema.views.view_definition) end as view_definition from information_schema.views union all select current_database(), alias_87241969.nspname, pg_catalog.pg_class.relname, ((('create materialized view \"' || pg_catalog.pg_class.relname) || '\" as ') || pg_get_viewdef(pg_catalog.pg_class.oid)) from (pg_catalog.pg_class join pg_catalog.pg_namespace as alias_87241969 on pg_catalog.pg_class.relnamespace = alias_87241969.oid) where pg_catalog.pg_class.relkind = 'm') as t where t.table_schema in (?) order by 1, 2, 3");
M_SOURCES.put(SQLITE, "select null as catalog, null as schema, sqlite_master.name, sqlite_master.sql from sqlite_master order by sqlite_master.name");
M_SOURCES.put(TRINO, "select '' TABLE_CATALOG, INFORMATION_SCHEMA.VIEWS.TABLE_SCHEMA, INFORMATION_SCHEMA.VIEWS.TABLE_NAME, case when lower(INFORMATION_SCHEMA.VIEWS.VIEW_DEFINITION) like 'create%' then INFORMATION_SCHEMA.VIEWS.VIEW_DEFINITION else ((('create view \"' || INFORMATION_SCHEMA.VIEWS.TABLE_NAME) || '\" as ') || INFORMATION_SCHEMA.VIEWS.VIEW_DEFINITION) end VIEW_DEFINITION from INFORMATION_SCHEMA.VIEWS where INFORMATION_SCHEMA.VIEWS.TABLE_SCHEMA in (?) order by INFORMATION_SCHEMA.VIEWS.TABLE_SCHEMA, INFORMATION_SCHEMA.VIEWS.TABLE_NAME");
M_SOURCES.put(YUGABYTEDB, "select information_schema.views.table_catalog, information_schema.views.table_schema, information_schema.views.table_name, case when lower(information_schema.views.view_definition) like 'create%' then information_schema.views.view_definition else ((('create view \"' || information_schema.views.table_name) || '\" as ') || information_schema.views.view_definition) end as view_definition from information_schema.views where information_schema.views.table_schema in (?) order by information_schema.views.table_schema, information_schema.views.table_name");
M_SOURCES.put(YUGABYTEDB, "select t.table_catalog, t.table_schema, t.table_name, t.view_definition from (select information_schema.views.table_catalog, information_schema.views.table_schema, information_schema.views.table_name, case when lower(information_schema.views.view_definition) like 'create%' then information_schema.views.view_definition else ((('create view \"' || information_schema.views.table_name) || '\" as ') || information_schema.views.view_definition) end as view_definition from information_schema.views union all select current_database(), alias_87241969.nspname, pg_catalog.pg_class.relname, ((('create materialized view \"' || pg_catalog.pg_class.relname) || '\" as ') || pg_get_viewdef(pg_catalog.pg_class.oid)) from (pg_catalog.pg_class join pg_catalog.pg_namespace as alias_87241969 on pg_catalog.pg_class.relnamespace = alias_87241969.oid) where pg_catalog.pg_class.relkind = 'm') as t where t.table_schema in (?) order by 1, 2, 3");