use of org.jooq.Table in project jOOQ by jOOQ.
the class SelectQueryImpl method toSQLReference0.
/**
* This method renders the main part of a query without the LIMIT clause.
* This part is common to any type of limited query
*/
@SuppressWarnings("unchecked")
private final void toSQLReference0(Context<?> context, Field<?>[] originalFields, Field<?>[] alternativeFields) {
SQLDialect dialect = context.dialect();
SQLDialect family = dialect.family();
int unionOpSize = unionOp.size();
// The SQL standard specifies:
//
// <query expression> ::=
// [ <with clause> ] <query expression body>
// [ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]
//
// Depending on the dialect and on various syntax elements, parts of the above must be wrapped in
// synthetic parentheses
boolean wrapQueryExpressionInDerivedTable;
boolean wrapQueryExpressionBodyInDerivedTable = false;
wrapQueryExpressionInDerivedTable = false || // interpreted as the (missing) INSERT column list's parens.
(context.data(DATA_INSERT_SELECT_WITHOUT_INSERT_COLUMN_LIST) != null && unionOpSize > 0);
if (wrapQueryExpressionInDerivedTable)
context.keyword("select").sql(" *").formatSeparator().keyword("from").sql(" (").formatIndentStart().formatNewLine();
// all databases, we need to wrap relevant subqueries in parentheses.
if (unionOpSize > 0) {
for (int i = unionOpSize - 1; i >= 0; i--) {
switch(unionOp.get(i)) {
case EXCEPT:
context.start(SELECT_EXCEPT);
break;
case EXCEPT_ALL:
context.start(SELECT_EXCEPT_ALL);
break;
case INTERSECT:
context.start(SELECT_INTERSECT);
break;
case INTERSECT_ALL:
context.start(SELECT_INTERSECT_ALL);
break;
case UNION:
context.start(SELECT_UNION);
break;
case UNION_ALL:
context.start(SELECT_UNION_ALL);
break;
}
unionParenthesis(context, "(");
}
}
// SELECT clause
// -------------
context.start(SELECT_SELECT).keyword("select").sql(' ');
// [#1493] Oracle hints come directly after the SELECT keyword
if (!StringUtils.isBlank(hint)) {
context.sql(hint).sql(' ');
}
if (!distinctOn.isEmpty()) {
context.keyword("distinct on").sql(" (").visit(distinctOn).sql(") ");
} else if (distinct) {
context.keyword("distinct").sql(' ');
}
context.declareFields(true);
// non-ambiguous column names as ambiguous column names are not allowed in subqueries
if (alternativeFields != null) {
if (wrapQueryExpressionBodyInDerivedTable && originalFields.length < alternativeFields.length)
context.visit(new SelectFieldList(Arrays.copyOf(alternativeFields, alternativeFields.length - 1)));
else
context.visit(new SelectFieldList(alternativeFields));
} else // arrays explicitly, as the subquery doesn't form an implicit RVE
if (context.subquery() && dialect == H2 && context.data(DATA_ROW_VALUE_EXPRESSION_PREDICATE_SUBQUERY) != null) {
Object data = context.data(DATA_ROW_VALUE_EXPRESSION_PREDICATE_SUBQUERY);
try {
context.data(DATA_ROW_VALUE_EXPRESSION_PREDICATE_SUBQUERY, null);
context.sql('(').visit(getSelect1()).sql(')');
} finally {
context.data(DATA_ROW_VALUE_EXPRESSION_PREDICATE_SUBQUERY, data);
}
} else // The default behaviour
{
context.visit(getSelect1());
}
context.declareFields(false).end(SELECT_SELECT);
// only in top level SELECTs
if (!context.subquery() && !asList().contains(family)) {
context.start(SELECT_INTO);
Table<?> actualInto = (Table<?>) context.data(DATA_SELECT_INTO_TABLE);
if (actualInto == null)
actualInto = into;
if (actualInto != null && context.data(DATA_OMIT_INTO_CLAUSE) == null && asList(HSQLDB, POSTGRES).contains(family)) {
context.formatSeparator().keyword("into").sql(' ').visit(actualInto);
}
context.end(SELECT_INTO);
}
// FROM and JOIN clauses
// ---------------------
context.start(SELECT_FROM).declareTables(true);
// [#....] Some SQL dialects do not require a FROM clause. Others do and
// jOOQ generates a "DUAL" table or something equivalent.
// See also org.jooq.impl.Dual for details.
boolean hasFrom = !getFrom().isEmpty() || asList(CUBRID, DERBY, FIREBIRD, HSQLDB, MARIADB, MYSQL).contains(family);
List<Condition> semiAntiJoinPredicates = null;
if (hasFrom) {
Object previousCollect = context.data(DATA_COLLECT_SEMI_ANTI_JOIN, true);
Object previousCollected = context.data(DATA_COLLECTED_SEMI_ANTI_JOIN, null);
context.formatSeparator().keyword("from").sql(' ').visit(getFrom());
semiAntiJoinPredicates = (List<Condition>) context.data(DATA_COLLECTED_SEMI_ANTI_JOIN, previousCollected);
context.data(DATA_COLLECT_SEMI_ANTI_JOIN, previousCollect);
}
context.declareTables(false).end(SELECT_FROM);
// WHERE clause
// ------------
context.start(SELECT_WHERE);
if (getWhere().getWhere() instanceof TrueCondition && semiAntiJoinPredicates == null)
;
else {
ConditionProviderImpl where = new ConditionProviderImpl();
if (semiAntiJoinPredicates != null)
where.addConditions(semiAntiJoinPredicates);
if (!(getWhere().getWhere() instanceof TrueCondition))
where.addConditions(getWhere());
context.formatSeparator().keyword("where").sql(' ').visit(where);
}
context.end(SELECT_WHERE);
// CONNECT BY clause
// -----------------
// CUBRID supports this clause only as [ START WITH .. ] CONNECT BY
// Oracle also knows the CONNECT BY .. [ START WITH ] alternative
// syntax
context.start(SELECT_START_WITH);
if (!(getConnectByStartWith().getWhere() instanceof TrueCondition)) {
context.formatSeparator().keyword("start with").sql(' ').visit(getConnectByStartWith());
}
context.end(SELECT_START_WITH);
context.start(SELECT_CONNECT_BY);
if (!(getConnectBy().getWhere() instanceof TrueCondition)) {
context.formatSeparator().keyword("connect by");
if (connectByNoCycle) {
context.sql(' ').keyword("nocycle");
}
context.sql(' ').visit(getConnectBy());
}
context.end(SELECT_CONNECT_BY);
// GROUP BY and HAVING clause
// --------------------------
context.start(SELECT_GROUP_BY);
if (grouping) {
context.formatSeparator().keyword("group by").sql(' ');
// [#1665] Empty GROUP BY () clauses need parentheses
if (getGroupBy().isEmpty()) {
// [#1681] Use the constant field from the dummy table Sybase ASE, Ingres
if (asList().contains(family)) {
context.sql("empty_grouping_dummy_table.dual");
} else // references, as in the ORDER BY clause!
if (asList(DERBY).contains(family)) {
context.sql('0');
} else // [#4447] CUBRID can't handle subqueries in GROUP BY
if (family == CUBRID) {
context.sql("1 + 0");
} else // [#4292] Some dialects don't support empty GROUP BY () clauses
if (asList(FIREBIRD, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE).contains(family)) {
context.sql('(').visit(DSL.select(one())).sql(')');
} else // Few dialects support the SQL standard "grand total" (i.e. empty grouping set)
{
context.sql("()");
}
} else {
context.visit(getGroupBy());
}
}
context.end(SELECT_GROUP_BY);
// HAVING clause
// -------------
context.start(SELECT_HAVING);
if (!(getHaving().getWhere() instanceof TrueCondition)) {
context.formatSeparator().keyword("having").sql(' ').visit(getHaving());
}
context.end(SELECT_HAVING);
// WINDOW clause
// -------------
context.start(SELECT_WINDOW);
if (!getWindow().isEmpty() && asList(POSTGRES).contains(family)) {
context.formatSeparator().keyword("window").sql(' ').declareWindows(true).visit(getWindow()).declareWindows(false);
}
context.end(SELECT_WINDOW);
// ORDER BY clause for local subselect
// -----------------------------------
toSQLOrderBy(context, originalFields, alternativeFields, false, wrapQueryExpressionBodyInDerivedTable, orderBy, limit);
// --------------------------------------------
if (unionOpSize > 0) {
unionParenthesis(context, ")");
for (int i = 0; i < unionOpSize; i++) {
CombineOperator op = unionOp.get(i);
for (Select<?> other : union.get(i)) {
context.formatSeparator().keyword(op.toSQL(dialect)).sql(' ');
unionParenthesis(context, "(");
context.visit(other);
unionParenthesis(context, ")");
}
// [#1658] Close parentheses opened previously
if (i < unionOpSize - 1)
unionParenthesis(context, ")");
switch(unionOp.get(i)) {
case EXCEPT:
context.end(SELECT_EXCEPT);
break;
case EXCEPT_ALL:
context.end(SELECT_EXCEPT_ALL);
break;
case INTERSECT:
context.end(SELECT_INTERSECT);
break;
case INTERSECT_ALL:
context.end(SELECT_INTERSECT_ALL);
break;
case UNION:
context.end(SELECT_UNION);
break;
case UNION_ALL:
context.end(SELECT_UNION_ALL);
break;
}
}
}
// ORDER BY clause for UNION
// -------------------------
boolean qualify = context.qualify();
try {
context.qualify(false);
toSQLOrderBy(context, originalFields, alternativeFields, wrapQueryExpressionInDerivedTable, wrapQueryExpressionBodyInDerivedTable, unionOrderBy, unionLimit);
} finally {
context.qualify(qualify);
}
}
use of org.jooq.Table in project jOOQ by jOOQ.
the class DefaultParseContext method parseInsert.
private final Query parseInsert(WithImpl with, boolean parseResultQuery) {
scopeStart();
parseKeyword("INSERT", "INS");
parseKeywordIf("INTO");
Table<?> table = parseTableNameIf();
if (table == null)
table = table(parseSelect());
Name alias;
if (parseKeywordIf("AS"))
table = table.as(parseIdentifier());
else if (!peekKeyword("DEFAULT VALUES", "SEL", "SELECT", "SET", "VALUES") && (alias = parseIdentifierIf()) != null)
table = table.as(alias);
scope(table);
InsertSetStep<?> s1 = (with == null ? dsl.insertInto(table) : with.insertInto(table));
Field<?>[] fields = null;
if (!peekSelectOrWith(true) && parseIf('(') && !parseIf(')')) {
fields = parseList(',', c -> parseField()).toArray(EMPTY_FIELD);
parse(')');
}
InsertOnDuplicateStep<?> onDuplicate;
InsertReturningStep<?> returning;
try {
// [#11821] The Teradata INSERT INTO t (1, 2) syntax can be recognised:
// When there are non-references fields
boolean hasExpressions = anyMatch(fields, f -> !(f instanceof TableField));
if (hasExpressions || parseKeywordIf("VALUES")) {
List<List<Field<?>>> allValues = new ArrayList<>();
if (hasExpressions) {
allValues.add(asList(fields));
fields = null;
}
valuesLoop: do {
if (hasExpressions && !parseIf(','))
break valuesLoop;
parse('(');
// [#6936] MySQL treats an empty VALUES() clause as the same thing as the standard DEFAULT VALUES
if (fields == null && parseIf(')'))
break valuesLoop;
List<Field<?>> values = parseList(',', c -> c.parseKeywordIf("DEFAULT") ? default_() : c.parseField());
if (fields != null && fields.length != values.size())
throw exception("Insert field size (" + fields.length + ") must match values size (" + values.size() + ")");
allValues.add(values);
parse(')');
} while (parseIf(','));
InsertValuesStepN<?> step2 = (fields != null) ? s1.columns(fields) : (InsertValuesStepN<?>) s1;
for (List<Field<?>> values : allValues) step2 = step2.values(values);
returning = onDuplicate = step2;
} else if (parseKeywordIf("SET")) {
Map<Field<?>, Object> map = parseSetClauseList();
returning = onDuplicate = s1.set(map);
} else if (peekSelectOrWith(true)) {
// [#10954] These are moved into the INSERT .. SELECT clause handling. They should not be necessary here
// either, but it seems we currently don't correctly implement nesting scopes?
scopeEnd(null);
scopeStart();
Select<?> select = parseWithOrSelect();
returning = onDuplicate = (fields == null) ? s1.select(select) : s1.columns(fields).select(select);
} else if (parseKeywordIf("DEFAULT VALUES")) {
if (fields != null)
throw notImplemented("DEFAULT VALUES without INSERT field list");
else
returning = onDuplicate = s1.defaultValues();
} else
throw expected("DEFAULT VALUES", "WITH", "SELECT", "SET", "VALUES");
if (parseKeywordIf("ON")) {
if (parseKeywordIf("DUPLICATE KEY UPDATE")) {
parseKeywordIf("SET");
InsertOnConflictWhereStep<?> where = onDuplicate.onDuplicateKeyUpdate().set(parseSetClauseList());
if (parseKeywordIf("WHERE"))
returning = where.where(parseCondition());
else
returning = where;
} else if (parseKeywordIf("DUPLICATE KEY IGNORE")) {
returning = onDuplicate.onDuplicateKeyIgnore();
} else if (parseKeywordIf("CONFLICT")) {
InsertOnConflictDoUpdateStep<?> doUpdate;
if (parseKeywordIf("ON CONSTRAINT")) {
doUpdate = onDuplicate.onConflictOnConstraint(parseName());
} else if (parseIf('(')) {
InsertOnConflictWhereIndexPredicateStep<?> where = onDuplicate.onConflict(parseList(',', c -> parseFieldName()));
parse(')');
doUpdate = parseKeywordIf("WHERE") ? where.where(parseCondition()) : where;
} else {
doUpdate = onDuplicate.onConflict();
}
parseKeyword("DO");
if (parseKeywordIf("NOTHING")) {
returning = doUpdate.doNothing();
} else if (parseKeywordIf("UPDATE SET")) {
InsertOnConflictWhereStep<?> where = doUpdate.doUpdate().set(parseSetClauseList());
if (parseKeywordIf("WHERE"))
returning = where.where(parseCondition());
else
returning = where;
} else
throw expected("NOTHING", "UPDATE");
} else
throw expected("CONFLICT", "DUPLICATE");
}
return (parseResultQuery ? parseKeyword("RETURNING") : parseKeywordIf("RETURNING")) ? returning.returning(parseSelectList()) : returning;
} finally {
scopeEnd(((InsertImpl) s1).getDelegate());
}
}
use of org.jooq.Table in project jOOQ by jOOQ.
the class DefaultParseContext method parseCommentOn.
private final DDLQuery parseCommentOn() {
parseKeyword("COMMENT ON");
CommentOnIsStep s1;
if (parseKeywordIf("COLUMN")) {
s1 = dsl.commentOnColumn(parseFieldName());
} else if (parseKeywordIf("TABLE")) {
Table<?> table = parseTableName();
if (parseIf('(')) {
s1 = dsl.commentOnColumn(table.getQualifiedName().append(parseIdentifier()));
parseKeyword("IS");
DDLQuery s2 = s1.is(parseStringLiteral());
parse(')');
return s2;
} else
s1 = dsl.commentOnTable(table);
} else if (parseKeywordIf("VIEW")) {
s1 = dsl.commentOnView(parseTableName());
} else // https://docs.oracle.com/database/121/SQLRF/statements_4010.htm
if (parseAndGetKeywordIf("ACCESS METHOD", "AUDIT POLICY", "COLLATION", "CONVERSION", "DATABASE", "DOMAIN", "EDITION", "EXTENSION", "EVENT TRIGGER", "FOREIGN DATA WRAPPER", "FOREIGN TABLE", "INDEX", "INDEXTYPE", "LANGUAGE", "LARGE OBJECT", "MATERIALIZED VIEW", "MINING MODEL", "OPERATOR", "PROCEDURAL LANGUAGE", "PUBLICATION", "ROLE", "SCHEMA", "SEQUENCE", "SERVER", "STATISTICS", "SUBSCRIPTION", "TABLESPACE", "TEXT SEARCH CONFIGURATION", "TEXT SEARCH DICTIONARY", "TEXT SEARCH PARSER", "TEXT SEARCH TEMPLATE", "TYPE", "VIEW") != null) {
parseIdentifier();
parseKeyword("IS");
parseStringLiteral();
return IGNORE;
} else // https://www.postgresql.org/docs/10/static/sql-comment.html
if (parseKeywordIf("CONSTRAINT")) {
parseIdentifier();
parseKeyword("ON");
parseKeywordIf("DOMAIN");
parseName();
parseKeyword("IS");
parseStringLiteral();
return IGNORE;
} else if (parseAndGetKeywordIf("POLICY", "RULE", "TRIGGER") != null) {
parseIdentifier();
parseKeyword("ON");
parseIdentifier();
parseKeyword("IS");
parseStringLiteral();
return IGNORE;
} else if (parseKeywordIf("TRANSFORM FOR")) {
parseIdentifier();
parseKeyword("LANGUAGE");
parseIdentifier();
parseKeyword("IS");
parseStringLiteral();
return IGNORE;
} else
throw unsupportedClause();
parseKeyword("IS");
return s1.is(parseStringLiteral());
}
use of org.jooq.Table in project jOOQ by jOOQ.
the class DefaultParseContext method parseCreateTable.
private final DDLQuery parseCreateTable(boolean temporary) {
boolean ifNotExists = parseKeywordIf("IF NOT EXISTS");
Table<?> tableName = DSL.table(parseTableName().getQualifiedName());
if (parseKeywordIf("USING"))
parseIdentifier();
CreateTableOnCommitStep onCommitStep;
CreateTableCommentStep commentStep;
List<Field<?>> fields = new ArrayList<>();
List<Constraint> constraints = new ArrayList<>();
List<Index> indexes = new ArrayList<>();
boolean primary = false;
boolean identity = false;
boolean readonly = false;
boolean ctas = false;
if (!peekSelectOrWith(true) && parseIf('(')) {
columnLoop: do {
int p = position();
ConstraintTypeStep constraint = parseConstraintNameSpecification();
if (parsePrimaryKeyClusteredNonClusteredKeywordIf()) {
if (primary)
throw exception("Duplicate primary key specification");
primary = true;
constraints.add(parsePrimaryKeySpecification(constraint));
continue columnLoop;
} else if (parseKeywordIf("UNIQUE")) {
if (!parseKeywordIf("KEY"))
parseKeywordIf("INDEX");
// [#9132] Avoid parsing "using" as an identifier
parseUsingIndexTypeIf();
// [#7268] MySQL has some legacy syntax where an index name
// can override a constraint name
Name index = parseIdentifierIf();
if (index != null)
constraint = constraint(index);
constraints.add(parseUniqueSpecification(constraint));
continue columnLoop;
} else if (parseKeywordIf("FOREIGN KEY")) {
constraints.add(parseForeignKeySpecification(constraint));
continue columnLoop;
} else if (parseKeywordIf("CHECK")) {
constraints.add(parseCheckSpecification(constraint));
continue columnLoop;
} else if (constraint == null && parseIndexOrKeyIf()) {
parseUsingIndexTypeIf();
int p2 = position();
// Look ahead if the next tokens indicate a MySQL index definition
if (parseIf('(') || (parseDataTypeIf(false) == null && parseIdentifierIf() != null && parseUsingIndexTypeIf() && parseIf('('))) {
position(p2);
indexes.add(parseIndexSpecification(tableName));
parseUsingIndexTypeIf();
continue columnLoop;
} else {
position(p);
}
} else if (constraint != null)
throw expected("CHECK", "CONSTRAINT", "FOREIGN KEY", "INDEX", "KEY", "PRIMARY KEY", "UNIQUE");
Name fieldName = parseIdentifier();
boolean skipType = peek(',') || peek(')');
// If only we had multiple return values or destructuring...
ParseInlineConstraints inlineConstraints = parseInlineConstraints(fieldName, !skipType ? parseDataType() : SQLDataType.OTHER, constraints, primary, identity, readonly);
primary = inlineConstraints.primary;
identity = inlineConstraints.identity;
fields.add(field(fieldName, inlineConstraints.type, inlineConstraints.fieldComment));
} while (parseIf(','));
if (fields.isEmpty())
throw expected("At least one column");
parse(')');
} else
ctas = true;
CreateTableElementListStep elementListStep = ifNotExists ? temporary ? dsl.createTemporaryTableIfNotExists(tableName) : dsl.createTableIfNotExists(tableName) : temporary ? dsl.createTemporaryTable(tableName) : dsl.createTable(tableName);
if (!fields.isEmpty())
elementListStep = elementListStep.columns(fields);
CreateTableElementListStep constraintStep = constraints.isEmpty() ? elementListStep : elementListStep.constraints(constraints);
CreateTableAsStep asStep = indexes.isEmpty() ? constraintStep : constraintStep.indexes(indexes);
// [#6133] Historically, the jOOQ API places the ON COMMIT clause after
// the AS clause, which doesn't correspond to dialect implementations
Function<CreateTableOnCommitStep, CreateTableCommentStep> onCommit;
if (temporary && parseKeywordIf("ON COMMIT")) {
if (parseKeywordIf("DELETE ROWS"))
onCommit = CreateTableOnCommitStep::onCommitDeleteRows;
else if (parseKeywordIf("DROP"))
onCommit = CreateTableOnCommitStep::onCommitDrop;
else if (parseKeywordIf("PRESERVE ROWS"))
onCommit = CreateTableOnCommitStep::onCommitPreserveRows;
else
throw unsupportedClause();
} else
onCommit = s -> s;
// keyword only for empty field lists
if (parseKeywordIf("AS") || fields.isEmpty() && peekSelectOrWith(true)) {
boolean previousMetaLookupsForceIgnore = metaLookupsForceIgnore();
CreateTableWithDataStep withDataStep = asStep.as((Select<Record>) metaLookupsForceIgnore(false).parseQuery(true, true));
metaLookupsForceIgnore(previousMetaLookupsForceIgnore);
onCommitStep = parseKeywordIf("WITH DATA") ? withDataStep.withData() : parseKeywordIf("WITH NO DATA") ? withDataStep.withNoData() : withDataStep;
} else if (ctas)
throw expected("AS, WITH, SELECT, or (");
else
onCommitStep = asStep;
commentStep = onCommit.apply(onCommitStep);
List<SQL> storage = new ArrayList<>();
Comment comment = null;
storageLoop: for (boolean first = true; ; first = false) {
boolean optional = first || !parseIf(',');
Keyword keyword = null;
// MySQL storage clauses (see: https://dev.mysql.com/doc/refman/5.7/en/create-table.html)
if ((keyword = parseAndGetKeywordIf("AUTO_INCREMENT")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseFieldUnsignedNumericLiteral(Sign.NONE)));
} else if ((keyword = parseAndGetKeywordIf("AVG_ROW_LENGTH")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseFieldUnsignedNumericLiteral(Sign.NONE)));
} else if ((keyword = parseAndGetKeywordIf("CHARACTER SET")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseIdentifier()));
} else if ((keyword = parseAndGetKeywordIf("DEFAULT CHARACTER SET")) != null || (keyword = parseAndGetKeywordIf("DEFAULT CHARSET")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseIdentifier()));
} else if ((keyword = parseAndGetKeywordIf("CHECKSUM")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseZeroOne()));
} else if ((keyword = parseAndGetKeywordIf("COLLATE")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseIdentifier()));
} else if ((keyword = parseAndGetKeywordIf("DEFAULT COLLATE")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseIdentifier()));
} else // [#10164] In a statement batch, this could already be the next statement
if (!peekKeyword("COMMENT ON") && parseKeywordIf("COMMENT")) {
if (!parseIf('='))
parseKeywordIf("IS");
comment = parseComment();
} else if (peekKeyword("OPTIONS")) {
comment = parseOptionsDescription();
} else if ((keyword = parseAndGetKeywordIf("COMPRESSION")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseStringLiteral()));
} else if ((keyword = parseAndGetKeywordIf("CONNECTION")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseStringLiteral()));
} else if ((keyword = parseAndGetKeywordIf("DATA DIRECTORY")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseStringLiteral()));
} else if ((keyword = parseAndGetKeywordIf("INDEX DIRECTORY")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseStringLiteral()));
} else if ((keyword = parseAndGetKeywordIf("DELAY_KEY_WRITE")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseZeroOne()));
} else if ((keyword = parseAndGetKeywordIf("ENCRYPTION")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseStringLiteral()));
} else if ((keyword = parseAndGetKeywordIf("ENGINE")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseIdentifier()));
} else if ((keyword = parseAndGetKeywordIf("INSERT_METHOD")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseAndGetKeyword("NO", "FIRST", "LAST")));
} else if ((keyword = parseAndGetKeywordIf("KEY_BLOCK_SIZE")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseFieldUnsignedNumericLiteral(Sign.NONE)));
} else if ((keyword = parseAndGetKeywordIf("MAX_ROWS")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseFieldUnsignedNumericLiteral(Sign.NONE)));
} else if ((keyword = parseAndGetKeywordIf("MIN_ROWS")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseFieldUnsignedNumericLiteral(Sign.NONE)));
} else if ((keyword = parseAndGetKeywordIf("PACK_KEYS")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseZeroOneDefault()));
} else if ((keyword = parseAndGetKeywordIf("PASSWORD")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseStringLiteral()));
} else if ((keyword = parseAndGetKeywordIf("ROW_FORMAT")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseAndGetKeyword("DEFAULT", "DYNAMIC", "FIXED", "COMPRESSED", "REDUNDANT", "COMPACT")));
} else if ((keyword = parseAndGetKeywordIf("STATS_AUTO_RECALC")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseZeroOneDefault()));
} else if ((keyword = parseAndGetKeywordIf("STATS_PERSISTENT")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseZeroOneDefault()));
} else if ((keyword = parseAndGetKeywordIf("STATS_SAMPLE_PAGES")) != null) {
parseIf('=');
storage.add(sql("{0} {1}", keyword, parseFieldUnsignedNumericLiteral(Sign.NONE)));
} else if ((keyword = parseAndGetKeywordIf("TABLESPACE")) != null) {
storage.add(sql("{0} {1}", keyword, parseIdentifier()));
if ((keyword = parseAndGetKeywordIf("STORAGE")) != null)
storage.add(sql("{0} {1}", keyword, parseAndGetKeyword("DISK", "MEMORY", "DEFAULT")));
} else if ((keyword = parseAndGetKeywordIf("UNION")) != null) {
parseIf('=');
parse('(');
storage.add(sql("{0} ({1})", keyword, list(parseIdentifiers())));
parse(')');
} else if (optional)
break storageLoop;
else
throw expected("storage clause after ','");
}
CreateTableStorageStep storageStep = comment != null ? commentStep.comment(comment) : commentStep;
if (storage.size() > 0)
return storageStep.storage(new SQLConcatenationImpl(storage.toArray(EMPTY_QUERYPART)));
else
return storageStep;
}
use of org.jooq.Table in project jOOQ by jOOQ.
the class MergeImpl method toSQLStandard.
private final void toSQLStandard(Context<?> ctx) {
ctx.start(MERGE_MERGE_INTO).visit(K_MERGE_INTO).sql(' ').declareTables(true, c -> c.visit(table)).end(MERGE_MERGE_INTO).formatSeparator().start(MERGE_USING).visit(K_USING).sql(' ');
ctx.declareTables(true, c1 -> c1.data(DATA_WRAP_DERIVED_TABLES_IN_PARENTHESES, true, c2 -> {
// in its MERGE statement.
if (usingDual) {
switch(c2.family()) {
case DERBY:
c2.visit(new Dual());
break;
default:
c2.visit(DSL.selectOne());
break;
}
} else
c2.visit(using);
}));
boolean onParentheses = false;
ctx.end(MERGE_USING).formatSeparator().start(MERGE_ON).visit(K_ON).sql(onParentheses ? " (" : " ").visit(on).sql(onParentheses ? ")" : "").end(MERGE_ON).start(MERGE_WHEN_MATCHED_THEN_UPDATE).start(MERGE_SET);
// [#7291] Multi MATCHED emulation
boolean emulate = false;
boolean requireMatchedConditions = false;
// [#10054] TODO: Skip all WHEN MATCHED clauses after a WHEN MATCHED clause with no search condition
if (NO_SUPPORT_CONDITION_AFTER_NO_CONDITION.contains(ctx.dialect())) {
boolean withoutMatchedConditionFound = false;
for (MatchedClause m : matched) {
if (requireMatchedConditions |= withoutMatchedConditionFound)
break;
withoutMatchedConditionFound |= m.condition instanceof NoCondition;
}
}
emulateCheck: if ((NO_SUPPORT_MULTI.contains(ctx.dialect()) && matched.size() > 1)) {
boolean matchUpdate = false;
boolean matchDelete = false;
for (MatchedClause m : matched) {
if (m.delete) {
if (emulate |= matchDelete)
break emulateCheck;
matchDelete = true;
} else {
if (emulate |= matchUpdate)
break emulateCheck;
matchUpdate = true;
}
}
}
if (emulate) {
MatchedClause update = null;
MatchedClause delete = null;
Condition negate = noCondition();
for (MatchedClause m : matched) {
Condition condition = negate.and(m.condition);
if (m.delete) {
if (delete == null)
delete = new MatchedClause(noCondition(), true);
delete.condition = delete.condition.or(condition);
} else {
if (update == null)
update = new MatchedClause(noCondition());
for (Entry<Field<?>, Field<?>> e : m.updateMap.entrySet()) {
Field<?> exp = update.updateMap.get(e.getKey());
if (exp instanceof CaseConditionStepImpl)
((CaseConditionStepImpl) exp).when(negate.and(condition), e.getValue());
else
update.updateMap.put(e.getKey(), when(negate.and(condition), (Field) e.getValue()).else_(e.getKey()));
}
update.condition = update.condition.or(condition);
}
if (REQUIRE_NEGATION.contains(ctx.dialect()))
negate = negate.andNot(m.condition instanceof NoCondition ? trueCondition() : m.condition);
}
{
if (delete != null)
toSQLMatched(ctx, delete, requireMatchedConditions);
if (update != null)
toSQLMatched(ctx, update, requireMatchedConditions);
}
} else // [#7291] Workaround for https://github.com/h2database/h2database/issues/2552
if (REQUIRE_NEGATION.contains(ctx.dialect())) {
Condition negate = noCondition();
for (MatchedClause m : matched) {
toSQLMatched(ctx, new MatchedClause(negate.and(m.condition), m.delete, m.updateMap), requireMatchedConditions);
negate = negate.andNot(m.condition instanceof NoCondition ? trueCondition() : m.condition);
}
} else {
for (MatchedClause m : matched) toSQLMatched(ctx, m, requireMatchedConditions);
}
ctx.end(MERGE_SET).end(MERGE_WHEN_MATCHED_THEN_UPDATE).start(MERGE_WHEN_NOT_MATCHED_THEN_INSERT);
for (NotMatchedClause m : notMatched) toSQLNotMatched(ctx, m);
ctx.end(MERGE_WHEN_NOT_MATCHED_THEN_INSERT);
}
Aggregations