[#6316] ALTER TABLE .. ADD COLUMN ignores column type's DEFAULT clause

This commit is contained in:
lukaseder 2017-06-05 14:27:14 +02:00
parent 43ff705bbd
commit ef55ac7436
3 changed files with 49 additions and 55 deletions

View File

@ -76,7 +76,6 @@ import static org.jooq.impl.Keywords.K_EXEC;
import static org.jooq.impl.Keywords.K_IF_EXISTS;
import static org.jooq.impl.Keywords.K_MODIFY;
import static org.jooq.impl.Keywords.K_NOT_NULL;
import static org.jooq.impl.Keywords.K_NULL;
import static org.jooq.impl.Keywords.K_RENAME_COLUMN;
import static org.jooq.impl.Keywords.K_RENAME_CONSTRAINT;
import static org.jooq.impl.Keywords.K_RENAME_INDEX;
@ -88,6 +87,7 @@ import static org.jooq.impl.Keywords.K_TO;
import static org.jooq.impl.Keywords.K_TYPE;
import static org.jooq.impl.Keywords.K_USING_INDEX;
import static org.jooq.impl.Tools.toSQLDDLTypeDeclaration;
import static org.jooq.impl.Tools.toSQLDDLTypeDeclarationForAddition;
import static org.jooq.impl.Tools.DataKey.DATA_CONSTRAINT_REFERENCE;
import org.jooq.AlterTableAlterStep;
@ -619,15 +619,7 @@ final class AlterTableImpl extends AbstractQuery implements
.visit(addColumn).sql(' ')
.qualify(qualify);
toSQLDDLTypeDeclaration(ctx, addColumnType);
if (!addColumnType.nullable())
ctx.sql(' ').visit(K_NOT_NULL);
// Some databases default to NOT NULL, so explicitly setting columns to NULL is mostly required here
// [#3400] [#4321] ... but not in Derby, Firebird
else if (!asList(DERBY, FIREBIRD).contains(family))
ctx.sql(' ').visit(K_NULL);
toSQLDDLTypeDeclarationForAddition(ctx, addColumnType);

View File

@ -57,18 +57,12 @@ import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.insertInto;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.Keywords.K_AS;
import static org.jooq.impl.Keywords.K_AUTO_INCREMENT;
import static org.jooq.impl.Keywords.K_BEGIN;
import static org.jooq.impl.Keywords.K_CREATE;
import static org.jooq.impl.Keywords.K_DEFAULT;
import static org.jooq.impl.Keywords.K_END;
import static org.jooq.impl.Keywords.K_EXECUTE_IMMEDIATE;
import static org.jooq.impl.Keywords.K_GENERATED_BY_DEFAULT_AS_IDENTITY;
import static org.jooq.impl.Keywords.K_GLOBAL_TEMPORARY;
import static org.jooq.impl.Keywords.K_IDENTITY;
import static org.jooq.impl.Keywords.K_IF_NOT_EXISTS;
import static org.jooq.impl.Keywords.K_NOT_NULL;
import static org.jooq.impl.Keywords.K_NULL;
import static org.jooq.impl.Keywords.K_ON_COMMIT_DELETE_ROWS;
import static org.jooq.impl.Keywords.K_ON_COMMIT_DROP;
import static org.jooq.impl.Keywords.K_ON_COMMIT_PRESERVE_ROWS;
@ -269,40 +263,7 @@ final class CreateTableImpl<R extends Record> extends AbstractQuery implements
ctx.visit(columnFields.get(i))
.sql(' ');
Tools.toSQLDDLTypeDeclaration(ctx, type);
// [#5356] Some dialects require the DEFAULT clause prior to the
// NULL constraints clause
if (asList(HSQLDB).contains(ctx.family()))
acceptDefault(ctx, type);
if (type.nullable()) {
// [#4321] Not all dialects support explicit NULL type declarations
if (!asList(DERBY, FIREBIRD).contains(ctx.family()))
ctx.sql(' ').visit(K_NULL);
}
else {
ctx.sql(' ').visit(K_NOT_NULL);
}
if (type.identity()) {
// [#5062] H2's (and others') AUTO_INCREMENT flag is syntactically located *after* NULL flags.
switch (ctx.family()) {
case H2:
case MARIADB:
case MYSQL: ctx.sql(' ').visit(K_AUTO_INCREMENT); break;
}
}
if (!asList(HSQLDB).contains(ctx.family()))
acceptDefault(ctx, type);
Tools.toSQLDDLTypeDeclarationForAddition(ctx, type);
if (i < columnFields.size() - 1)
ctx.sql(',').formatSeparator();
@ -328,11 +289,6 @@ final class CreateTableImpl<R extends Record> extends AbstractQuery implements
}
}
private final void acceptDefault(Context<?> ctx, DataType<?> type) {
if (type.defaulted())
ctx.sql(' ').visit(K_DEFAULT).sql(' ').visit(type.defaultValue());
}
private final void acceptCreateTableAsSelect(Context<?> ctx) {
ctx.start(CREATE_TABLE);
toSQLCreateTableName(ctx);

View File

@ -40,6 +40,9 @@ import static java.util.Arrays.asList;
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
import static org.jooq.SQLDialect.DERBY;
import static org.jooq.SQLDialect.FIREBIRD;
import static org.jooq.SQLDialect.HSQLDB;
import static org.jooq.SQLDialect.MARIADB;
import static org.jooq.SQLDialect.MYSQL;
// ...
@ -84,6 +87,7 @@ import static org.jooq.impl.Keywords.K_BEGIN;
import static org.jooq.impl.Keywords.K_BEGIN_CATCH;
import static org.jooq.impl.Keywords.K_BEGIN_TRY;
import static org.jooq.impl.Keywords.K_DECLARE;
import static org.jooq.impl.Keywords.K_DEFAULT;
import static org.jooq.impl.Keywords.K_DO;
import static org.jooq.impl.Keywords.K_ELSE;
import static org.jooq.impl.Keywords.K_END;
@ -105,6 +109,7 @@ import static org.jooq.impl.Keywords.K_IN;
import static org.jooq.impl.Keywords.K_INT;
import static org.jooq.impl.Keywords.K_LIKE;
import static org.jooq.impl.Keywords.K_LOOP;
import static org.jooq.impl.Keywords.K_NOT_NULL;
import static org.jooq.impl.Keywords.K_NULL;
import static org.jooq.impl.Keywords.K_NVARCHAR;
import static org.jooq.impl.Keywords.K_RAISE;
@ -3529,6 +3534,47 @@ final class Tools {
}
}
static final void toSQLDDLTypeDeclarationForAddition(Context<?> ctx, DataType<?> type) {
toSQLDDLTypeDeclaration(ctx, type);
// [#5356] Some dialects require the DEFAULT clause prior to the
// NULL constraints clause
if (asList(HSQLDB).contains(ctx.family()))
toSQLDDLTypeDeclarationDefault(ctx, type);
if (!type.nullable())
ctx.sql(' ').visit(K_NOT_NULL);
// Some databases default to NOT NULL, so explicitly setting columns to NULL is mostly required here
// [#3400] [#4321] ... but not in Derby, Firebird
else if (!asList(DERBY, FIREBIRD).contains(ctx.family()))
ctx.sql(' ').visit(K_NULL);
if (type.identity()) {
// [#5062] H2's (and others') AUTO_INCREMENT flag is syntactically located *after* NULL flags.
switch (ctx.family()) {
case H2:
case MARIADB:
case MYSQL: ctx.sql(' ').visit(K_AUTO_INCREMENT); break;
}
}
if (!asList(HSQLDB).contains(ctx.family()))
toSQLDDLTypeDeclarationDefault(ctx, type);
}
private static final void toSQLDDLTypeDeclarationDefault(Context<?> ctx, DataType<?> type) {
if (type.defaulted())
ctx.sql(' ').visit(K_DEFAULT).sql(' ').visit(type.defaultValue());
}
static final void toSQLDDLTypeDeclaration(Context<?> ctx, DataType<?> type) {
String typeName = type.getTypeName(ctx.configuration());