use of org.jooq.CreateTableElementListStep 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;
}
Aggregations