diff --git a/jOOQ/src/main/java/org/jooq/impl/AlterTableImpl.java b/jOOQ/src/main/java/org/jooq/impl/AlterTableImpl.java index dfedf7d874..3b0e9c7d17 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AlterTableImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/AlterTableImpl.java @@ -1327,7 +1327,7 @@ implements if (part instanceof Field f) { ctx.sql(' '); - toSQLDDLTypeDeclarationForAddition(ctx, f.getDataType()); + toSQLDDLTypeDeclarationForAddition(ctx, table, f.getDataType()); CreateTableImpl.acceptColumnComment(ctx, f); } } @@ -1355,7 +1355,7 @@ implements ctx.qualify(false, c -> c.visit(Tools.uncollate(addColumn))).sql(' '); - toSQLDDLTypeDeclarationForAddition(ctx, addColumnType); + toSQLDDLTypeDeclarationForAddition(ctx, table, addColumnType); CreateTableImpl.acceptColumnComment(ctx, addColumn); @@ -1502,7 +1502,7 @@ implements ctx.sql(' '); toSQLDDLTypeDeclaration(ctx, alterColumnType); - toSQLDDLTypeDeclarationIdentityBeforeNull(ctx, alterColumnType); + toSQLDDLTypeDeclarationIdentityBeforeNull(ctx, table, alterColumnType); // [#3805] Some databases cannot change the type and the NOT NULL constraint in a single statement if (!NO_SUPPORT_ALTER_TYPE_AND_NULL.contains(ctx.dialect())) { @@ -1518,7 +1518,7 @@ implements } } - toSQLDDLTypeDeclarationIdentityAfterNull(ctx, alterColumnType); + toSQLDDLTypeDeclarationIdentityAfterNull(ctx, table, alterColumnType); } else if (alterColumnDefault != null) { ctx.start(ALTER_TABLE_ALTER_DEFAULT); diff --git a/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java b/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java index 9b05036007..08eb39cda4 100644 --- a/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java @@ -356,6 +356,7 @@ implements static final Set REQUIRE_EXECUTE_IMMEDIATE = SQLDialect.supportedBy(FIREBIRD); static final Set NO_SUPPORT_NULLABLE_PRIMARY_KEY = SQLDialect.supportedBy(CLICKHOUSE, MARIADB, MYSQL); static final Set REQUIRE_NON_PK_COLUMNS = SQLDialect.supportedBy(IGNITE); + static final Set CREATE_SEQUENCE_FOR_IDENTITY = SQLDialect.supportedBy(DUCKDB); @@ -441,6 +442,11 @@ implements private final void accept1(Context ctx) { ctx.start(Clause.CREATE_TABLE); + if (CREATE_SEQUENCE_FOR_IDENTITY.contains(ctx.family()) + && anyMatch(tableElements, e -> e instanceof Field && ((Field) e).getDataType().identity()) + ) + prependSQL(ctx, createSequenceIfNotExists(identitySequence(table))); + if (select != null) { @@ -522,7 +528,7 @@ implements if (select == null) { ctx.sql(' '); - Tools.toSQLDDLTypeDeclarationForAddition(ctx, type); + Tools.toSQLDDLTypeDeclarationForAddition(ctx, table, type); acceptColumnComment(ctx, field); } @@ -610,7 +616,7 @@ implements if (select == null) { ctx.sql(' '); - Tools.toSQLDDLTypeDeclarationForAddition(ctx, INTEGER); + Tools.toSQLDDLTypeDeclarationForAddition(ctx, table, INTEGER); } } } diff --git a/jOOQ/src/main/java/org/jooq/impl/CreateTypeImpl.java b/jOOQ/src/main/java/org/jooq/impl/CreateTypeImpl.java index 3b5c126045..fc8249b487 100644 --- a/jOOQ/src/main/java/org/jooq/impl/CreateTypeImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/CreateTypeImpl.java @@ -211,7 +211,7 @@ implements return CustomField.of(f.getUnqualifiedName(), f.getDataType(), c -> { c.visit(f.getUnqualifiedName()); c.sql(' '); - Tools.toSQLDDLTypeDeclarationForAddition(c, f.getDataType()); + Tools.toSQLDDLTypeDeclarationForAddition(c, null, f.getDataType()); }); } diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index 8112a10db9..b8dc17ff20 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -334,6 +334,7 @@ import org.jooq.Schema; import org.jooq.Scope; import org.jooq.Select; import org.jooq.SelectFieldOrAsterisk; +import org.jooq.Sequence; import org.jooq.SortField; import org.jooq.Source; import org.jooq.Table; @@ -5763,7 +5764,7 @@ final class Tools { }); } - static final void toSQLDDLTypeDeclarationForAddition(Context ctx, DataType type) { + static final void toSQLDDLTypeDeclarationForAddition(Context ctx, Table table, DataType type) { boolean qualify = ctx.qualify(); toSQLDDLTypeDeclaration(ctx, type); @@ -5771,7 +5772,7 @@ final class Tools { // have qualified field references elsewhere, e.g. in computed // column declarations. ctx.qualify(false); - toSQLDDLTypeDeclarationIdentityBeforeNull(ctx, type); + toSQLDDLTypeDeclarationIdentityBeforeNull(ctx, table, type); @@ -5792,7 +5793,7 @@ final class Tools { if (!DEFAULT_BEFORE_NULL.contains(ctx.dialect())) toSQLDDLTypeDeclarationDefault(ctx, type); - toSQLDDLTypeDeclarationIdentityAfterNull(ctx, type); + toSQLDDLTypeDeclarationIdentityAfterNull(ctx, table, type); @@ -5858,14 +5859,28 @@ final class Tools { } } - private static final Set REQUIRE_IDENTITY_AFTER_NULL = SQLDialect.supportedBy(H2, MARIADB, MYSQL); + static final Sequence identitySequence(Table table) { + if (table == null) + return DSL.sequence("id"); + + Name n = table.getQualifiedName(); + + if (n.qualified()) + n = n.qualifier().append(n.last() + "_seq"); + else + n = name(n.last() + "_seq"); + + return DSL.sequence(n); + } + + private static final Set REQUIRE_IDENTITY_AFTER_NULL = SQLDialect.supportedBy(DUCKDB, H2, MARIADB, MYSQL); private static final Set SUPPORT_PG_IDENTITY = SQLDialect.supportedBy(POSTGRES); /** * If a type is an identity type, some dialects require the relevant * keywords before the [ NOT ] NULL constraint. */ - static final void toSQLDDLTypeDeclarationIdentityBeforeNull(Context ctx, DataType type) { + static final void toSQLDDLTypeDeclarationIdentityBeforeNull(Context ctx, Table table, DataType type) { if (REQUIRE_IDENTITY_AFTER_NULL.contains(ctx.dialect())) return; @@ -5902,7 +5917,7 @@ final class Tools { * If a type is an identity type, some dialects require the relevant * keywords after the [ NOT ] NULL constraint. */ - static final void toSQLDDLTypeDeclarationIdentityAfterNull(Context ctx, DataType type) { + static final void toSQLDDLTypeDeclarationIdentityAfterNull(Context ctx, Table table, DataType type) { if (!REQUIRE_IDENTITY_AFTER_NULL.contains(ctx.dialect())) return; @@ -5922,6 +5937,7 @@ final class Tools { case MARIADB: case MYSQL: ctx.sql(' ').visit(K_AUTO_INCREMENT); break; + case DUCKDB: ctx.sql(' ').visit(K_DEFAULT).sql(' ').visit(identitySequence(table).nextval()); break; } } }