[jOOQ/jOOQ#10827] Add a DSL.currentCatalog() function

This commit is contained in:
Lukas Eder 2020-11-04 12:55:29 +01:00
parent 2226072a28
commit 58e484ee1d
8 changed files with 163 additions and 16 deletions

View File

@ -48,6 +48,9 @@ import static org.jooq.impl.DSL.not;
import static org.jooq.impl.DSL.nullif;
import static org.jooq.impl.DSL.one;
import static org.jooq.impl.DSL.when;
import static org.jooq.impl.SQLDataType.BIGINT;
import static org.jooq.impl.SQLDataType.BOOLEAN;
import static org.jooq.impl.SQLDataType.INTEGER;
import static org.jooq.impl.SQLDataType.VARCHAR;
import static org.jooq.meta.derby.sys.Tables.SYSCHECKS;
import static org.jooq.meta.derby.sys.Tables.SYSCONGLOMERATES;
@ -67,12 +70,16 @@ import java.util.regex.Pattern;
import org.jooq.DSLContext;
import org.jooq.Field;
import org.jooq.Record;
import org.jooq.Record12;
import org.jooq.Record5;
import org.jooq.Record6;
import org.jooq.Result;
import org.jooq.ResultQuery;
import org.jooq.SQLDialect;
import org.jooq.SortOrder;
import org.jooq.TableOptions.TableType;
import org.jooq.impl.DSL;
import org.jooq.impl.SQLDataType;
import org.jooq.meta.AbstractDatabase;
import org.jooq.meta.AbstractIndexDefinition;
import org.jooq.meta.ArrayDefinition;
@ -88,6 +95,7 @@ import org.jooq.meta.EnumDefinition;
import org.jooq.meta.IndexColumnDefinition;
import org.jooq.meta.IndexDefinition;
import org.jooq.meta.PackageDefinition;
import org.jooq.meta.ResultQueryDatabase;
import org.jooq.meta.RoutineDefinition;
import org.jooq.meta.SchemaDefinition;
import org.jooq.meta.SequenceDefinition;
@ -97,7 +105,7 @@ import org.jooq.meta.UDTDefinition;
/**
* @author Lukas Eder
*/
public class DerbyDatabase extends AbstractDatabase {
public class DerbyDatabase extends AbstractDatabase implements ResultQueryDatabase {
@Override
protected void loadPrimaryKeys(DefaultRelations relations) throws SQLException {
@ -132,6 +140,16 @@ public class DerbyDatabase extends AbstractDatabase {
}
}
@Override
public ResultQuery<Record6<String, String, String, String, String, Integer>> primaryKeys(List<String> schemas) {
return null;
}
@Override
public ResultQuery<Record6<String, String, String, String, String, Integer>> uniqueKeys(List<String> schemas) {
return null;
}
private Result<Record5<String, String, String, String, String>> fetchKeys(String constraintType) {
return create().select(
SYSKEYS.sysconglomerates().systables().sysschemas().SCHEMANAME,
@ -337,35 +355,42 @@ public class DerbyDatabase extends AbstractDatabase {
}
@Override
protected List<SequenceDefinition> getSequences0() throws SQLException {
List<SequenceDefinition> result = new ArrayList<>();
for (Record record : create().select(
public ResultQuery<Record12<String, String, String, String, Integer, Integer, Long, Long, Long, Long, Boolean, Long>> sequences(List<String> schemas) {
return create().select(
inline(null, VARCHAR).cast(VARCHAR).as("catalog"),
SYSSEQUENCES.sysschemas().SCHEMANAME,
SYSSEQUENCES.SEQUENCENAME,
SYSSEQUENCES.SEQUENCEDATATYPE,
nullif(SYSSEQUENCES.STARTVALUE, one()).as(SYSSEQUENCES.STARTVALUE),
nullif(SYSSEQUENCES.INCREMENT, one()).as(SYSSEQUENCES.INCREMENT),
inline(null, INTEGER).cast(INTEGER).as("numeric_precision"),
inline(null, INTEGER).cast(INTEGER).as("numeric_scale"),
nullif(SYSSEQUENCES.STARTVALUE, inline(1L)).as(SYSSEQUENCES.STARTVALUE),
nullif(SYSSEQUENCES.INCREMENT, inline(1L)).as(SYSSEQUENCES.INCREMENT),
nullif(SYSSEQUENCES.MINIMUMVALUE, case_(cast(SYSSEQUENCES.SEQUENCEDATATYPE, VARCHAR))
.when(inline("SMALLINT"), inline((long) Short.MIN_VALUE))
.when(inline("INTEGER"), inline((long) Integer.MIN_VALUE))
.when(inline("BIGINT"), inline(Long.MIN_VALUE))
).as(SYSSEQUENCES.MINIMUMVALUE),
).as(SYSSEQUENCES.MINIMUMVALUE),
nullif(SYSSEQUENCES.MAXIMUMVALUE, case_(cast(SYSSEQUENCES.SEQUENCEDATATYPE, VARCHAR))
.when(inline("SMALLINT"), inline((long) Short.MAX_VALUE))
.when(inline("INTEGER"), inline((long) Integer.MAX_VALUE))
.when(inline("BIGINT"), inline(Long.MAX_VALUE))
).as(SYSSEQUENCES.MAXIMUMVALUE),
SYSSEQUENCES.CYCLEOPTION
).as(SYSSEQUENCES.MAXIMUMVALUE),
SYSSEQUENCES.CYCLEOPTION.coerce(BOOLEAN),
inline(null, BIGINT).cast(BIGINT).as("cache")
)
.from(SYSSEQUENCES)
// [#6797] The cast is necessary if a non-standard collation is used
.where(SYSSEQUENCES.sysschemas().SCHEMANAME.cast(VARCHAR(32672)).in(getInputSchemata()))
.where(SYSSEQUENCES.sysschemas().SCHEMANAME.cast(VARCHAR(32672)).in(schemas))
.orderBy(
SYSSEQUENCES.sysschemas().SCHEMANAME,
SYSSEQUENCES.SEQUENCENAME)
.fetch()) {
SYSSEQUENCES.SEQUENCENAME);
}
@Override
protected List<SequenceDefinition> getSequences0() throws SQLException {
List<SequenceDefinition> result = new ArrayList<>();
for (Record record : sequences(getInputSchemata())) {
SchemaDefinition schema = getSchema(record.get(SYSSEQUENCES.sysschemas().SCHEMANAME));
DataTypeDefinition type = new DefaultDataTypeDefinition(

View File

@ -64,7 +64,7 @@ implements
private final Schema schema;
private final boolean createSchemaIfNotExists;
CreateSchemaImpl(
Configuration configuration,

View File

@ -0,0 +1,90 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.impl;
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.DSL.unquotedName;
import static org.jooq.impl.Names.N_CURRENT_CATALOG;
import static org.jooq.impl.Names.N_CURRENT_DATABASE;
import static org.jooq.impl.Names.N_DB_NAME;
import static org.jooq.impl.SQLDataType.VARCHAR;
import org.jooq.Context;
/**
* @author Lukas Eder
*/
final class CurrentCatalog extends AbstractField<String> {
/**
* Generated UID
*/
private static final long serialVersionUID = -7273879239726265322L;
CurrentCatalog() {
super(N_CURRENT_CATALOG, VARCHAR);
}
@Override
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
case FIREBIRD:
case SQLITE:
ctx.visit(inline(""));
break;
case POSTGRES:
default:
ctx.visit(N_CURRENT_DATABASE).sql("()");
break;
}
}
}

View File

@ -26211,6 +26211,15 @@ public class DSL {
return new CurrentSchema();
}
/**
* Get the <code>current_catalog()</code> function.
*/
@NotNull
@Support({ FIREBIRD, POSTGRES, SQLITE })
public static Field<String> currentCatalog() {
return new CurrentCatalog();
}
// -------------------------------------------------------------------------
// XXX utility API
// -------------------------------------------------------------------------

View File

@ -66,7 +66,7 @@ implements
private final Schema schema;
private final boolean dropSchemaIfExists;
private Boolean cascade;
DropSchemaImpl(
Configuration configuration,
Schema schema,
@ -100,7 +100,7 @@ implements
// -------------------------------------------------------------------------
// XXX: DSL API
// -------------------------------------------------------------------------
@Override
public final DropSchemaImpl cascade() {
this.cascade = true;

View File

@ -29,6 +29,7 @@ final class MetaSQL {
M_SEQUENCES.put(DERBY, "select cast(null as varchar(32672)) as catalog, alias_8805161.SCHEMANAME, SYS.SYSSEQUENCES.SEQUENCENAME, SYS.SYSSEQUENCES.SEQUENCEDATATYPE, cast(null as int) as numeric_precision, cast(null as int) as numeric_scale, nullif(SYS.SYSSEQUENCES.STARTVALUE, 1) as STARTVALUE, nullif(SYS.SYSSEQUENCES.INCREMENT, 1) as INCREMENT, nullif(SYS.SYSSEQUENCES.MINIMUMVALUE, case when cast(SYS.SYSSEQUENCES.SEQUENCEDATATYPE as varchar(32672)) = 'SMALLINT' then -32768 when cast(SYS.SYSSEQUENCES.SEQUENCEDATATYPE as varchar(32672)) = 'INTEGER' then -2147483648 when cast(SYS.SYSSEQUENCES.SEQUENCEDATATYPE as varchar(32672)) = 'BIGINT' then -9223372036854775808 end) as MINIMUMVALUE, nullif(SYS.SYSSEQUENCES.MAXIMUMVALUE, case when cast(SYS.SYSSEQUENCES.SEQUENCEDATATYPE as varchar(32672)) = 'SMALLINT' then 32767 when cast(SYS.SYSSEQUENCES.SEQUENCEDATATYPE as varchar(32672)) = 'INTEGER' then 2147483647 when cast(SYS.SYSSEQUENCES.SEQUENCEDATATYPE as varchar(32672)) = 'BIGINT' then 9223372036854775807 end) as MAXIMUMVALUE, SYS.SYSSEQUENCES.CYCLEOPTION, cast(null as bigint) as cache from (SYS.SYSSEQUENCES join SYS.SYSSCHEMAS as alias_8805161 on SYS.SYSSEQUENCES.SCHEMAID = alias_8805161.SCHEMAID) where cast(alias_8805161.SCHEMANAME as varchar(32672)) in (cast(? as varchar(32672))) order by alias_8805161.SCHEMANAME, SYS.SYSSEQUENCES.SEQUENCENAME");
M_SEQUENCES.put(FIREBIRD, "select null catalog, null schema, trim(RDB$GENERATORS.RDB$GENERATOR_NAME) RDB$GENERATOR_NAME, 'BIGINT' type_name, null numeric_precision, null numeric_scale, 0 RDB$INITIAL_VALUE, 1 RDB$GENERATOR_INCREMENT, null min_value, null max_value, null cycle, null cache from RDB$GENERATORS order by RDB$GENERATORS.RDB$GENERATOR_NAME");
M_SEQUENCES.put(H2, "select null catalog, INFORMATION_SCHEMA.SEQUENCES.SEQUENCE_SCHEMA, INFORMATION_SCHEMA.SEQUENCES.SEQUENCE_NAME, 'BIGINT' type_name, null precision, null scale, null start_value, nullif(INFORMATION_SCHEMA.SEQUENCES.INCREMENT, 1) INCREMENT, nullif(INFORMATION_SCHEMA.SEQUENCES.MIN_VALUE, 1) MIN_VALUE, nullif(INFORMATION_SCHEMA.SEQUENCES.MAX_VALUE, 9223372036854775807) MAX_VALUE, INFORMATION_SCHEMA.SEQUENCES.IS_CYCLE, nullif(INFORMATION_SCHEMA.SEQUENCES.CACHE, 32) CACHE from INFORMATION_SCHEMA.SEQUENCES where (INFORMATION_SCHEMA.SEQUENCES.SEQUENCE_SCHEMA in (cast(? as varchar(2147483647))) and upper(INFORMATION_SCHEMA.SEQUENCES.SEQUENCE_NAME) not like 'SYSTEM!_SEQUENCE!_%' escape '!') order by INFORMATION_SCHEMA.SEQUENCES.SEQUENCE_SCHEMA, INFORMATION_SCHEMA.SEQUENCES.SEQUENCE_NAME");
M_SEQUENCES.put(HSQLDB, "select null as catalog, INFORMATION_SCHEMA.SEQUENCES.SEQUENCE_SCHEMA, INFORMATION_SCHEMA.SEQUENCES.SEQUENCE_NAME, INFORMATION_SCHEMA.SEQUENCES.DATA_TYPE, INFORMATION_SCHEMA.SEQUENCES.NUMERIC_PRECISION, INFORMATION_SCHEMA.SEQUENCES.NUMERIC_SCALE, INFORMATION_SCHEMA.SEQUENCES.START_WITH, INFORMATION_SCHEMA.SEQUENCES.INCREMENT, INFORMATION_SCHEMA.SEQUENCES.MINIMUM_VALUE, INFORMATION_SCHEMA.SEQUENCES.MAXIMUM_VALUE, case when INFORMATION_SCHEMA.SEQUENCES.CYCLE_OPTION is not distinct from 'YES' then true else false end as CYCLE_OPTION, null as cache from INFORMATION_SCHEMA.SEQUENCES where INFORMATION_SCHEMA.SEQUENCES.SEQUENCE_SCHEMA in (cast(? as varchar(128))) order by INFORMATION_SCHEMA.SEQUENCES.SEQUENCE_SCHEMA, INFORMATION_SCHEMA.SEQUENCES.SEQUENCE_NAME");

View File

@ -87,6 +87,8 @@ final class Names {
static final Name N_COUNT = unquotedName("count");
static final Name N_COUNTSET = unquotedName("countset");
static final Name N_CURRENT_BIGDATETIME = unquotedName("current_bigdatetime");
static final Name N_CURRENT_CATALOG = unquotedName("current_catalog");
static final Name N_CURRENT_DATABASE = unquotedName("current_database");
static final Name N_CURRENT_DATE = unquotedName("current_date");
static final Name N_CURRENT_SCHEMA = unquotedName("current_schema");
static final Name N_CURRENT_TIME = unquotedName("current_time");

View File

@ -104,6 +104,7 @@ import static org.jooq.impl.DSL.count;
import static org.jooq.impl.DSL.countDistinct;
import static org.jooq.impl.DSL.cube;
import static org.jooq.impl.DSL.cumeDist;
import static org.jooq.impl.DSL.currentCatalog;
import static org.jooq.impl.DSL.currentDate;
import static org.jooq.impl.DSL.currentSchema;
import static org.jooq.impl.DSL.currentTime;
@ -6608,6 +6609,10 @@ final class ParserImpl implements Parser {
if (S.is(type))
if ((field = parseFieldConcatIf(ctx)) != null)
return field;
else if ((parseFunctionNameIf(ctx, "CURRENT_CATALOG") && parse(ctx, '(') && parse(ctx, ')')))
return currentCatalog();
else if ((parseFunctionNameIf(ctx, "CURRENT_DATABASE") && parse(ctx, '(') && parse(ctx, ')')))
return currentCatalog();
else if ((parseKeywordIf(ctx, "CURRENT_SCHEMA") || parseKeywordIf(ctx, "CURRENT SCHEMA")) && (parseIf(ctx, '(') && parse(ctx, ')') || true))
return currentSchema();
else if ((parseKeywordIf(ctx, "CURRENT_USER") || parseKeywordIf(ctx, "CURRENT USER")) && (parseIf(ctx, '(') && parse(ctx, ')') || true))
@ -6680,6 +6685,12 @@ final class ParserImpl implements Parser {
break;
case 'D':
if (S.is(type))
if ((parseFunctionNameIf(ctx, "DB_NAME") && parse(ctx, '(') && parse(ctx, ')')))
return currentCatalog();
else if ((parseFunctionNameIf(ctx, "DBINFO") && parse(ctx, '(') && parseStringLiteral(ctx, "dbname") != null && parse(ctx, ')')))
return currentCatalog();
if (D.is(type))
if ((field = parseFieldDateLiteralIf(ctx)) != null)
return field;
@ -10781,6 +10792,15 @@ final class ParserImpl implements Parser {
return DSL.comment(parseStringLiteral(ctx));
}
private static final String parseStringLiteral(ParserContext ctx, String literal) {
String value = parseStringLiteral(ctx);
if (!literal.equals(value))
throw ctx.expected("String literal: '" + literal + "'");
return value;
}
private static final String parseStringLiteral(ParserContext ctx) {
String result = parseStringLiteralIf(ctx);