[#5732] Emulate ALTER .. IF EXISTS in Oracle using a PL/SQL block

This commit is contained in:
lukaseder 2016-12-23 18:23:29 +01:00
parent d1e1f3e648
commit 93ab556360
7 changed files with 241 additions and 33 deletions

View File

@ -40,9 +40,18 @@
*/
package org.jooq.impl;
import static java.util.Arrays.asList;
import static org.jooq.Clause.ALTER_INDEX;
import static org.jooq.Clause.ALTER_INDEX_INDEX;
import static org.jooq.Clause.ALTER_INDEX_RENAME;
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
import static org.jooq.SQLDialect.DERBY;
import static org.jooq.SQLDialect.FIREBIRD;
// ...
// ...
import static org.jooq.impl.DSL.name;
import org.jooq.AlterIndexFinalStep;
@ -101,12 +110,27 @@ final class AlterIndexImpl extends AbstractQuery implements
// XXX: QueryPart API
// ------------------------------------------------------------------------
private final boolean supportsIfExists(Context<?> ctx) {
return !asList(CUBRID, DERBY, FIREBIRD).contains(ctx.family());
}
@Override
public final void accept(Context<?> ctx) {
if (ifExists && !supportsIfExists(ctx)) {
Tools.executeImmediateIfExistsBegin(ctx, DDLStatementType.ALTER_INDEX, index);
accept0(ctx);
Tools.executeImmediateIfExistsEnd(ctx, DDLStatementType.ALTER_INDEX, index);
}
else {
accept0(ctx);
}
}
private final void accept0(Context<?> ctx) {
ctx.start(ALTER_INDEX_INDEX)
.keyword("alter index");
if (ifExists)
if (ifExists && supportsIfExists(ctx))
ctx.sql(' ').keyword("if exists");
ctx.sql(' ').visit(index)

View File

@ -45,8 +45,15 @@ import static org.jooq.Clause.ALTER_SEQUENCE;
import static org.jooq.Clause.ALTER_SEQUENCE_RENAME;
import static org.jooq.Clause.ALTER_SEQUENCE_RESTART;
import static org.jooq.Clause.ALTER_SEQUENCE_SEQUENCE;
// ...
// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
import static org.jooq.SQLDialect.DERBY;
import static org.jooq.SQLDialect.FIREBIRD;
// ...
// ...
// ...
// ...
import org.jooq.AlterSequenceFinalStep;
@ -123,8 +130,23 @@ final class AlterSequenceImpl<T extends Number> extends AbstractQuery implements
// XXX: QueryPart API
// ------------------------------------------------------------------------
private final boolean supportsIfExists(Context<?> ctx) {
return !asList(CUBRID, DERBY, FIREBIRD).contains(ctx.family());
}
@Override
public final void accept(Context<?> ctx) {
if (ifExists && !supportsIfExists(ctx)) {
Tools.executeImmediateIfExistsBegin(ctx, DDLStatementType.ALTER_SEQUENCE, sequence);
accept0(ctx);
Tools.executeImmediateIfExistsEnd(ctx, DDLStatementType.ALTER_SEQUENCE, sequence);
}
else {
accept0(ctx);
}
}
private final void accept0(Context<?> ctx) {
switch (ctx.family()) {
@ -137,7 +159,7 @@ final class AlterSequenceImpl<T extends Number> extends AbstractQuery implements
default:
accept0(ctx);
accept1(ctx);
break;
}
}
@ -162,13 +184,13 @@ final class AlterSequenceImpl<T extends Number> extends AbstractQuery implements
private final void accept0(Context<?> ctx) {
private final void accept1(Context<?> ctx) {
ctx.start(ALTER_SEQUENCE_SEQUENCE)
.keyword("alter")
.sql(' ')
.keyword(ctx.family() == CUBRID ? "serial" : "sequence");
if (ifExists)
if (ifExists && supportsIfExists(ctx))
ctx.sql(' ').keyword("if exists");
switch (ctx.family()) {

View File

@ -50,11 +50,16 @@ import static org.jooq.Clause.ALTER_TABLE_RENAME;
import static org.jooq.Clause.ALTER_TABLE_RENAME_COLUMN;
import static org.jooq.Clause.ALTER_TABLE_RENAME_CONSTRAINT;
import static org.jooq.Clause.ALTER_TABLE_TABLE;
// ...
// ...
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.impl.DSL.constraint;
import static org.jooq.impl.DSL.field;
import static org.jooq.impl.DSL.inline;
@ -381,35 +386,50 @@ final class AlterTableImpl extends AbstractQuery implements
// XXX: QueryPart API
// ------------------------------------------------------------------------
private final boolean supportsIfExists(Context<?> ctx) {
return !asList(CUBRID, DERBY, FIREBIRD).contains(ctx.family());
}
@Override
public final void accept(Context<?> ctx) {
SQLDialect family = ctx.configuration().dialect().family();
accept0(ctx);
if (ifExists && !supportsIfExists(ctx)) {
Tools.executeImmediateIfExistsBegin(ctx, DDLStatementType.ALTER_TABLE, table);
accept0(ctx);
Tools.executeImmediateIfExistsEnd(ctx, DDLStatementType.ALTER_TABLE, table);
}
else {
accept0(ctx);
}
}
private final void accept0(Context<?> ctx) {
SQLDialect family = ctx.family();
accept1(ctx);
}
private final void accept1(Context<?> ctx) {
SQLDialect family = ctx.family();
boolean omitAlterTable =
family == HSQLDB && renameConstraint != null;
@ -418,7 +438,7 @@ final class AlterTableImpl extends AbstractQuery implements
ctx.start(ALTER_TABLE_TABLE)
.keyword("alter table");
if (ifExists)
if (ifExists && supportsIfExists(ctx))
ctx.sql(' ').keyword("if exists");
ctx.sql(' ').visit(table)

View File

@ -40,10 +40,19 @@
*/
package org.jooq.impl;
import static java.util.Arrays.asList;
import static org.jooq.Clause.ALTER_VIEW;
import static org.jooq.Clause.ALTER_VIEW_RENAME;
import static org.jooq.Clause.ALTER_VIEW_VIEW;
// ...
// ...
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.impl.DSL.name;
import org.jooq.AlterViewFinalStep;
@ -108,8 +117,23 @@ final class AlterViewImpl extends AbstractQuery implements
// XXX: QueryPart API
// ------------------------------------------------------------------------
private final boolean supportsIfExists(Context<?> ctx) {
return !asList(CUBRID, DERBY, FIREBIRD).contains(ctx.family());
}
@Override
public final void accept(Context<?> ctx) {
if (ifExists && !supportsIfExists(ctx)) {
Tools.executeImmediateIfExistsBegin(ctx, DDLStatementType.ALTER_VIEW, view);
accept0(ctx);
Tools.executeImmediateIfExistsEnd(ctx, DDLStatementType.ALTER_VIEW, view);
}
else {
accept0(ctx);
}
}
private final void accept0(Context<?> ctx) {
switch (ctx.family()) {
@ -122,7 +146,7 @@ final class AlterViewImpl extends AbstractQuery implements
default:
accept0(ctx);
accept1(ctx);
break;
}
@ -148,12 +172,12 @@ final class AlterViewImpl extends AbstractQuery implements
private final void accept0(Context<?> ctx) {
private final void accept1(Context<?> ctx) {
ctx.start(ALTER_VIEW_VIEW)
.keyword("alter").sql(' ')
.keyword(ctx.family() == HSQLDB ? "table" : "view");
if (ifExists)
if (ifExists && supportsIfExists(ctx))
ctx.sql(' ').keyword("if exists");
ctx.sql(' ').visit(view)

View File

@ -50,6 +50,12 @@ enum DDLStatementType {
CREATE_VIEW,
CREATE_SCHEMA,
ALTER_INDEX,
ALTER_SEQUENCE,
ALTER_TABLE,
ALTER_VIEW,
ALTER_SCHEMA,
DROP_INDEX,
DROP_SEQUENCE,
DROP_TABLE,

View File

@ -121,9 +121,9 @@ final class DropIndexImpl extends AbstractQuery implements
@Override
public final void accept(Context<?> ctx) {
if (ifExists && !supportsIfExists(ctx)) {
Tools.executeImmediateBegin(ctx, DDLStatementType.DROP_INDEX);
Tools.executeImmediateIfExistsBegin(ctx, DDLStatementType.DROP_INDEX, index);
accept0(ctx);
Tools.executeImmediateEnd(ctx, DDLStatementType.DROP_INDEX);
Tools.executeImmediateIfExistsEnd(ctx, DDLStatementType.DROP_INDEX, index);
}
else {
accept0(ctx);

View File

@ -68,6 +68,7 @@ import static org.jooq.impl.DSL.escape;
import static org.jooq.impl.DSL.getDataType;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.DSL.nullSafe;
import static org.jooq.impl.DSL.select;
import static org.jooq.impl.DSL.val;
import static org.jooq.impl.DefaultExecuteContext.localConnection;
import static org.jooq.impl.Identifiers.QUOTES;
@ -146,7 +147,9 @@ import org.jooq.Results;
import org.jooq.Row;
import org.jooq.SQLDialect;
import org.jooq.Schema;
import org.jooq.Select;
import org.jooq.SelectField;
import org.jooq.Sequence;
import org.jooq.SortField;
import org.jooq.Table;
import org.jooq.TableRecord;
@ -3204,6 +3207,115 @@ final class Tools {
}
}
static final void executeImmediateIfExistsBegin(Context<?> ctx, DDLStatementType type, QueryPart object) {
switch (ctx.family()) {
default:
executeImmediateBegin(ctx, type);
break;
}
}
static final void executeImmediateIfExistsEnd(Context<?> ctx, DDLStatementType type, QueryPart object) {
switch (ctx.family()) {
default:
executeImmediateEnd(ctx, type);
break;
}
}
static final void toSQLDDLTypeDeclaration(Context<?> ctx, DataType<?> type) {
String typeName = type.getTypeName(ctx.configuration());