From 05e49b28001c96c6b69eeedae05e15510caee43e Mon Sep 17 00:00:00 2001 From: lukaseder Date: Thu, 31 Jan 2019 15:03:12 +0100 Subject: [PATCH] [#5309] [#7518] Add support for CREATE TABLE t(c1, c2, ..., cn) AS SELECT ... --- .../resources/org/jooq/web/grammar-3.12.txt | 2 +- .../main/java/org/jooq/CreateTableAsStep.java | 50 -------- .../java/org/jooq/CreateTableColumnStep.java | 2 +- jOOQ/src/main/java/org/jooq/DSLContext.java | 24 ++-- .../java/org/jooq/impl/CreateTableImpl.java | 99 ++++++++------- jOOQ/src/main/java/org/jooq/impl/DSL.java | 26 ++-- .../java/org/jooq/impl/DefaultDSLContext.java | 34 +++--- .../main/java/org/jooq/impl/ParserImpl.java | 115 ++++++++++-------- 8 files changed, 163 insertions(+), 189 deletions(-) diff --git a/jOOQ-manual/src/main/resources/org/jooq/web/grammar-3.12.txt b/jOOQ-manual/src/main/resources/org/jooq/web/grammar-3.12.txt index bb4f82e68e..5d000e5de0 100644 --- a/jOOQ-manual/src/main/resources/org/jooq/web/grammar-3.12.txt +++ b/jOOQ-manual/src/main/resources/org/jooq/web/grammar-3.12.txt @@ -191,7 +191,7 @@ break createTableStatement = 'CREATE' [ [ 'GLOBAL' ] 'TEMPORARY' ] 'TABLE' [ 'IF NOT EXISTS' ] tableName ( break ) ( - 'AS' select + [ '(' identifiers ')' ] 'AS' select | '(' ( 'CONSTRAINT' constraintName constraint | constraint | index | column ) { ',' ( 'CONSTRAINT' constraintName constraint | constraint | index | column ) } ')' ) diff --git a/jOOQ/src/main/java/org/jooq/CreateTableAsStep.java b/jOOQ/src/main/java/org/jooq/CreateTableAsStep.java index d2e916577d..de4405627e 100644 --- a/jOOQ/src/main/java/org/jooq/CreateTableAsStep.java +++ b/jOOQ/src/main/java/org/jooq/CreateTableAsStep.java @@ -58,8 +58,6 @@ import static org.jooq.SQLDialect.SQLITE; // ... // ... -import java.util.Collection; - /** * A {@link Query} that can create tables. *

@@ -90,52 +88,4 @@ public interface CreateTableAsStep { */ @Support({ CUBRID, DERBY, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE }) CreateTableWithDataStep as(Select select); - - /** - * Add a column to the column list of the CREATE TABLE - * statement. - *

- * This is the same as calling {@link #column(Field, DataType)} with - * {@link Field#getDataType()} as the argument data type. - */ - @Support - CreateTableColumnStep column(Field field); - - /** - * Add a column to the column list of the CREATE TABLE statement. - */ - @Support - CreateTableColumnStep column(Field field, DataType type); - - /** - * Add a column to the column list of the CREATE TABLE statement. - */ - @Support - CreateTableColumnStep column(Name field, DataType type); - - /** - * Add a column to the column list of the CREATE TABLE statement. - */ - @Support - CreateTableColumnStep column(String field, DataType type); - - /** - * Add several columns to the column list of the CREATE TABLE - * statement. - *

- * This is the same as calling {@link #column(Field, DataType)} for each - * column, with {@link Field#getDataType()} as the argument data type. - */ - @Support - CreateTableColumnStep columns(Field... fields); - - /** - * Add several columns to the column list of the CREATE TABLE - * statement. - *

- * This is the same as calling {@link #column(Field, DataType)} for each - * column, with {@link Field#getDataType()} as the argument data type. - */ - @Support - CreateTableColumnStep columns(Collection> fields); } diff --git a/jOOQ/src/main/java/org/jooq/CreateTableColumnStep.java b/jOOQ/src/main/java/org/jooq/CreateTableColumnStep.java index 923d815176..134150871d 100644 --- a/jOOQ/src/main/java/org/jooq/CreateTableColumnStep.java +++ b/jOOQ/src/main/java/org/jooq/CreateTableColumnStep.java @@ -62,7 +62,7 @@ import java.util.Collection; * * @author Lukas Eder */ -public interface CreateTableColumnStep extends CreateTableConstraintStep { +public interface CreateTableColumnStep extends CreateTableAsStep, CreateTableConstraintStep { /** * Add a column to the column list of the CREATE TABLE diff --git a/jOOQ/src/main/java/org/jooq/DSLContext.java b/jOOQ/src/main/java/org/jooq/DSLContext.java index 2306639d58..7a99d91023 100644 --- a/jOOQ/src/main/java/org/jooq/DSLContext.java +++ b/jOOQ/src/main/java/org/jooq/DSLContext.java @@ -8525,7 +8525,7 @@ public interface DSLContext extends Scope , AutoCloseable { * @see DSL#createTable(String) */ @Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE }) - CreateTableAsStep createTable(String table); + CreateTableColumnStep createTable(String table); /** * Create a new DSL CREATE TABLE statement. @@ -8533,7 +8533,7 @@ public interface DSLContext extends Scope , AutoCloseable { * @see DSL#createTable(Name) */ @Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE }) - CreateTableAsStep createTable(Name table); + CreateTableColumnStep createTable(Name table); /** * Create a new DSL CREATE TABLE statement. @@ -8541,7 +8541,7 @@ public interface DSLContext extends Scope , AutoCloseable { * @see DSL#createTable(Table) */ @Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE }) - CreateTableAsStep createTable(Table table); + CreateTableColumnStep createTable(Table table); /** * Create a new DSL CREATE TABLE statement. @@ -8549,7 +8549,7 @@ public interface DSLContext extends Scope , AutoCloseable { * @see DSL#createTableIfNotExists(String) */ @Support({ FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE }) - CreateTableAsStep createTableIfNotExists(String table); + CreateTableColumnStep createTableIfNotExists(String table); /** * Create a new DSL CREATE TABLE statement. @@ -8557,7 +8557,7 @@ public interface DSLContext extends Scope , AutoCloseable { * @see DSL#createTableIfNotExists(Name) */ @Support({ FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE }) - CreateTableAsStep createTableIfNotExists(Name table); + CreateTableColumnStep createTableIfNotExists(Name table); /** * Create a new DSL CREATE TABLE statement. @@ -8565,7 +8565,7 @@ public interface DSLContext extends Scope , AutoCloseable { * @see DSL#createTableIfNotExists(Table) */ @Support({ FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE }) - CreateTableAsStep createTableIfNotExists(Table table); + CreateTableColumnStep createTableIfNotExists(Table table); /** * Create a new DSL CREATE TEMPORARY TABLE statement. @@ -8573,7 +8573,7 @@ public interface DSLContext extends Scope , AutoCloseable { * @see DSL#createTemporaryTable(String) */ @Support({ MARIADB, MYSQL, POSTGRES }) - CreateTableAsStep createTemporaryTable(String table); + CreateTableColumnStep createTemporaryTable(String table); /** * Create a new DSL CREATE TEMPORARY TABLE statement. @@ -8581,7 +8581,7 @@ public interface DSLContext extends Scope , AutoCloseable { * @see DSL#createTemporaryTable(Name) */ @Support({ MARIADB, MYSQL, POSTGRES }) - CreateTableAsStep createTemporaryTable(Name table); + CreateTableColumnStep createTemporaryTable(Name table); /** * Create a new DSL CREATE TEMPORARY TABLE statement. @@ -8589,7 +8589,7 @@ public interface DSLContext extends Scope , AutoCloseable { * @see DSL#createTemporaryTable(Table) */ @Support({ MARIADB, MYSQL, POSTGRES }) - CreateTableAsStep createTemporaryTable(Table table); + CreateTableColumnStep createTemporaryTable(Table table); /** * Create a new DSL CREATE GLOBAL TEMPORARY TABLE statement. @@ -8597,7 +8597,7 @@ public interface DSLContext extends Scope , AutoCloseable { * @see DSL#createGlobalTemporaryTable(String) */ @Support({ MARIADB, MYSQL, POSTGRES }) - CreateTableAsStep createGlobalTemporaryTable(String table); + CreateTableColumnStep createGlobalTemporaryTable(String table); /** * Create a new DSL CREATE GLOBAL TEMPORARY TABLE statement. @@ -8605,7 +8605,7 @@ public interface DSLContext extends Scope , AutoCloseable { * @see DSL#createGlobalTemporaryTable(Name) */ @Support({ MARIADB, MYSQL, POSTGRES }) - CreateTableAsStep createGlobalTemporaryTable(Name table); + CreateTableColumnStep createGlobalTemporaryTable(Name table); /** * Create a new DSL CREATE GLOBAL TEMPORARY TABLE statement. @@ -8613,7 +8613,7 @@ public interface DSLContext extends Scope , AutoCloseable { * @see DSL#createGlobalTemporaryTable(Table) */ @Support({ MARIADB, MYSQL, POSTGRES }) - CreateTableAsStep createGlobalTemporaryTable(Table table); + CreateTableColumnStep createGlobalTemporaryTable(Table table); /** * Create a new DSL CREATE VIEW statement. diff --git a/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java b/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java index e283a5983a..c3d571ae29 100644 --- a/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java @@ -104,7 +104,6 @@ import org.jooq.Comment; import org.jooq.Configuration; import org.jooq.Constraint; import org.jooq.Context; -import org.jooq.CreateTableAsStep; import org.jooq.CreateTableColumnStep; import org.jooq.CreateTableWithDataStep; import org.jooq.DataType; @@ -123,10 +122,9 @@ import org.jooq.Table; /** * @author Lukas Eder */ -final class CreateTableImpl extends AbstractQuery implements +final class CreateTableImpl extends AbstractQuery implements // Cascading interface implementations for CREATE TABLE behaviour - CreateTableAsStep, CreateTableWithDataStep, CreateTableColumnStep { @@ -149,6 +147,8 @@ final class CreateTableImpl extends AbstractQuery implements + + private final Table table; private Select select; private Boolean withData; @@ -179,36 +179,36 @@ final class CreateTableImpl extends AbstractQuery implements // ------------------------------------------------------------------------ @Override - public final CreateTableImpl as(Select s) { + public final CreateTableImpl as(Select s) { this.select = s; return this; } @Override - public final CreateTableImpl withData() { + public final CreateTableImpl withData() { withData = true; return this; } @Override - public final CreateTableImpl withNoData() { + public final CreateTableImpl withNoData() { withData = false; return this; } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override - public final CreateTableImpl column(Field field) { + public final CreateTableImpl column(Field field) { return column((Field) field, field.getDataType()); } @Override - public final CreateTableImpl columns(Field... fields) { + public final CreateTableImpl columns(Field... fields) { return columns(Arrays.asList(fields)); } @Override - public final CreateTableImpl columns(Collection> fields) { + public final CreateTableImpl columns(Collection> fields) { for (Field field : fields) column(field); @@ -216,103 +216,103 @@ final class CreateTableImpl extends AbstractQuery implements } @Override - public final CreateTableImpl column(Field field, DataType type) { + public final CreateTableImpl column(Field field, DataType type) { columnFields.add(field); columnTypes.add(type); return this; } @Override - public final CreateTableImpl column(Name field, DataType type) { + public final CreateTableImpl column(Name field, DataType type) { columnFields.add(field(field, type)); columnTypes.add(type); return this; } @Override - public final CreateTableImpl column(String field, DataType type) { + public final CreateTableImpl column(String field, DataType type) { return column(name(field), type); } @Override - public final CreateTableImpl constraint(Constraint c) { + public final CreateTableImpl constraint(Constraint c) { return constraints(Arrays.asList(c)); } @Override - public final CreateTableImpl constraints(Constraint... c) { + public final CreateTableImpl constraints(Constraint... c) { return constraints(Arrays.asList(c)); } @Override - public final CreateTableImpl constraints(Collection c) { + public final CreateTableImpl constraints(Collection c) { constraints.addAll(c); return this; } @Override - public final CreateTableImpl index(Index i) { + public final CreateTableImpl index(Index i) { return indexes(Arrays.asList(i)); } @Override - public final CreateTableImpl indexes(Index... i) { + public final CreateTableImpl indexes(Index... i) { return indexes(Arrays.asList(i)); } @Override - public final CreateTableImpl indexes(Collection i) { + public final CreateTableImpl indexes(Collection i) { indexes.addAll(i); return this; } @Override - public final CreateTableImpl onCommitDeleteRows() { + public final CreateTableImpl onCommitDeleteRows() { onCommit = OnCommit.DELETE_ROWS; return this; } @Override - public final CreateTableImpl onCommitPreserveRows() { + public final CreateTableImpl onCommitPreserveRows() { onCommit = OnCommit.PRESERVE_ROWS; return this; } @Override - public final CreateTableImpl onCommitDrop() { + public final CreateTableImpl onCommitDrop() { onCommit = OnCommit.DROP; return this; } @Override - public final CreateTableImpl comment(String c) { + public final CreateTableImpl comment(String c) { return comment(DSL.comment(c)); } @Override - public final CreateTableImpl comment(Comment c) { + public final CreateTableImpl comment(Comment c) { comment = c; return this; } @Override - public final CreateTableImpl storage(SQL sql) { + public final CreateTableImpl storage(SQL sql) { storage = sql; return this; } @Override - public final CreateTableImpl storage(String sql) { + public final CreateTableImpl storage(String sql) { return storage(sql(sql)); } @Override - public final CreateTableImpl storage(String sql, Object... bindings) { + public final CreateTableImpl storage(String sql, Object... bindings) { return storage(sql(sql, bindings)); } @Override - public final CreateTableImpl storage(String sql, QueryPart... parts) { + public final CreateTableImpl storage(String sql, QueryPart... parts) { return storage(sql(sql, parts)); } @@ -420,7 +420,26 @@ final class CreateTableImpl extends AbstractQuery implements acceptCreateTableAsSelect(ctx); } else { - toSQLCreateTableName(ctx); + toSQLCreateTable(ctx); + toSQLOnCommit(ctx); + } + + if (comment != null && !EMULATE_COMMENT_IN_BLOCK.contains(ctx.family())) + ctx.formatSeparator() + .visit(K_COMMENT).sql(' ').visit(comment); + + // [#7772] This data() value should be available from ctx directly, not only from ctx.configuration() + if (storage != null && ctx.configuration().data("org.jooq.meta.extensions.ddl.ignore-storage-clauses") == null) + ctx.formatSeparator() + .visit(storage); + + ctx.end(CREATE_TABLE); + } + + private void toSQLCreateTable(Context ctx) { + toSQLCreateTableName(ctx); + + if (!columnFields.isEmpty()) { ctx.sql('(') .start(CREATE_TABLE_COLUMNS) .formatIndentStart() @@ -435,9 +454,12 @@ final class CreateTableImpl extends AbstractQuery implements if (identity == null && type.identity()) identity = columnFields.get(i); - ctx.visit(columnFields.get(i)) - .sql(' '); - Tools.toSQLDDLTypeDeclarationForAddition(ctx, type); + ctx.visit(columnFields.get(i)); + + if (select == null) { + ctx.sql(' '); + Tools.toSQLDDLTypeDeclarationForAddition(ctx, type); + } if (i < columnFields.size() - 1) ctx.sql(',').formatSeparator(); @@ -499,20 +521,7 @@ final class CreateTableImpl extends AbstractQuery implements ctx.formatIndentEnd() .formatNewLine() .sql(')'); - - toSQLOnCommit(ctx); } - - if (comment != null && !EMULATE_COMMENT_IN_BLOCK.contains(ctx.family())) - ctx.formatSeparator() - .visit(K_COMMENT).sql(' ').visit(comment); - - // [#7772] This data() value should be available from ctx directly, not only from ctx.configuration() - if (storage != null && ctx.configuration().data("org.jooq.meta.extensions.ddl.ignore-storage-clauses") == null) - ctx.formatSeparator() - .visit(storage); - - ctx.end(CREATE_TABLE); } private final boolean matchingPrimaryKey(Constraint constraint, Field identity) { @@ -523,7 +532,7 @@ final class CreateTableImpl extends AbstractQuery implements } private final void acceptCreateTableAsSelect(Context ctx) { - toSQLCreateTableName(ctx); + toSQLCreateTable(ctx); toSQLOnCommit(ctx); ctx.formatSeparator() .visit(K_AS); diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java index 241dccde00..3699a8f929 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DSL.java +++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java @@ -170,7 +170,7 @@ import org.jooq.ConstraintTypeStep; import org.jooq.CreateIndexStep; import org.jooq.CreateSchemaFinalStep; import org.jooq.CreateSequenceFlagsStep; -import org.jooq.CreateTableAsStep; +import org.jooq.CreateTableColumnStep; import org.jooq.CreateTypeStep; import org.jooq.CreateViewAsStep; import org.jooq.DSLContext; @@ -6617,7 +6617,7 @@ public class DSL { * @see DSLContext#createTable(String) */ @Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE }) - public static CreateTableAsStep createTable(String table) { + public static CreateTableColumnStep createTable(String table) { return dsl().createTable(table); } @@ -6627,7 +6627,7 @@ public class DSL { * @see DSLContext#createTable(Name) */ @Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE }) - public static CreateTableAsStep createTable(Name table) { + public static CreateTableColumnStep createTable(Name table) { return dsl().createTable(table); } @@ -6637,7 +6637,7 @@ public class DSL { * @see DSLContext#createTable(Table) */ @Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE }) - public static CreateTableAsStep createTable(Table table) { + public static CreateTableColumnStep createTable(Table table) { return dsl().createTable(table); } @@ -6647,7 +6647,7 @@ public class DSL { * @see DSLContext#createTableIfNotExists(String) */ @Support({ FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE }) - public static CreateTableAsStep createTableIfNotExists(String table) { + public static CreateTableColumnStep createTableIfNotExists(String table) { return dsl().createTableIfNotExists(table); } @@ -6657,7 +6657,7 @@ public class DSL { * @see DSLContext#createTableIfNotExists(Name) */ @Support({ FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE }) - public static CreateTableAsStep createTableIfNotExists(Name table) { + public static CreateTableColumnStep createTableIfNotExists(Name table) { return dsl().createTableIfNotExists(table); } @@ -6667,7 +6667,7 @@ public class DSL { * @see DSLContext#createTableIfNotExists(Table) */ @Support({ FIREBIRD, H2, HSQLDB, MARIADB, MYSQL, POSTGRES, SQLITE }) - public static CreateTableAsStep createTableIfNotExists(Table table) { + public static CreateTableColumnStep createTableIfNotExists(Table table) { return dsl().createTableIfNotExists(table); } @@ -6677,7 +6677,7 @@ public class DSL { * @see DSLContext#createTemporaryTable(String) */ @Support({ MARIADB, MYSQL, POSTGRES }) - public static CreateTableAsStep createTemporaryTable(String table) { + public static CreateTableColumnStep createTemporaryTable(String table) { return dsl().createTemporaryTable(table); } @@ -6687,7 +6687,7 @@ public class DSL { * @see DSLContext#createTemporaryTable(Name) */ @Support({ MARIADB, MYSQL, POSTGRES }) - public static CreateTableAsStep createTemporaryTable(Name table) { + public static CreateTableColumnStep createTemporaryTable(Name table) { return dsl().createTemporaryTable(table); } @@ -6697,7 +6697,7 @@ public class DSL { * @see DSLContext#createTemporaryTable(Table) */ @Support({ MARIADB, MYSQL, POSTGRES }) - public static CreateTableAsStep createTemporaryTable(Table table) { + public static CreateTableColumnStep createTemporaryTable(Table table) { return dsl().createTemporaryTable(table); } @@ -6707,7 +6707,7 @@ public class DSL { * @see DSLContext#createGlobalTemporaryTable(String) */ @Support({ MARIADB, MYSQL, POSTGRES }) - public static CreateTableAsStep createGlobalTemporaryTable(String table) { + public static CreateTableColumnStep createGlobalTemporaryTable(String table) { return dsl().createGlobalTemporaryTable(table); } @@ -6717,7 +6717,7 @@ public class DSL { * @see DSLContext#createGlobalTemporaryTable(Name) */ @Support({ MARIADB, MYSQL, POSTGRES }) - public static CreateTableAsStep createGlobalTemporaryTable(Name table) { + public static CreateTableColumnStep createGlobalTemporaryTable(Name table) { return dsl().createGlobalTemporaryTable(table); } @@ -6727,7 +6727,7 @@ public class DSL { * @see DSLContext#createGlobalTemporaryTable(Table) */ @Support({ MARIADB, MYSQL, POSTGRES }) - public static CreateTableAsStep createGlobalTemporaryTable(Table table) { + public static CreateTableColumnStep createGlobalTemporaryTable(Table table) { return dsl().createGlobalTemporaryTable(table); } diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java index 997e6b4165..9ce7abe888 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java @@ -113,7 +113,7 @@ import org.jooq.ContextTransactionalRunnable; import org.jooq.CreateIndexStep; import org.jooq.CreateSchemaFinalStep; import org.jooq.CreateSequenceFlagsStep; -import org.jooq.CreateTableAsStep; +import org.jooq.CreateTableColumnStep; import org.jooq.CreateTypeStep; import org.jooq.CreateViewAsStep; import org.jooq.Cursor; @@ -3013,63 +3013,63 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri } @Override - public CreateTableAsStep createTable(String table) { + public CreateTableColumnStep createTable(String table) { return createTable(name(table)); } @Override - public CreateTableAsStep createTable(Name table) { + public CreateTableColumnStep createTable(Name table) { return createTable(table(table)); } @Override - public CreateTableAsStep createTable(Table table) { - return new CreateTableImpl(configuration(), table, false, false); + public CreateTableColumnStep createTable(Table table) { + return new CreateTableImpl(configuration(), table, false, false); } @Override - public CreateTableAsStep createTableIfNotExists(String table) { + public CreateTableColumnStep createTableIfNotExists(String table) { return createTableIfNotExists(name(table)); } @Override - public CreateTableAsStep createTableIfNotExists(Name table) { + public CreateTableColumnStep createTableIfNotExists(Name table) { return createTableIfNotExists(table(table)); } @Override - public CreateTableAsStep createTableIfNotExists(Table table) { - return new CreateTableImpl(configuration(), table, false, true); + public CreateTableColumnStep createTableIfNotExists(Table table) { + return new CreateTableImpl(configuration(), table, false, true); } @Override - public CreateTableAsStep createTemporaryTable(String table) { + public CreateTableColumnStep createTemporaryTable(String table) { return createTemporaryTable(name(table)); } @Override - public CreateTableAsStep createTemporaryTable(Name table) { + public CreateTableColumnStep createTemporaryTable(Name table) { return createTemporaryTable(table(table)); } @Override - public CreateTableAsStep createTemporaryTable(Table table) { - return new CreateTableImpl(configuration(), table, true, false); + public CreateTableColumnStep createTemporaryTable(Table table) { + return new CreateTableImpl(configuration(), table, true, false); } @Override - public CreateTableAsStep createGlobalTemporaryTable(String table) { + public CreateTableColumnStep createGlobalTemporaryTable(String table) { return createGlobalTemporaryTable(name(table)); } @Override - public CreateTableAsStep createGlobalTemporaryTable(Name table) { + public CreateTableColumnStep createGlobalTemporaryTable(Name table) { return createGlobalTemporaryTable(table(table)); } @Override - public CreateTableAsStep createGlobalTemporaryTable(Table table) { - return new CreateTableImpl(configuration(), table, true, false); + public CreateTableColumnStep createGlobalTemporaryTable(Table table) { + return new CreateTableImpl(configuration(), table, true, false); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index 7c9949de0d..a4ddc5c448 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -37,6 +37,8 @@ */ package org.jooq.impl; +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; // ... @@ -336,11 +338,10 @@ import org.jooq.CreateIndexIncludeStep; import org.jooq.CreateIndexStep; import org.jooq.CreateIndexWhereStep; import org.jooq.CreateSequenceFlagsStep; -import org.jooq.CreateTableAsStep; import org.jooq.CreateTableColumnStep; import org.jooq.CreateTableCommentStep; import org.jooq.CreateTableConstraintStep; -import org.jooq.CreateTableIndexStep; +import org.jooq.CreateTableOnCommitStep; import org.jooq.CreateTableStorageStep; import org.jooq.CreateTableWithDataStep; import org.jooq.DDLQuery; @@ -2804,32 +2805,18 @@ final class ParserImpl implements Parser { CreateTableCommentStep commentStep; CreateTableStorageStep storageStep; - // [#5309] TODO: Move this after the column specification - if (parseKeywordIf(ctx, "AS")) { - Select select = (Select) parseQuery(ctx, true, true); + List> fields = new ArrayList>(); + List constraints = new ArrayList(); + List indexes = new ArrayList(); + boolean primary = false; - CreateTableAsStep s1 = ifNotExists - ? ctx.dsl.createTableIfNotExists(tableName) - : temporary - ? ctx.dsl.createTemporaryTable(tableName) - : ctx.dsl.createTable(tableName); + // Three valued boolean: + // null: Possibly CTAS + // true: Definitely CTAS + // false: Definitely not CTAS + Boolean ctas = null; - CreateTableWithDataStep s2 = s1.as(select); - - storageStep = commentStep = - parseKeywordIf(ctx, "WITH DATA") - ? s2.withData() - : parseKeywordIf(ctx, "WITH NO DATA") - ? s2.withNoData() - : s2; - } - else { - List> fields = new ArrayList>(); - List constraints = new ArrayList(); - List indexes = new ArrayList(); - boolean primary = false; - - parse(ctx, '('); + if (parseIf(ctx, '(')) { columnLoop: do { @@ -2885,7 +2872,17 @@ final class ParserImpl implements Parser { throw ctx.expected("CHECK", "CONSTRAINT", "FOREIGN KEY", "INDEX", "KEY", "PRIMARY KEY", "UNIQUE"); Name fieldName = parseIdentifier(ctx); - DataType type = parseDataType(ctx); + DataType type = null; + + if (ctas == null && (peek(ctx, ',') || peek(ctx, ')'))) + ctas = true; + else + ctas = false; + + type = !TRUE.equals(ctas) + ? parseDataType(ctx) + : SQLDataType.OTHER; + Comment fieldComment = null; boolean nullable = false; @@ -3048,7 +3045,10 @@ final class ParserImpl implements Parser { break; } - fields.add(field(fieldName, type, fieldComment)); + if (ctas) + fields.add(field(fieldName)); + else + fields.add(field(fieldName, type, fieldComment)); } while (parseIf(ctx, ',')); @@ -3056,35 +3056,54 @@ final class ParserImpl implements Parser { throw ctx.expected("At least one column"); parse(ctx, ')'); + } + else + ctas = true; - CreateTableAsStep s1 = ifNotExists - ? ctx.dsl.createTableIfNotExists(tableName) - : temporary - ? ctx.dsl.createTemporaryTable(tableName) - : ctx.dsl.createTable(tableName); - CreateTableColumnStep s2 = s1.columns(fields); - CreateTableConstraintStep s3 = constraints.isEmpty() - ? s2 - : s2.constraints(constraints); - CreateTableIndexStep s4 = indexes.isEmpty() - ? s3 - : s3.indexes(indexes); - CreateTableCommentStep s5 = s4; + CreateTableColumnStep columnStep = ifNotExists + ? ctx.dsl.createTableIfNotExists(tableName) + : temporary + ? ctx.dsl.createTemporaryTable(tableName) + : ctx.dsl.createTable(tableName); + if (!fields.isEmpty()) + columnStep = columnStep.columns(fields); + + if (TRUE.equals(ctas) && parseKeyword(ctx, "AS") || + !FALSE.equals(ctas) && parseKeywordIf(ctx, "AS")) { + CreateTableWithDataStep withDataStep = columnStep.as((Select) parseQuery(ctx, true, true)); + commentStep = + parseKeywordIf(ctx, "WITH DATA") + ? withDataStep.withData() + : parseKeywordIf(ctx, "WITH NO DATA") + ? withDataStep.withNoData() + : withDataStep; + } + else { + CreateTableConstraintStep constraintStep = constraints.isEmpty() + ? columnStep + : columnStep.constraints(constraints); + CreateTableOnCommitStep onCommitStep = indexes.isEmpty() + ? constraintStep + : constraintStep.indexes(indexes); + + // [#6133] TODO Support this also with CTAS if (temporary && parseKeywordIf(ctx, "ON COMMIT")) { if (parseKeywordIf(ctx, "DELETE ROWS")) - s5 = s4.onCommitDeleteRows(); + commentStep = onCommitStep.onCommitDeleteRows(); else if (parseKeywordIf(ctx, "DROP")) - s5 = s4.onCommitDrop(); + commentStep = onCommitStep.onCommitDrop(); else if (parseKeywordIf(ctx, "PRESERVE ROWS")) - s5 = s4.onCommitPreserveRows(); + commentStep = onCommitStep.onCommitPreserveRows(); else throw ctx.unsupportedClause(); } - - storageStep = commentStep = s5; + else + commentStep = onCommitStep; } + storageStep = commentStep; + List storage = new ArrayList(); Comment comment = null; @@ -4604,10 +4623,6 @@ final class ParserImpl implements Parser { - - - - if (field == null) { field = parseField(ctx);