[jOOQ/jOOQ#17354] Generated view definition's source code case should match the one from the view text

This commit is contained in:
Lukas Eder 2024-09-24 17:16:25 +02:00
parent 1f35febea7
commit fb9c62849a
8 changed files with 40 additions and 18 deletions

View File

@ -49,14 +49,19 @@ import static org.jooq.SQLDialect.CUBRID;
import static org.jooq.SQLDialect.FIREBIRD;
import static org.jooq.SQLDialect.SQLITE;
// ...
import static org.jooq.impl.DSL.concat;
import static org.jooq.impl.DSL.count;
import static org.jooq.impl.DSL.falseCondition;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.DSL.noCondition;
import static org.jooq.impl.DSL.one;
import static org.jooq.impl.DSL.partitionBy;
import static org.jooq.impl.DSL.rowNumber;
import static org.jooq.impl.DSL.substring;
import static org.jooq.impl.DSL.table;
import static org.jooq.impl.DSL.trim;
import static org.jooq.impl.DSL.upper;
import static org.jooq.impl.DSL.when;
import static org.jooq.meta.AbstractTypedElementDefinition.customType;
import static org.jooq.tools.StringUtils.defaultIfBlank;
@ -699,6 +704,22 @@ public abstract class AbstractDatabase implements Database {
return Stream.of(t).allMatch(this::exists);
}
@Internal
protected Field<String> prependCreateView(Field<String> tableName, Field<String> viewDefinition, char quote) {
return
when(upper(substring(trim(viewDefinition), inline(1), inline(1))).eq(substring(trim(viewDefinition), inline(1), inline(1))),
concat(inline("CREATE VIEW " + quote), tableName, inline(quote + " AS "), viewDefinition))
.else_(concat(inline("create view " + quote), tableName, inline(quote + " as "), viewDefinition));
}
@Internal
protected Field<String> prependCreateMaterializedView(Field<String> tableName, Field<String> viewDefinition, char quote) {
return
when(upper(substring(trim(viewDefinition), inline(1), inline(1))).eq(substring(trim(viewDefinition), inline(1), inline(1))),
concat(inline("CREATE MATERIALIZED VIEW " + quote), tableName, inline(quote + " AS "), viewDefinition))
.else_(concat(inline("create materialized view " + quote), tableName, inline(quote + " as "), viewDefinition));
}
final boolean matches(Pattern pattern, Definition definition) {
if (pattern == null)
return false;

View File

@ -404,7 +404,7 @@ public class FirebirdDatabase extends AbstractDatabase implements ResultQueryDat
inline(null, VARCHAR).as("schema"),
trim(RDB$RELATIONS.RDB$RELATION_NAME),
when(lower(RDB$RELATIONS.RDB$VIEW_SOURCE).like(inline("create%")), trim(RDB$RELATIONS.RDB$VIEW_SOURCE))
.else_(inline("create view \"").concat(trim(RDB$RELATIONS.RDB$RELATION_NAME)).concat(inline("\" as ")).concat(RDB$RELATIONS.RDB$VIEW_SOURCE)).as("view_source"))
.else_(prependCreateView(trim(RDB$RELATIONS.RDB$RELATION_NAME), RDB$RELATIONS.RDB$VIEW_SOURCE, '"')).as("view_source"))
.from(RDB$RELATIONS)
.orderBy(trim(RDB$RELATIONS.RDB$RELATION_NAME));
}
@ -520,7 +520,7 @@ public class FirebirdDatabase extends AbstractDatabase implements ResultQueryDat
trim(when(RDB$RELATIONS.RDB$RELATION_TYPE.eq(inline((short) 1)), inline(TableType.VIEW.name()))
.else_(inline(TableType.TABLE.name()))).as("table_type"),
when(lower(RDB$RELATIONS.RDB$VIEW_SOURCE).like(inline("create%")), trim(RDB$RELATIONS.RDB$VIEW_SOURCE))
.else_(inline("create view \"").concat(trim(RDB$RELATIONS.RDB$RELATION_NAME)).concat("\" as ").concat(RDB$RELATIONS.RDB$VIEW_SOURCE)).as("view_source"))
.else_(prependCreateView(trim(RDB$RELATIONS.RDB$RELATION_NAME), RDB$RELATIONS.RDB$VIEW_SOURCE, '"')).as("view_source"))
.from(RDB$RELATIONS)
.unionAll(
select(

View File

@ -149,6 +149,7 @@ import org.jooq.tools.StringUtils;
import org.jooq.tools.csv.CSVReader;
import org.jooq.util.h2.H2DataType;
import org.jetbrains.annotations.ApiStatus.Internal;
import org.jetbrains.annotations.NotNull;
/**
@ -653,7 +654,7 @@ public class H2Database extends AbstractDatabase implements ResultQueryDatabase
VIEWS.TABLE_CATALOG,
VIEWS.TABLE_SCHEMA,
VIEWS.TABLE_NAME,
concat(inline("create view \""), VIEWS.TABLE_NAME, inline("\" as "), VIEWS.VIEW_DEFINITION).as(VIEWS.VIEW_DEFINITION))
prependCreateView(VIEWS.TABLE_NAME, VIEWS.VIEW_DEFINITION, '"').as(VIEWS.VIEW_DEFINITION))
.from(VIEWS)
.where(VIEWS.TABLE_SCHEMA.in(schemas))
.orderBy(

View File

@ -531,7 +531,7 @@ public class HSQLDBDatabase extends AbstractDatabase implements ResultQueryDatab
trim(when(SYSTEM_TABLES.TABLE_TYPE.eq(inline("VIEW")), inline(TableType.VIEW.name()))
.else_(inline(TableType.TABLE.name()))).as("table_type"),
when(lower(VIEWS.VIEW_DEFINITION).like(inline("create%")), VIEWS.VIEW_DEFINITION)
.else_(inline("create view \"").concat(SYSTEM_TABLES.TABLE_NAME).concat("\" as ").concat(VIEWS.VIEW_DEFINITION)).as(VIEWS.VIEW_DEFINITION)
.else_(prependCreateView(SYSTEM_TABLES.TABLE_NAME, VIEWS.VIEW_DEFINITION, '"')).as(VIEWS.VIEW_DEFINITION)
)
.from(SYSTEM_TABLES)
.leftJoin(VIEWS)

View File

@ -479,7 +479,7 @@ public class MySQLDatabase extends AbstractDatabase implements ResultQueryDataba
VIEWS.TABLE_SCHEMA,
VIEWS.TABLE_NAME,
when(lower(VIEWS.VIEW_DEFINITION).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))
.else_(prependCreateView(VIEWS.TABLE_NAME, VIEWS.VIEW_DEFINITION, '`')).as(VIEWS.VIEW_DEFINITION))
.from(VIEWS)
.where(VIEWS.TABLE_SCHEMA.in(schemas))
.orderBy(

View File

@ -187,6 +187,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
@ -683,17 +685,15 @@ public class PostgresDatabase extends AbstractDatabase implements ResultQueryDat
// [#9483] Some dialects include materialized views in the INFORMATION_SCHEMA.VIEWS view
PgClass c = PG_CLASS.as("c");
Field<String> pgGetViewdef = field("pg_get_viewdef({0})", VARCHAR, c.OID);
return create()
.select(
currentCatalog(),
c.pgNamespace().NSPNAME,
c.RELNAME,
when(c.RELKIND.eq(inline("m")), inline("create materialized view \""))
.else_(inline("create view \""))
.concat(c.RELNAME)
.concat(inline("\" as "))
.concat(field("pg_get_viewdef({0})", VARCHAR, c.OID)))
when(c.RELKIND.eq(inline("m")), prependCreateMaterializedView(c.RELNAME, pgGetViewdef, '"'))
.else_(prependCreateView(c.RELNAME, pgGetViewdef, '"')).as("view_definition"))
.from(c)
.where(c.RELKIND.in(inline("v"), inline("m")))
.and(c.pgNamespace().NSPNAME.in(schemas))

View File

@ -165,7 +165,7 @@ public class TrinoDatabase extends AbstractDatabase implements ResultQueryDataba
VIEWS.TABLE_SCHEMA,
VIEWS.TABLE_NAME,
when(lower(VIEWS.VIEW_DEFINITION).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)
.else_(prependCreateView(VIEWS.TABLE_NAME, VIEWS.VIEW_DEFINITION, '"')).as(VIEWS.VIEW_DEFINITION)
)
.from(VIEWS)
.where(VIEWS.TABLE_SCHEMA.in(schemas))

View File

@ -269,15 +269,15 @@ final class MetaSQL {
M_SOURCES.put(CLICKHOUSE, "select system.tables.database catalog, system.tables.database, system.tables.table, system.tables.create_table_query from system.tables where (system.tables.database in (?) and system.tables.engine = 'View')");
M_SOURCES.put(DERBY, "select cast(null as varchar(32672)) as catalog, SYS.SYSSCHEMAS.SCHEMANAME, SYS.SYSTABLES.TABLENAME, SYS.SYSVIEWS.VIEWDEFINITION from SYS.SYSTABLES join SYS.SYSSCHEMAS on SYS.SYSTABLES.SCHEMAID = SYS.SYSSCHEMAS.SCHEMAID left outer join SYS.SYSVIEWS on SYS.SYSTABLES.TABLEID = SYS.SYSVIEWS.TABLEID where cast(SYS.SYSSCHEMAS.SCHEMANAME as varchar(32672)) in (cast(? as varchar(32672))) order by SYS.SYSSCHEMAS.SCHEMANAME, SYS.SYSTABLES.TABLENAME");
M_SOURCES.put(DUCKDB, "select duckdb_views.database_name, duckdb_views.schema_name, duckdb_views.view_name, duckdb_views.sql from duckdb_views() where duckdb_views.schema_name in (cast(? as varchar))");
M_SOURCES.put(FIREBIRD, "select null catalog, null schema, trim(RDB$RELATIONS.RDB$RELATION_NAME), case when lower(RDB$RELATIONS.RDB$VIEW_SOURCE) like 'create%' then trim(RDB$RELATIONS.RDB$VIEW_SOURCE) else ((('create view \"' || trim(RDB$RELATIONS.RDB$RELATION_NAME)) || '\" as ') || RDB$RELATIONS.RDB$VIEW_SOURCE) end view_source from RDB$RELATIONS order by trim(RDB$RELATIONS.RDB$RELATION_NAME)");
M_SOURCES.put(H2, "select INFORMATION_SCHEMA.VIEWS.TABLE_CATALOG, INFORMATION_SCHEMA.VIEWS.TABLE_SCHEMA, INFORMATION_SCHEMA.VIEWS.TABLE_NAME, ('create view \"' || INFORMATION_SCHEMA.VIEWS.TABLE_NAME || '\" as ' || INFORMATION_SCHEMA.VIEWS.VIEW_DEFINITION) VIEW_DEFINITION from INFORMATION_SCHEMA.VIEWS where INFORMATION_SCHEMA.VIEWS.TABLE_SCHEMA in (cast(? as varchar)) order by INFORMATION_SCHEMA.VIEWS.TABLE_SCHEMA, INFORMATION_SCHEMA.VIEWS.TABLE_NAME");
M_SOURCES.put(FIREBIRD, "select null catalog, null schema, trim(RDB$RELATIONS.RDB$RELATION_NAME), case when lower(RDB$RELATIONS.RDB$VIEW_SOURCE) like 'create%' then trim(RDB$RELATIONS.RDB$VIEW_SOURCE) else case when upper(substring(trim(RDB$RELATIONS.RDB$VIEW_SOURCE) from 1 for 1)) = substring(trim(RDB$RELATIONS.RDB$VIEW_SOURCE) from 1 for 1) then ((('CREATE VIEW \"' || trim(RDB$RELATIONS.RDB$RELATION_NAME)) || '\" AS ') || RDB$RELATIONS.RDB$VIEW_SOURCE) else ((('create view \"' || trim(RDB$RELATIONS.RDB$RELATION_NAME)) || '\" as ') || RDB$RELATIONS.RDB$VIEW_SOURCE) end end view_source from RDB$RELATIONS order by trim(RDB$RELATIONS.RDB$RELATION_NAME)");
M_SOURCES.put(H2, "select INFORMATION_SCHEMA.VIEWS.TABLE_CATALOG, INFORMATION_SCHEMA.VIEWS.TABLE_SCHEMA, INFORMATION_SCHEMA.VIEWS.TABLE_NAME, case when upper(substring(trim(INFORMATION_SCHEMA.VIEWS.VIEW_DEFINITION), 1, 1)) = substring(trim(INFORMATION_SCHEMA.VIEWS.VIEW_DEFINITION), 1, 1) then ('CREATE VIEW \"' || INFORMATION_SCHEMA.VIEWS.TABLE_NAME || '\" AS ' || 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 (cast(? as varchar)) order by INFORMATION_SCHEMA.VIEWS.TABLE_SCHEMA, INFORMATION_SCHEMA.VIEWS.TABLE_NAME");
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('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('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 current_database(), alias_5049504.nspname, c.relname, (case when c.relkind = 'm' then 'create materialized view \"' else 'create view \"' end || c.relname || '\" as ' || pg_get_viewdef(c.oid)) from (pg_catalog.pg_class as c join pg_catalog.pg_namespace as alias_5049504 on c.relnamespace = alias_5049504.oid) where (c.relkind in ('v', 'm') and alias_5049504.nspname in (?)) order by 1, 2, 3");
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 case when upper(substring(trim(information_schema.VIEWS.VIEW_DEFINITION), 1, 1)) = substring(trim(information_schema.VIEWS.VIEW_DEFINITION), 1, 1) then concat('CREATE VIEW `', information_schema.VIEWS.TABLE_NAME, '` AS ', information_schema.VIEWS.VIEW_DEFINITION) else concat('create view `', information_schema.VIEWS.TABLE_NAME, '` as ', information_schema.VIEWS.VIEW_DEFINITION) end 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 case when upper(substring(trim(information_schema.VIEWS.VIEW_DEFINITION), 1, 1)) = substring(trim(information_schema.VIEWS.VIEW_DEFINITION), 1, 1) then concat('CREATE VIEW `', information_schema.VIEWS.TABLE_NAME, '` AS ', information_schema.VIEWS.VIEW_DEFINITION) else concat('create view `', information_schema.VIEWS.TABLE_NAME, '` as ', information_schema.VIEWS.VIEW_DEFINITION) end 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 current_database(), alias_5049504.nspname, c.relname, case when c.relkind = 'm' then case when upper(substring(trim(pg_get_viewdef(c.oid)), 1, 1)) = substring(trim(pg_get_viewdef(c.oid)), 1, 1) then ('CREATE MATERIALIZED VIEW \"' || c.relname || '\" AS ' || pg_get_viewdef(c.oid)) else ('create materialized view \"' || c.relname || '\" as ' || pg_get_viewdef(c.oid)) end else case when upper(substring(trim(pg_get_viewdef(c.oid)), 1, 1)) = substring(trim(pg_get_viewdef(c.oid)), 1, 1) then ('CREATE VIEW \"' || c.relname || '\" AS ' || pg_get_viewdef(c.oid)) else ('create view \"' || c.relname || '\" as ' || pg_get_viewdef(c.oid)) end end as view_definition from (pg_catalog.pg_class as c join pg_catalog.pg_namespace as alias_5049504 on c.relnamespace = alias_5049504.oid) where (c.relkind in ('v', 'm') and alias_5049504.nspname 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 current_database(), alias_5049504.nspname, c.relname, (case when c.relkind = 'm' then 'create materialized view \"' else 'create view \"' end || c.relname || '\" as ' || pg_get_viewdef(c.oid)) from (pg_catalog.pg_class as c join pg_catalog.pg_namespace as alias_5049504 on c.relnamespace = alias_5049504.oid) where (c.relkind in ('v', 'm') and alias_5049504.nspname in (?)) order by 1, 2, 3");
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 case when upper(substring(trim(INFORMATION_SCHEMA.VIEWS.VIEW_DEFINITION), 1, 1)) = substring(trim(INFORMATION_SCHEMA.VIEWS.VIEW_DEFINITION), 1, 1) then ((('CREATE VIEW \"' || INFORMATION_SCHEMA.VIEWS.TABLE_NAME) || '\" AS ') || INFORMATION_SCHEMA.VIEWS.VIEW_DEFINITION) else ((('create view \"' || INFORMATION_SCHEMA.VIEWS.TABLE_NAME) || '\" as ') || INFORMATION_SCHEMA.VIEWS.VIEW_DEFINITION) end 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 current_database(), alias_5049504.nspname, c.relname, case when c.relkind = 'm' then case when upper(substring(trim(pg_get_viewdef(c.oid)), 1, 1)) = substring(trim(pg_get_viewdef(c.oid)), 1, 1) then ('CREATE MATERIALIZED VIEW \"' || c.relname || '\" AS ' || pg_get_viewdef(c.oid)) else ('create materialized view \"' || c.relname || '\" as ' || pg_get_viewdef(c.oid)) end else case when upper(substring(trim(pg_get_viewdef(c.oid)), 1, 1)) = substring(trim(pg_get_viewdef(c.oid)), 1, 1) then ('CREATE VIEW \"' || c.relname || '\" AS ' || pg_get_viewdef(c.oid)) else ('create view \"' || c.relname || '\" as ' || pg_get_viewdef(c.oid)) end end as view_definition from (pg_catalog.pg_class as c join pg_catalog.pg_namespace as alias_5049504 on c.relnamespace = alias_5049504.oid) where (c.relkind in ('v', 'm') and alias_5049504.nspname in (?)) order by 1, 2, 3");