[jOOQ/jOOQ#2620] Support Google BigQuery - WIP

This includes:

- [jOOQ/jOOQ#11461] MetaTable does not contain table COMMENT (REMARKS)
This commit is contained in:
Lukas Eder 2021-02-17 21:34:11 +01:00
parent 7759f5bb7a
commit ad21db797a
38 changed files with 294 additions and 61 deletions

View File

@ -41,6 +41,7 @@ import org.jooq.SQLDialect;
// ...
// ...
// ...
// ...
import org.jooq.meta.cubrid.CUBRIDDatabase;
// ...
import org.jooq.meta.derby.DerbyDatabase;
@ -77,7 +78,6 @@ public class Databases {
/**
* Get a reference to a {@link Database} class for a given {@link SQLDialect}.
*/
@SuppressWarnings("deprecation")
public static final Class<? extends Database> databaseClass(SQLDialect dialect) {
Class<? extends Database> result = JDBCDatabase.class;
@ -101,6 +101,7 @@ public class Databases {
case CUBRID: result = CUBRIDDatabase.class; break;
case DERBY: result = DerbyDatabase.class; break;

View File

@ -55,7 +55,7 @@ public class DefaultMetaTableDefinition extends AbstractTableDefinition {
private final Table<?> table;
public DefaultMetaTableDefinition(SchemaDefinition schema, Table<?> table) {
super(schema, table.getName(), "");
super(schema, table.getName(), table.getComment());
this.table = table;
}
@ -85,7 +85,7 @@ public class DefaultMetaTableDefinition extends AbstractTableDefinition {
result.size() + 1,
type,
false,
null
field.getComment()
));
}

View File

@ -47,6 +47,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
import static org.jooq.SQLDialect.DEFAULT;
@ -172,6 +173,7 @@ public @interface Allow {
CUBRID,

View File

@ -43,6 +43,7 @@ package org.jooq;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
import static org.jooq.SQLDialect.DERBY;

View File

@ -40,6 +40,7 @@ package org.jooq;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
import static org.jooq.SQLDialect.H2;

View File

@ -705,6 +705,14 @@ public enum SQLDialect {

View File

@ -42,6 +42,7 @@ package org.jooq;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
import static org.jooq.SQLDialect.DERBY;

View File

@ -43,6 +43,7 @@ package org.jooq;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
import static org.jooq.SQLDialect.DERBY;

View File

@ -50,6 +50,7 @@ import static org.jooq.Clause.TABLE_REFERENCE;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
import static org.jooq.SQLDialect.DERBY;
import static org.jooq.SQLDialect.FIREBIRD;

View File

@ -57,6 +57,7 @@ import static org.jooq.Nullability.NULL;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
import static org.jooq.SQLDialect.DERBY;
@ -101,6 +102,7 @@ import static org.jooq.impl.Keywords.K_BEFORE;
import static org.jooq.impl.Keywords.K_CASCADE;
import static org.jooq.impl.Keywords.K_CHANGE;
import static org.jooq.impl.Keywords.K_CHANGE_COLUMN;
import static org.jooq.impl.Keywords.K_COLUMN;
import static org.jooq.impl.Keywords.K_COMMENT;
import static org.jooq.impl.Keywords.K_CONSTRAINT;
import static org.jooq.impl.Keywords.K_CONSTRAINTS;
@ -1312,6 +1314,11 @@ final class AlterTableImpl extends AbstractRowCountQuery implements
ctx.start(ALTER_TABLE_ADD)
.visit(K_ADD).sql(' ');
if (ifNotExistsColumn && supportsIfNotExistsColumn(ctx))
ctx.visit(K_IF_NOT_EXISTS).sql(' ');

View File

@ -46,7 +46,6 @@ import java.util.Set;
import org.jooq.Condition;
import org.jooq.Context;
import org.jooq.Field;
import org.jooq.SQLDialect;
/**
@ -77,6 +76,9 @@ final class BoolAnd extends DefaultAggregateFunction<Boolean> {
default:
super.acceptFunctionName(ctx);
break;

View File

@ -100,6 +100,9 @@ final class BoolOr extends DefaultAggregateFunction<Boolean> {
default:
super.acceptFunctionName(ctx);
break;

View File

@ -38,6 +38,7 @@
package org.jooq.impl;
// ...
// ...
import static org.jooq.impl.Keywords.K_MINUS;
@ -57,46 +58,48 @@ enum CombineOperator {
* Unite the sets of rows produced by the two {@link Select}'s (disallowing
* duplicate records).
*/
UNION("union"),
UNION("union", true),
/**
* Unite the bags of rows produced by the two {@link Select}'s (allowing
* duplicate records).
*/
UNION_ALL("union all"),
UNION_ALL("union all", false),
/**
* Remove all rows in the set of rows produced by the second {@link Select}
* from the set of rows produced by the first {@link Select} (disallowing
* duplicate records).
*/
EXCEPT("except"),
EXCEPT("except", true),
/**
* Remove all rows in the bag of rows produced by the second {@link Select}
* from the bag of rows produced by the first {@link Select} (allowing
* duplicate records).
*/
EXCEPT_ALL("except all"),
EXCEPT_ALL("except all", false),
/**
* Retain all rows in the sets of rows produced by both {@link Select}'s
* (disallowing duplicate records).
*/
INTERSECT("intersect"),
INTERSECT("intersect", true),
/**
* Retain all rows in the bags of rows produced by both {@link Select}'s
* (allowing duplicate records).
*/
INTERSECT_ALL("intersect all");
INTERSECT_ALL("intersect all", false);
private final String sql;
private final Keyword keywordOptionalDistinct;
private final Keyword keyword;
private CombineOperator(String sql) {
private CombineOperator(String sql, boolean distinct) {
this.sql = sql;
this.keyword = DSL.keyword(sql);
this.keywordOptionalDistinct = distinct ? DSL.keyword(sql + " distinct") : keyword;
}
public final String toSQL(SQLDialect dialect) {
@ -114,6 +117,8 @@ enum CombineOperator {
return keyword;
}
}

View File

@ -162,6 +162,10 @@ implements
case MARIADB:
case MYSQL: {
if (table != null)
@ -223,6 +227,13 @@ implements

View File

@ -40,6 +40,7 @@ package org.jooq.impl;
import static java.lang.Boolean.TRUE;
import static org.jooq.Clause.CONSTRAINT;
// ...
// ...
import static org.jooq.SQLDialect.IGNITE;
// ...
// ...
@ -150,6 +151,7 @@ implements
*/
private static final long serialVersionUID = 1018023703769802616L;
private static final Clause[] CLAUSES = { CONSTRAINT };
private static final Set<SQLDialect> NO_SUPPORT_PK = SQLDialect.supportedBy();
private static final Set<SQLDialect> NO_SUPPORT_UK = SQLDialect.supportedBy(IGNITE);
private static final Set<SQLDialect> NO_SUPPORT_FK = SQLDialect.supportedBy(IGNITE);
private static final Set<SQLDialect> NO_SUPPORT_CHECK = SQLDialect.supportedBy(IGNITE);
@ -1159,7 +1161,7 @@ implements
}
final boolean supported(Context<?> ctx) {
return primaryKey != null
return primaryKey != null && !NO_SUPPORT_PK.contains(ctx.dialect())
|| unique != null && !NO_SUPPORT_UK.contains(ctx.dialect())
|| references != null && !NO_SUPPORT_FK.contains(ctx.dialect())
|| check != null && !NO_SUPPORT_CHECK.contains(ctx.dialect());

View File

@ -46,6 +46,7 @@ import static org.jooq.Operator.OR;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
// ...
@ -23353,8 +23354,8 @@ public class DSL {
* <code>percentile_cont([number]) within group (order by [column])</code>
* function.
* <p>
* While {@link SQLDialect#ORACLE} and {@link SQLDialect#POSTGRES} support
* this as an aggregate function, {@link SQLDialect#SQLSERVER} and
* While most dialects support this as an aggregate function,
* {@link SQLDialect#BIGQUERY}, {@link SQLDialect#SQLSERVER}, and
* {@link SQLDialect#REDSHIFT} support only its window function variant.
*/
@NotNull
@ -23368,8 +23369,8 @@ public class DSL {
* <code>percentile_cont([number]) within group (order by [column])</code>
* function.
* <p>
* While {@link SQLDialect#ORACLE} and {@link SQLDialect#POSTGRES} support
* this as an aggregate function, {@link SQLDialect#SQLSERVER} and
* While most dialects support this as an aggregate function,
* {@link SQLDialect#BIGQUERY}, {@link SQLDialect#SQLSERVER}, and
* {@link SQLDialect#REDSHIFT} support only its window function variant.
*/
@NotNull
@ -23383,8 +23384,8 @@ public class DSL {
* <code>percentile_disc([number]) within group (order by [column])</code>
* function.
* <p>
* While {@link SQLDialect#ORACLE} and {@link SQLDialect#POSTGRES} support
* this as an aggregate function, {@link SQLDialect#SQLSERVER} and
* While most dialects support this as an aggregate function,
* {@link SQLDialect#BIGQUERY}, {@link SQLDialect#SQLSERVER}, and
* {@link SQLDialect#REDSHIFT} support only its window function variant.
*/
@NotNull
@ -23398,8 +23399,8 @@ public class DSL {
* <code>percentile_disc([number]) within group (order by [column])</code>
* function.
* <p>
* While {@link SQLDialect#ORACLE} and {@link SQLDialect#POSTGRES} support
* this as an aggregate function, {@link SQLDialect#SQLSERVER} and
* While most dialects support this as an aggregate function,
* {@link SQLDialect#BIGQUERY}, {@link SQLDialect#SQLSERVER}, and
* {@link SQLDialect#REDSHIFT} support only its window function variant.
*/
@NotNull

View File

@ -51,6 +51,7 @@ import static java.time.temporal.ChronoField.YEAR;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
import static org.jooq.SQLDialect.DEFAULT;
@ -565,6 +566,8 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
final DataType<T> dataType;
final Converter<T, U> converter;
final boolean attachable;
@ -819,12 +822,17 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
/**
* Escape a string literal by replacing <code>'</code> by <code>''</code>, and possibly also backslashes.
*/
static final String escape(Object val, Context<?> context) {
static final String escape(Object val, Context<?> ctx) {
String result = val.toString();
if (needsBackslashEscaping(context.configuration()))
if (needsBackslashEscaping(ctx.configuration()))
result = StringUtils.replace(result, "\\", "\\\\");
return StringUtils.replace(result, "'", "''");
}
@ -2809,6 +2817,7 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
// [#5895] HSQLDB derives the specific data type from the literal
case HSQLDB:
ctx.render().visit(K_TIMESTAMP).sql(" '").sql(escape(format(value, family), ctx.render())).sql('\'');
@ -4028,6 +4037,7 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
// [#1253] Derby doesn't support the standard literal
else if (ctx.family() == DERBY)
ctx.render().visit(K_TIMESTAMP).sql("('").sql(escape(value, ctx.render())).sql("')");

View File

@ -47,6 +47,7 @@ import static org.jooq.Clause.DELETE_WHERE;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
import static org.jooq.SQLDialect.DERBY;
@ -73,6 +74,7 @@ import static org.jooq.SQLDialect.SQLITE;
import static org.jooq.conf.SettingsTools.getExecuteDeleteWithoutWhere;
import static org.jooq.impl.DSL.row;
import static org.jooq.impl.DSL.select;
import static org.jooq.impl.DSL.trueCondition;
import static org.jooq.impl.Keywords.K_DELETE;
import static org.jooq.impl.Keywords.K_FROM;
import static org.jooq.impl.Keywords.K_LIMIT;
@ -114,6 +116,11 @@ final class DeleteQueryImpl<R extends Record> extends AbstractDMLQuery<R> implem
// LIMIT is supported but not ORDER BY
private static final Set<SQLDialect> NO_SUPPORT_ORDER_BY_LIMIT = SQLDialect.supportedBy(IGNITE);
private final TableList using;
private final ConditionProviderImpl condition;
private final SortFieldList orderBy;
@ -259,6 +266,12 @@ final class DeleteQueryImpl<R extends Record> extends AbstractDMLQuery<R> implem
.visit(K_WHERE).sql(' ')
.visit(getWhere());
ctx.end(DELETE_WHERE);
if (!orderBy.isEmpty())

View File

@ -134,6 +134,7 @@ final class Dual extends AbstractTable<Record> {
case H2:
case POSTGRES:
case SQLITE:

View File

@ -103,6 +103,7 @@ extends
case CUBRID:
case DERBY:

View File

@ -76,6 +76,7 @@ final class Identifiers {
case MARIADB:
case MYSQL:
QUOTES.put(family, new char[][][] {

View File

@ -129,6 +129,7 @@ final class Keywords {
static final Keyword K_DEFINE = keyword("define");
static final Keyword K_DELETE = keyword("delete");
static final Keyword K_DENSE_RANK = keyword("dense_rank");
static final Keyword K_DESCRIPTION = keyword("description");
static final Keyword K_DETERMINISTIC = keyword("deterministic");
static final Keyword K_DISABLE = keyword("disable");
static final Keyword K_DISTINCT = keyword("distinct");
@ -299,9 +300,11 @@ final class Keywords {
static final Keyword K_ON_DUPLICATE_KEY_UPDATE = keyword("on duplicate key update");
static final Keyword K_ON_UPDATE = keyword("on update");
static final Keyword K_OPEN = keyword("open");
static final Keyword K_OPTIONS = keyword("options");
static final Keyword K_OR = keyword("or");
static final Keyword K_ORDER = keyword("order");
static final Keyword K_ORDER_BY = keyword("order by");
static final Keyword K_ORDINAL = keyword("ordinal");
static final Keyword K_ORDINALITY = keyword("ordinality");
static final Keyword K_OUT = keyword("out");
static final Keyword K_OUTPUT = keyword("output");
@ -387,6 +390,7 @@ final class Keywords {
static final Keyword K_STATEMENT = keyword("statement");
static final Keyword K_STEP = keyword("step");
static final Keyword K_STORING = keyword("storing");
static final Keyword K_STRUCT = keyword("struct");
static final Keyword K_SWITCH = keyword("switch");
static final Keyword K_SYMMETRIC = keyword("symmetric");
static final Keyword K_TABLE = keyword("table");

View File

@ -40,6 +40,7 @@ package org.jooq.impl;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
import static org.jooq.SQLDialect.H2;

View File

@ -59,6 +59,7 @@ import static org.jooq.SQLDialect.POSTGRES;
import static org.jooq.SQLDialect.SQLITE;
// ...
import static org.jooq.impl.AbstractNamed.findIgnoreCase;
import static org.jooq.impl.DSL.comment;
import static org.jooq.impl.DSL.condition;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.name;
@ -401,7 +402,8 @@ final class MetaImpl extends AbstractMeta {
SQLDataType.VARCHAR, // TABLE_CAT
SQLDataType.VARCHAR, // TABLE_SCHEM
SQLDataType.VARCHAR, // TABLE_NAME
SQLDataType.VARCHAR // TABLE_TYPE
SQLDataType.VARCHAR, // TABLE_TYPE
SQLDataType.VARCHAR // REMARKS
);
}
});
@ -412,6 +414,7 @@ final class MetaImpl extends AbstractMeta {
String schema = table.get(1, String.class);
String name = table.get(2, String.class);
String type = table.get(3, String.class);
String remarks = table.get(4, String.class);
// "TABLE","VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY","LOCAL TEMPORARY", "ALIAS", "SYNONYM".
TableType tableType =
@ -430,7 +433,14 @@ final class MetaImpl extends AbstractMeta {
: TableType.TABLE;
result.add(new MetaTable(name, this, getColumns(catalog, schema, name), getUks(catalog, schema, name), tableType));
result.add(new MetaTable(
name,
this,
getColumns(catalog, schema, name),
getUks(catalog, schema, name),
remarks,
tableType
));
// TODO: Find a more efficient way to do this
// Result<Record> pkColumns = executor.fetch(meta().getPrimaryKeys(catalog, schema, name))
@ -684,8 +694,8 @@ final class MetaImpl extends AbstractMeta {
private static final long serialVersionUID = 4843841667753000233L;
private final Result<Record> uks;
MetaTable(String name, Schema schema, Result<Record> columns, Result<Record> uks, TableType tableType) {
super(name(name), schema, null, null, null, null, null, TableOptions.of(tableType));
MetaTable(String name, Schema schema, Result<Record> columns, Result<Record> uks, String remarks, TableType tableType) {
super(name(name), schema, null, null, null, null, comment(remarks), TableOptions.of(tableType));
// Possible scenarios for columns being null:
// - The "table" is in fact a SYNONYM

View File

@ -37,9 +37,11 @@
*/
package org.jooq.impl;
import static org.jooq.impl.DSL.keyword;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.DSL.unquotedName;
import org.jooq.Keyword;
import org.jooq.Name;
/**
@ -186,6 +188,8 @@ final class Names {
static final Name N_LOCATE = unquotedName("locate");
static final Name N_LOG = unquotedName("log");
static final Name N_LOG10 = unquotedName("log10");
static final Name N_LOGICAL_AND = unquotedName("logical_and");
static final Name N_LOGICAL_OR = unquotedName("logical_or");
static final Name N_LOGN = unquotedName("logn");
static final Name N_LOWER = unquotedName("lower");
static final Name N_LPAD = unquotedName("lpad");
@ -257,6 +261,7 @@ final class Names {
static final Name N_SIN = unquotedName("sin");
static final Name N_SINH = unquotedName("sinh");
static final Name N_SPACE = unquotedName("space");
static final Name N_SPLIT = unquotedName("split");
static final Name N_SPLIT_PART = unquotedName("split_part");
static final Name N_SQL_TSI_DAY = unquotedName("sql_tsi_day");
static final Name N_SQL_TSI_FRAC_SECOND = unquotedName("sql_tsi_frac_second");

View File

@ -98,6 +98,7 @@ final class Nvl<T> extends AbstractField<T> {
case MARIADB:
case MYSQL:
case SQLITE:

View File

@ -3853,8 +3853,21 @@ final class ParserContext {
}
else if (parseKeywordIf("OWNER TO") && parseUser() != null)
return IGNORE;
else if (parseKeywordIf("SET"))
return dsl.alterView(oldName).comment(parseOptionsDescription());
else
throw expected("OWNER TO", "RENAME");
throw expected("OWNER TO", "RENAME", "SET");
}
private final Comment parseOptionsDescription() {
parseKeyword("OPTIONS");
parse('(');
parseKeyword("DESCRIPTION");
parse('=');
Comment comment = parseComment();
parse(')');
return comment;
}
private final DDLQuery parseDropView() {
@ -4261,10 +4274,13 @@ final class ParserContext {
}
// [#10164] In a statement batch, this could already be the next statement
else if (!peekKeyword("COMMENT ON") && (keyword = parseAndGetKeywordIf("COMMENT")) != null) {
else if (!peekKeyword("COMMENT ON") && parseKeywordIf("COMMENT")) {
parseIf('=');
comment = parseComment();
}
else if (peekKeyword("OPTIONS")) {
comment = parseOptionsDescription();
}
else if ((keyword = parseAndGetKeywordIf("COMPRESSION")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseStringLiteral()));
@ -4576,6 +4592,10 @@ final class ParserContext {
fieldComment = parseComment();
continue;
}
else if (peekKeyword("OPTIONS")) {
fieldComment = parseOptionsDescription();
continue;
}
}
break;
@ -4948,9 +4968,15 @@ final class ParserContext {
}
break;
case 'S':
if (parseKeywordIf("SET"))
return s1.comment(parseOptionsDescription());
break;
}
throw expected("ADD", "ALTER", "COMMENT", "DROP", "MODIFY", "OWNER TO", "RENAME");
throw expected("ADD", "ALTER", "COMMENT", "DROP", "MODIFY", "OWNER TO", "RENAME", "SET");
}
private final AlterTableFinalStep parseCascadeRestrictIf(AlterTableDropStep step) {
@ -12298,30 +12324,74 @@ final class ParserContext {
}
private final ComputationalOperation parseComputationalOperationIf() {
if (parseFunctionNameIf("AVG"))
return ComputationalOperation.AVG;
else if (parseFunctionNameIf("MAX"))
return ComputationalOperation.MAX;
else if (parseFunctionNameIf("MIN"))
return ComputationalOperation.MIN;
else if (parseFunctionNameIf("SUM"))
return ComputationalOperation.SUM;
else if (parseFunctionNameIf("PRODUCT"))
return ComputationalOperation.PRODUCT;
else if (parseFunctionNameIf("MEDIAN"))
return ComputationalOperation.MEDIAN;
else if (parseFunctionNameIf("EVERY", "BOOL_AND", "BOOLAND_AGG"))
return ComputationalOperation.EVERY;
else if (parseFunctionNameIf("ANY", "SOME", "BOOL_OR", "BOOLOR_AGG"))
return ComputationalOperation.ANY;
else if (parseFunctionNameIf("STDDEV_POP", "STDEVP"))
return ComputationalOperation.STDDEV_POP;
else if (parseFunctionNameIf("STDDEV_SAMP", "STDEV", "STDEV_SAMP"))
return ComputationalOperation.STDDEV_SAMP;
else if (parseFunctionNameIf("VAR_POP", "VARIANCE", "VARP"))
return ComputationalOperation.VAR_POP;
else if (parseFunctionNameIf("VAR_SAMP", "VARIANCE_SAMP", "VAR"))
return ComputationalOperation.VAR_SAMP;
switch (characterUpper()) {
case 'A':
if (parseFunctionNameIf("ANY"))
return ComputationalOperation.ANY;
else if (parseFunctionNameIf("AVG"))
return ComputationalOperation.AVG;
break;
case 'B':
if (parseFunctionNameIf("BOOL_AND", "BOOLAND_AGG"))
return ComputationalOperation.EVERY;
else if (parseFunctionNameIf("BOOL_OR", "BOOLOR_AGG"))
return ComputationalOperation.ANY;
break;
case 'E':
if (parseFunctionNameIf("EVERY"))
return ComputationalOperation.EVERY;
break;
case 'L':
if (parseFunctionNameIf("LOGICAL_AND"))
return ComputationalOperation.EVERY;
else if (parseFunctionNameIf("LOGICAL_OR"))
return ComputationalOperation.ANY;
break;
case 'M':
if (parseFunctionNameIf("MAX"))
return ComputationalOperation.MAX;
else if (parseFunctionNameIf("MEDIAN"))
return ComputationalOperation.MEDIAN;
else if (parseFunctionNameIf("MIN"))
return ComputationalOperation.MIN;
break;
case 'P':
if (parseFunctionNameIf("PRODUCT"))
return ComputationalOperation.PRODUCT;
break;
case 'S':
if (parseFunctionNameIf("SUM"))
return ComputationalOperation.SUM;
else if (parseFunctionNameIf("SOME"))
return ComputationalOperation.ANY;
else if (parseFunctionNameIf("STDDEV_POP", "STDEVP"))
return ComputationalOperation.STDDEV_POP;
else if (parseFunctionNameIf("STDDEV_SAMP", "STDEV", "STDEV_SAMP"))
return ComputationalOperation.STDDEV_SAMP;
break;
case 'V':
if (parseFunctionNameIf("VAR_POP", "VARIANCE", "VARP"))
return ComputationalOperation.VAR_POP;
else if (parseFunctionNameIf("VAR_SAMP", "VARIANCE_SAMP", "VAR"))
return ComputationalOperation.VAR_SAMP;
break;
}
return null;
}

View File

@ -122,6 +122,7 @@ extends
default:
ctx.visit(
DSL.case_(DSL.position(DSL.substring(in, startIndex), search))

View File

@ -140,6 +140,7 @@ extends
case FIREBIRD:

View File

@ -42,6 +42,7 @@ package org.jooq.impl;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
import static org.jooq.SQLDialect.DERBY;
@ -103,6 +104,7 @@ import org.jooq.types.YearToSecond;
// ...
// ...
// ...
// ...
import org.jooq.util.cubrid.CUBRIDDataType;
// ...
import org.jooq.util.derby.DerbyDataType;
@ -763,6 +765,9 @@ public final class SQLDataType {

View File

@ -65,6 +65,7 @@ import static org.jooq.Operator.OR;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
// ...

View File

@ -111,6 +111,7 @@ extends
case DERBY:
case HSQLDB:
case POSTGRES:

View File

@ -94,7 +94,17 @@ extends
@Override
public final void accept(Context<?> ctx) {
ctx.visit(N_SPLIT_PART).sql('(').visit(string).sql(", ").visit(delimiter).sql(", ").visit(n).sql(')');
switch (ctx.family()) {
default:
ctx.visit(N_SPLIT_PART).sql('(').visit(string).sql(", ").visit(delimiter).sql(", ").visit(n).sql(')');
break;
}
}

View File

@ -43,6 +43,7 @@ import static org.jooq.Clause.TABLE_ALIAS;
import static org.jooq.Clause.TABLE_REFERENCE;
// ...
// ...
// ...
import static org.jooq.SQLDialect.FIREBIRD;
import static org.jooq.SQLDialect.HSQLDB;
// ...
@ -64,6 +65,7 @@ import org.jooq.Context;
import org.jooq.Field;
import org.jooq.ForeignKey;
import org.jooq.Name;
// ...
import org.jooq.Record;
import org.jooq.Row;
import org.jooq.SQLDialect;
@ -83,11 +85,15 @@ import org.jooq.tools.StringUtils;
@org.jooq.Internal
public class TableImpl<R extends Record> extends AbstractTable<R> {
private static final long serialVersionUID = 261033315221985068L;
private static final Clause[] CLAUSES_TABLE_REFERENCE = { TABLE, TABLE_REFERENCE };
private static final Clause[] CLAUSES_TABLE_ALIAS = { TABLE, TABLE_ALIAS };
private static final Set<SQLDialect> NO_SUPPORT_QUALIFIED_TVF_CALLS = SQLDialect.supportedBy(HSQLDB, POSTGRES);
private static final Set<SQLDialect> REQUIRES_TVF_TABLE_CONSTRUCTOR = SQLDialect.supportedBy(HSQLDB);
private static final long serialVersionUID = 261033315221985068L;
private static final Clause[] CLAUSES_TABLE_REFERENCE = { TABLE, TABLE_REFERENCE };
private static final Clause[] CLAUSES_TABLE_ALIAS = { TABLE, TABLE_ALIAS };
private static final Set<SQLDialect> NO_SUPPORT_QUALIFIED_TVF_CALLS = SQLDialect.supportedBy(HSQLDB, POSTGRES);
private static final Set<SQLDialect> REQUIRES_TVF_TABLE_CONSTRUCTOR = SQLDialect.supportedBy(HSQLDB);
final FieldsImpl<R> fields;
final Alias<Table<R>> alias;
@ -301,8 +307,12 @@ public class TableImpl<R extends Record> extends AbstractTable<R> {
if (ctx.declareTables())
ctx.scopeMarkStart(this);
if (ctx.qualify() &&
(!NO_SUPPORT_QUALIFIED_TVF_CALLS.contains(ctx.dialect()) || parameters == null || ctx.declareTables())) {
if (ctx.qualify() && (ctx.declareTables()
|| (!NO_SUPPORT_QUALIFIED_TVF_CALLS.contains(ctx.dialect()) || parameters == null)
)) {
Schema mappedSchema = Tools.getMappedSchema(ctx.configuration(), getSchema());
if (mappedSchema != null && !"".equals(mappedSchema.getName())) {

View File

@ -48,6 +48,7 @@ import static java.util.Collections.singletonList;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
import static org.jooq.SQLDialect.DERBY;
import static org.jooq.SQLDialect.FIREBIRD;
@ -879,6 +880,10 @@ final class Tools {
// ------------------------------------------------------------------------
// XXX: Record constructors and related methods
// ------------------------------------------------------------------------
@ -5043,6 +5048,10 @@ final class Tools {
// [#6289] [#7191] Some databases don't support lengths on binary types
if (type.isBinary() && NO_SUPPORT_BINARY_TYPE_LENGTH.contains(ctx.dialect()))
ctx.sql(typeName);
else if (type.length() > 0)
ctx.sql(typeName).sql('(').sql(type.length()).sql(')');
@ -5071,6 +5080,10 @@ final class Tools {
ctx.sql(typeName).sql('(').sql(type.precision()).sql(", ").sql(type.scale()).sql(')');
else
ctx.sql(typeName).sql('(').sql(type.precision()).sql(')');
else
ctx.sql(type.getCastTypeName(ctx.configuration()));
}

View File

@ -49,6 +49,7 @@ import static org.jooq.Clause.UPDATE_WHERE;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
import static org.jooq.SQLDialect.DERBY;
@ -74,6 +75,7 @@ import static org.jooq.SQLDialect.SQLITE;
import static org.jooq.conf.SettingsTools.getExecuteUpdateWithoutWhere;
import static org.jooq.impl.DSL.row;
import static org.jooq.impl.DSL.select;
import static org.jooq.impl.DSL.trueCondition;
import static org.jooq.impl.Keywords.K_FROM;
import static org.jooq.impl.Keywords.K_LIMIT;
import static org.jooq.impl.Keywords.K_ORDER_BY;
@ -161,6 +163,9 @@ final class UpdateQueryImpl<R extends Record> extends AbstractStoreQuery<R> impl
private static final Set<SQLDialect> SUPPORT_RVE_SET = SQLDialect.supportedBy(H2, HSQLDB, POSTGRES);
private static final Set<SQLDialect> REQUIRE_RVE_ROW_CLAUSE = SQLDialect.supportedBy(POSTGRES);
@ -674,6 +679,12 @@ final class UpdateQueryImpl<R extends Record> extends AbstractStoreQuery<R> impl
.visit(K_WHERE).sql(' ')
.visit(getWhere());
ctx.end(UPDATE_WHERE);
if (!orderBy.isEmpty())

View File

@ -41,6 +41,7 @@ import static org.jooq.Clause.TABLE_VALUES;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.FIREBIRD;
// ...
// ...
@ -57,7 +58,9 @@ import static org.jooq.SQLDialect.MYSQL;
// ...
import static org.jooq.impl.Keywords.K_MULTISET;
import static org.jooq.impl.Keywords.K_ROW;
import static org.jooq.impl.Keywords.K_STRUCT;
import static org.jooq.impl.Keywords.K_TABLE;
import static org.jooq.impl.Keywords.K_UNNEST;
import static org.jooq.impl.Keywords.K_VALUES;
import static org.jooq.impl.Names.N_VALUES;
import static org.jooq.impl.Tools.visitSubquery;
@ -146,6 +149,8 @@ final class Values<R extends Record> extends AbstractTable<R> {
ctx.visit(K_VALUES);
if (rows.length > 1)
@ -162,6 +167,10 @@ final class Values<R extends Record> extends AbstractTable<R> {
if (ctx.family() == MYSQL)
ctx.visit(K_ROW).sql(" ");
ctx.visit(rows[i]);
}
@ -173,6 +182,8 @@ final class Values<R extends Record> extends AbstractTable<R> {
ctx.end(TABLE_VALUES);
}
}

View File

@ -37,6 +37,7 @@
*/
package org.jooq.tools.jdbc;
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
@ -405,6 +406,8 @@ public class JDBCUtils {
@ -467,6 +470,8 @@ public class JDBCUtils {