From 693f60f2934df611f116a659d5a8a1b22ebaf71e Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Wed, 18 Jan 2023 11:13:16 +0100 Subject: [PATCH] [jOOQ/jOOQ#14513] Implement emulation on non MySQL category dialects --- .../java/org/jooq/impl/AlterTableImpl.java | 50 ++++++++++++++++--- .../java/org/jooq/impl/CreateTableImpl.java | 10 ---- jOOQ/src/main/java/org/jooq/impl/Tools.java | 20 ++++++++ 3 files changed, 62 insertions(+), 18 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/AlterTableImpl.java b/jOOQ/src/main/java/org/jooq/impl/AlterTableImpl.java index ef3cfff904..720d42656f 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AlterTableImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/AlterTableImpl.java @@ -39,6 +39,8 @@ package org.jooq.impl; import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; import static org.jooq.Clause.ALTER_TABLE; import static org.jooq.Clause.ALTER_TABLE_ADD; import static org.jooq.Clause.ALTER_TABLE_ALTER; @@ -77,12 +79,11 @@ import static org.jooq.SQLDialect.POSTGRES; // ... // ... import static org.jooq.SQLDialect.YUGABYTEDB; -import static org.jooq.impl.QOM.Cascade.CASCADE; -import static org.jooq.impl.QOM.Cascade.RESTRICT; import static org.jooq.impl.ConstraintType.FOREIGN_KEY; import static org.jooq.impl.ConstraintType.PRIMARY_KEY; import static org.jooq.impl.ConstraintType.UNIQUE; import static org.jooq.impl.DSL.begin; +import static org.jooq.impl.DSL.commentOnColumn; import static org.jooq.impl.DSL.commentOnTable; import static org.jooq.impl.DSL.condition; import static org.jooq.impl.DSL.constraint; @@ -106,7 +107,6 @@ 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; @@ -140,7 +140,6 @@ import static org.jooq.impl.Keywords.K_RENAME_OBJECT; import static org.jooq.impl.Keywords.K_RENAME_TABLE; import static org.jooq.impl.Keywords.K_RENAME_TO; import static org.jooq.impl.Keywords.K_REPLACE; -import static org.jooq.impl.Keywords.K_RESTRICT; import static org.jooq.impl.Keywords.K_SET_DATA_TYPE; import static org.jooq.impl.Keywords.K_SET_DEFAULT; import static org.jooq.impl.Keywords.K_SET_NOT_NULL; @@ -150,12 +149,17 @@ import static org.jooq.impl.Keywords.K_TYPE; import static org.jooq.impl.Keywords.K_USING_INDEX; import static org.jooq.impl.Keywords.K_WHEN; import static org.jooq.impl.Keywords.K_WITH_NO_DATACOPY; +import static org.jooq.impl.QOM.Cascade.CASCADE; +import static org.jooq.impl.QOM.Cascade.RESTRICT; import static org.jooq.impl.SQLDataType.VARCHAR; import static org.jooq.impl.Tools.begin; import static org.jooq.impl.Tools.beginExecuteImmediate; import static org.jooq.impl.Tools.endExecuteImmediate; import static org.jooq.impl.Tools.executeImmediate; +import static org.jooq.impl.Tools.executeImmediateIf; import static org.jooq.impl.Tools.fieldsByName; +import static org.jooq.impl.Tools.filter; +import static org.jooq.impl.Tools.map; import static org.jooq.impl.Tools.toSQLDDLTypeDeclaration; import static org.jooq.impl.Tools.toSQLDDLTypeDeclarationForAddition; import static org.jooq.impl.Tools.toSQLDDLTypeDeclarationIdentityAfterNull; @@ -187,14 +191,12 @@ import org.jooq.Context; import org.jooq.DSLContext; import org.jooq.DataType; import org.jooq.Field; -import org.jooq.FieldOrConstraint; import org.jooq.Index; import org.jooq.Keyword; import org.jooq.Name; import org.jooq.Nullability; // ... import org.jooq.Query; -import org.jooq.QueryPart; import org.jooq.Record1; import org.jooq.SQLDialect; import org.jooq.Select; @@ -247,8 +249,6 @@ implements - - private final Table table; private final boolean ifExists; private boolean ifExistsColumn; @@ -1129,10 +1129,44 @@ implements + + if (CreateTableImpl.EMULATE_COLUMN_COMMENT_IN_BLOCK.contains(ctx.dialect())) { + List> comments = addColumnComments(); + + if (!comments.isEmpty()) { + begin(ctx, c1 -> { + executeImmediateIf( + CreateTableImpl.REQUIRE_EXECUTE_IMMEDIATE.contains(c1.dialect()), + c1, + c2 -> accept1(c2) + ); + + c1.formatSeparator(); + + for (Field c : comments) { + executeImmediateIf(CreateTableImpl.REQUIRE_EXECUTE_IMMEDIATE.contains(ctx.dialect()), c1, + c2 -> c2.visit(commentOnColumn(table.getQualifiedName().append(c.getUnqualifiedName())).is(c.getComment())) + ); + } + }); + return; + } + } accept1(ctx); } + private final List> addColumnComments() { + if (addColumn != null) { + if (!addColumn.getComment().isEmpty()) + return asList(addColumn); + } + else if (add != null) + return map(filter(add, c -> c instanceof Field && !c.getComment().isEmpty()), c -> (Field) c); + + return emptyList(); + } + private final void accept1(Context ctx) { SQLDialect family = ctx.family(); diff --git a/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java b/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java index 3726759e93..58c2d87706 100644 --- a/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/CreateTableImpl.java @@ -391,16 +391,6 @@ implements accept0(ctx); } - private static final void executeImmediateIf(boolean wrap, Context ctx, Consumer> runnable) { - if (wrap) { - executeImmediate(ctx, runnable); - } - else { - runnable.accept(ctx); - ctx.sql(';'); - } - } - private final void accept0(Context ctx) { boolean btc = comment != null && EMULATE_TABLE_COMMENT_IN_BLOCK.contains(ctx.dialect()); boolean bcc = EMULATE_COLUMN_COMMENT_IN_BLOCK.contains(ctx.dialect()) && anyMatch($columns(), c -> !c.getComment().isEmpty()); diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index 787ff901c9..d32293788d 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -193,6 +193,7 @@ import static org.jooq.impl.SQLDataType.XML; import static org.jooq.impl.SubqueryCharacteristics.DERIVED_TABLE; import static org.jooq.impl.SubqueryCharacteristics.PREDICAND; import static org.jooq.impl.SubqueryCharacteristics.SET_OPERATION; +import static org.jooq.impl.Tools.executeImmediate; import static org.jooq.impl.Tools.SimpleDataKey.DATA_BLOCK_NESTING; import static org.jooq.tools.StringUtils.defaultIfNull; @@ -938,6 +939,12 @@ final class Tools { */ DATA_WINDOW_FUNCTION, + /** + * [#14510] [#14513] Whether inline column comments should be rendered + * in DDL statements. + */ + DATA_INLINE_COLUMN_COMMENT, + ; private final boolean resetInSubqueryScope; @@ -5023,6 +5030,19 @@ final class Tools { } } + /** + * Wrap a statement in an EXECUTE IMMEDIATE statement. + */ + static final void executeImmediateIf(boolean wrap, Context ctx, Consumer> runnable) { + if (wrap) { + executeImmediate(ctx, runnable); + } + else { + runnable.accept(ctx); + ctx.sql(';'); + } + } + /** * Wrap a statement in an EXECUTE IMMEDIATE statement. */