[#3805] Emulation of repeatable nullability changes for Oracle
This commit is contained in:
parent
fe9cdba3d1
commit
0ec191b973
@ -67,20 +67,24 @@ import static org.jooq.impl.Keywords.K_ALTER;
|
||||
import static org.jooq.impl.Keywords.K_ALTER_COLUMN;
|
||||
import static org.jooq.impl.Keywords.K_ALTER_CONSTRAINT;
|
||||
import static org.jooq.impl.Keywords.K_ALTER_TABLE;
|
||||
import static org.jooq.impl.Keywords.K_BEGIN;
|
||||
import static org.jooq.impl.Keywords.K_CASCADE;
|
||||
import static org.jooq.impl.Keywords.K_CHANGE_COLUMN;
|
||||
import static org.jooq.impl.Keywords.K_DEFAULT;
|
||||
import static org.jooq.impl.Keywords.K_DO;
|
||||
import static org.jooq.impl.Keywords.K_DROP;
|
||||
import static org.jooq.impl.Keywords.K_DROP_COLUMN;
|
||||
import static org.jooq.impl.Keywords.K_DROP_CONSTRAINT;
|
||||
import static org.jooq.impl.Keywords.K_END;
|
||||
import static org.jooq.impl.Keywords.K_ELSE;
|
||||
import static org.jooq.impl.Keywords.K_END_IF;
|
||||
import static org.jooq.impl.Keywords.K_EXCEPTION;
|
||||
import static org.jooq.impl.Keywords.K_EXEC;
|
||||
import static org.jooq.impl.Keywords.K_EXECUTE_IMMEDIATE;
|
||||
import static org.jooq.impl.Keywords.K_IF;
|
||||
import static org.jooq.impl.Keywords.K_IF_EXISTS;
|
||||
import static org.jooq.impl.Keywords.K_LIKE;
|
||||
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_RAISE;
|
||||
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;
|
||||
@ -89,9 +93,13 @@ import static org.jooq.impl.Keywords.K_RENAME_TO;
|
||||
import static org.jooq.impl.Keywords.K_SET;
|
||||
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_THEN;
|
||||
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.Keywords.K_WHEN;
|
||||
import static org.jooq.impl.Tools.begin;
|
||||
import static org.jooq.impl.Tools.end;
|
||||
import static org.jooq.impl.Tools.toSQLDDLTypeDeclaration;
|
||||
import static org.jooq.impl.Tools.toSQLDDLTypeDeclarationForAddition;
|
||||
import static org.jooq.impl.Tools.DataKey.DATA_CONSTRAINT_REFERENCE;
|
||||
@ -114,6 +122,7 @@ import org.jooq.Field;
|
||||
import org.jooq.Index;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Nullability;
|
||||
import org.jooq.Query;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.Table;
|
||||
|
||||
@ -904,18 +913,57 @@ final class AlterTableImpl extends AbstractQuery implements
|
||||
private final void alterColumnTypeAndNullabilityInBlock(Context<?> ctx) {
|
||||
boolean qualify = ctx.qualify();
|
||||
|
||||
ctx.visit(K_DO).sql(" $$").formatSeparator()
|
||||
.visit(K_BEGIN).formatIndentStart().formatSeparator();
|
||||
begin(ctx);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
accept1(ctx);
|
||||
|
||||
ctx.sql(';').formatSeparator()
|
||||
.visit(K_ALTER_TABLE).sql(' ').visit(table).formatIndentStart().formatSeparator()
|
||||
.visit(K_ALTER).sql(' ').qualify(false).visit(alterColumn).qualify(qualify).sql(' ')
|
||||
.visit(alterColumnType.nullable() ? K_DROP : K_SET).sql(' ').visit(K_NOT_NULL).sql(';')
|
||||
.formatIndentEnd()
|
||||
.formatIndentEnd().formatSeparator()
|
||||
.visit(K_END).sql(" $$");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ctx.sql(';').formatSeparator();
|
||||
|
||||
switch (ctx.family()) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
case POSTGRES: {
|
||||
|
||||
// TODO [#6472] use jOOQ API here, once this is available
|
||||
ctx.visit(K_ALTER_TABLE).sql(' ').visit(table).formatIndentStart().formatSeparator()
|
||||
.visit(K_ALTER).sql(' ').qualify(false).visit(alterColumn).qualify(qualify).sql(' ')
|
||||
.visit(alterColumnType.nullable() ? K_DROP : K_SET).sql(' ').visit(K_NOT_NULL).sql(';')
|
||||
.formatIndentEnd();
|
||||
break;
|
||||
}
|
||||
}
|
||||
end(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -123,6 +123,7 @@ import static org.jooq.impl.Keywords.K_START_WITH;
|
||||
import static org.jooq.impl.Keywords.K_THEN;
|
||||
import static org.jooq.impl.Keywords.K_THROW;
|
||||
import static org.jooq.impl.Keywords.K_WHEN;
|
||||
import static org.jooq.impl.Tools.DataKey.DATA_BLOCK_NESTING;
|
||||
import static org.jooq.tools.reflect.Reflect.accessible;
|
||||
|
||||
import java.io.Serializable;
|
||||
@ -459,6 +460,11 @@ final class Tools {
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The level of anonymous block nesting, in case we're generating a block.
|
||||
*/
|
||||
DATA_BLOCK_NESTING,
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3445,6 +3451,67 @@ final class Tools {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the <code>BEGIN</code> part of an anonymous procedural block.
|
||||
*/
|
||||
static final void begin(Context<?> ctx) {
|
||||
switch (ctx.family()) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
case FIREBIRD: {
|
||||
ctx.visit(K_EXECUTE_BLOCK).formatSeparator()
|
||||
.visit(K_AS).formatSeparator()
|
||||
.visit(K_BEGIN).formatIndentStart().formatSeparator();
|
||||
break;
|
||||
}
|
||||
|
||||
case POSTGRES: {
|
||||
if (increment(ctx.data(), DATA_BLOCK_NESTING))
|
||||
ctx.visit(K_DO).sql(" $$").formatSeparator();
|
||||
|
||||
ctx.visit(K_BEGIN).formatIndentStart().formatSeparator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the <code>END</code> part of an anonymous procedural block.
|
||||
*/
|
||||
static final void end(Context<?> ctx) {
|
||||
switch (ctx.family()) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
case FIREBIRD: {
|
||||
ctx.formatIndentEnd().formatSeparator()
|
||||
.visit(K_END);
|
||||
break;
|
||||
}
|
||||
case POSTGRES: {
|
||||
ctx.formatIndentEnd().formatSeparator()
|
||||
.visit(K_END);
|
||||
|
||||
if (decrement(ctx.data(), DATA_BLOCK_NESTING))
|
||||
ctx.sql(" $$");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a <code>DROP .. IF EXISTS</code> statement with
|
||||
* <code>BEGIN EXECUTE IMMEDIATE '...' EXCEPTION WHEN ... END;</code>, if
|
||||
@ -3497,17 +3564,11 @@ final class Tools {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
case FIREBIRD: {
|
||||
ctx.visit(K_EXECUTE_BLOCK).formatSeparator()
|
||||
.visit(K_AS).formatSeparator()
|
||||
.visit(K_BEGIN).formatIndentStart().formatSeparator()
|
||||
.visit(K_EXECUTE_STATEMENT).sql(" '").stringLiteral(true).formatIndentStart().formatSeparator();
|
||||
|
||||
ctx.visit(K_EXECUTE_STATEMENT).sql(" '").stringLiteral(true).formatIndentStart().formatSeparator();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3594,17 +3655,14 @@ final class Tools {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
case FIREBIRD: {
|
||||
ctx.formatIndentEnd().formatSeparator().stringLiteral(false).sql("';").formatSeparator()
|
||||
.visit(K_WHEN).sql(" sqlcode -607 ").visit(K_DO).formatIndentStart().formatSeparator()
|
||||
.visit(K_BEGIN).sql(' ').visit(K_END).formatIndentEnd().formatIndentEnd().formatSeparator()
|
||||
.visit(K_END);
|
||||
|
||||
.visit(K_BEGIN).sql(' ').visit(K_END).formatIndentEnd();
|
||||
end(ctx);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3715,7 +3773,6 @@ final class Tools {
|
||||
|
||||
|
||||
|
||||
|
||||
default:
|
||||
executeImmediateEnd(ctx, type);
|
||||
break;
|
||||
@ -3980,11 +4037,38 @@ final class Tools {
|
||||
return null;
|
||||
}
|
||||
|
||||
static final void increment(Map<Object, Object> data, DataKey key) {
|
||||
/**
|
||||
* Increment a counter and return true if the counter was zero prior to
|
||||
* incrementing.
|
||||
*/
|
||||
static final boolean increment(Map<Object, Object> data, DataKey key) {
|
||||
boolean result = true;
|
||||
Integer updateCounts = (Integer) data.get(key);
|
||||
|
||||
if (updateCounts == null)
|
||||
updateCounts = 0;
|
||||
else
|
||||
result = false;
|
||||
|
||||
data.put(key, updateCounts + 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement a counter and return true if the counter is zero after
|
||||
* decrementing.
|
||||
*/
|
||||
static final boolean decrement(Map<Object, Object> data, DataKey key) {
|
||||
boolean result = false;
|
||||
Integer updateCounts = (Integer) data.get(key);
|
||||
|
||||
if (updateCounts == null || updateCounts == 0)
|
||||
throw new IllegalStateException("Unmatching increment / decrement on key: " + key);
|
||||
else if (updateCounts == 1)
|
||||
result = true;
|
||||
|
||||
data.put(key, updateCounts - 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
static Field<?> tableField(Table<?> table, Object field) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user