extends Named {
* Get this CHECK as a formal {@link Constraint} specification.
*/
Constraint constraint();
+
+ /**
+ * Whether this check is being enforced.
+ */
+ boolean enforced();
}
diff --git a/jOOQ/src/main/java/org/jooq/ConstraintEnforcementStep.java b/jOOQ/src/main/java/org/jooq/ConstraintEnforcementStep.java
new file mode 100644
index 0000000000..73e7823f2f
--- /dev/null
+++ b/jOOQ/src/main/java/org/jooq/ConstraintEnforcementStep.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Other licenses:
+ * -----------------------------------------------------------------------------
+ * Commercial licenses for this work are available. These replace the above
+ * ASL 2.0 and offer limited warranties, support, maintenance, and commercial
+ * database integrations.
+ *
+ * For more information, please visit: http://www.jooq.org/licenses
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+package org.jooq;
+
+// ...
+// ...
+
+/**
+ * The step in the {@link Constraint} construction DSL API that allows for
+ * adding ENFORCED and NOT ENFORCED clauses.
+ *
+ *
+ *
Referencing XYZ*Step types directly from client code
+ *
+ * It is usually not recommended to reference any XYZ*Step types
+ * directly from client code, or assign them to local variables. When writing
+ * dynamic SQL, creating a statement's components dynamically, and passing them
+ * to the DSL API statically is usually a better choice. See the manual's
+ * section about dynamic SQL for details: https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql.
+ *
+ * Drawbacks of referencing the XYZ*Step types directly:
+ *
+ * - They're operating on mutable implementations (as of jOOQ 3.x)
+ * - They're less composable and not easy to get right when dynamic SQL gets
+ * complex
+ * - They're less readable
+ * - They might have binary incompatible changes between minor releases
+ *
+ *
+ * @author Lukas Eder
+ */
+public interface ConstraintEnforcementStep extends ConstraintFinalStep {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/jOOQ/src/main/java/org/jooq/ConstraintForeignKeyOnStep.java b/jOOQ/src/main/java/org/jooq/ConstraintForeignKeyOnStep.java
index fce6392d6f..1b25c5cb7f 100644
--- a/jOOQ/src/main/java/org/jooq/ConstraintForeignKeyOnStep.java
+++ b/jOOQ/src/main/java/org/jooq/ConstraintForeignKeyOnStep.java
@@ -85,7 +85,7 @@ import static org.jooq.SQLDialect.SQLITE;
*
* @author Lukas Eder
*/
-public interface ConstraintForeignKeyOnStep extends ConstraintFinalStep {
+public interface ConstraintForeignKeyOnStep extends ConstraintEnforcementStep {
/**
* Add an ON DELETE NO ACTION clause to the
diff --git a/jOOQ/src/main/java/org/jooq/ConstraintTypeStep.java b/jOOQ/src/main/java/org/jooq/ConstraintTypeStep.java
index 927bc65e06..ed0dfb24af 100644
--- a/jOOQ/src/main/java/org/jooq/ConstraintTypeStep.java
+++ b/jOOQ/src/main/java/org/jooq/ConstraintTypeStep.java
@@ -89,19 +89,19 @@ public interface ConstraintTypeStep extends ConstraintFinalStep {
* Create a PRIMARY KEY constraint.
*/
@Support
- ConstraintFinalStep primaryKey(String... fields);
+ ConstraintEnforcementStep primaryKey(String... fields);
/**
* Create a PRIMARY KEY constraint.
*/
@Support
- ConstraintFinalStep primaryKey(Name... fields);
+ ConstraintEnforcementStep primaryKey(Name... fields);
/**
* Create a PRIMARY KEY constraint.
*/
@Support
- ConstraintFinalStep primaryKey(Field>... fields);
+ ConstraintEnforcementStep primaryKey(Field>... fields);
/**
* Add a FOREIGN KEY clause to the CONSTRAINT.
@@ -525,23 +525,23 @@ public interface ConstraintTypeStep extends ConstraintFinalStep {
* Create a UNIQUE constraint.
*/
@Support
- ConstraintFinalStep unique(String... fields);
+ ConstraintEnforcementStep unique(String... fields);
/**
* Create a UNIQUE constraint.
*/
@Support
- ConstraintFinalStep unique(Name... fields);
+ ConstraintEnforcementStep unique(Name... fields);
/**
* Create a UNIQUE constraint.
*/
@Support
- ConstraintFinalStep unique(Field>... fields);
+ ConstraintEnforcementStep unique(Field>... fields);
/**
* Create a CHECK constraint.
*/
@Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, MARIADB, POSTGRES, SQLITE })
- ConstraintFinalStep check(Condition condition);
+ ConstraintEnforcementStep check(Condition condition);
}
diff --git a/jOOQ/src/main/java/org/jooq/Key.java b/jOOQ/src/main/java/org/jooq/Key.java
index 4fee12c6cf..8a0b5c45b9 100644
--- a/jOOQ/src/main/java/org/jooq/Key.java
+++ b/jOOQ/src/main/java/org/jooq/Key.java
@@ -73,4 +73,9 @@ public interface Key extends Named {
* Get this KEY as a formal {@link Constraint} specification.
*/
Constraint constraint();
+
+ /**
+ * Whether this key is being enforced.
+ */
+ boolean enforced();
}
diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractKey.java b/jOOQ/src/main/java/org/jooq/impl/AbstractKey.java
index cf1e8b4507..ff9ff0cac4 100644
--- a/jOOQ/src/main/java/org/jooq/impl/AbstractKey.java
+++ b/jOOQ/src/main/java/org/jooq/impl/AbstractKey.java
@@ -60,22 +60,18 @@ abstract class AbstractKey extends AbstractNamed implements Ke
private final Table table;
private final TableField[] fields;
+ private final boolean enforced;
-
- @SafeVarargs
-
- AbstractKey(Table table, TableField... fields) {
- this(table, null, fields);
+ AbstractKey(Table table, TableField[] fields, boolean enforced) {
+ this(table, null, fields, enforced);
}
-
- @SafeVarargs
-
- AbstractKey(Table table, String name, TableField... fields) {
+ AbstractKey(Table table, String name, TableField[] fields, boolean enforced) {
super(name == null ? null : DSL.name(name), null);
this.table = table;
this.fields = fields;
+ this.enforced = enforced;
}
@Override
@@ -93,6 +89,11 @@ abstract class AbstractKey extends AbstractNamed implements Ke
return fields;
}
+ @Override
+ public final boolean enforced() {
+ return enforced;
+ }
+
@Override
public final void accept(Context> ctx) {
ctx.visit(getUnqualifiedName());
diff --git a/jOOQ/src/main/java/org/jooq/impl/AlterTableImpl.java b/jOOQ/src/main/java/org/jooq/impl/AlterTableImpl.java
index c05f8d01b3..5468aa926f 100644
--- a/jOOQ/src/main/java/org/jooq/impl/AlterTableImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/AlterTableImpl.java
@@ -164,6 +164,7 @@ import java.util.List;
import java.util.Set;
import org.jooq.AlterTableAddStep;
+// ...
import org.jooq.AlterTableAlterStep;
import org.jooq.AlterTableDropStep;
import org.jooq.AlterTableFinalStep;
@@ -203,6 +204,7 @@ final class AlterTableImpl extends AbstractRowCountQuery implements
AlterTableAddStep,
AlterTableDropStep,
AlterTableAlterStep,
+ AlterTableAlterConstraintStep,
AlterTableUsingIndexStep,
AlterTableRenameColumnToStep,
AlterTableRenameIndexToStep,
@@ -259,6 +261,10 @@ final class AlterTableImpl extends AbstractRowCountQuery implements
+
+
+
+
private Field> alterColumn;
private Nullability alterColumnNullability;
private DataType> alterColumnType;
@@ -280,32 +286,38 @@ final class AlterTableImpl extends AbstractRowCountQuery implements
this.ifExists = ifExists;
}
- final Table> $table() { return table; }
- final boolean $ifExists() { return ifExists; }
- final boolean $ifExistsColumn() { return ifExistsColumn; }
- final boolean $ifExistsConstraint() { return ifExistsConstraint; }
- final boolean $ifNotExistsColumn() { return ifNotExistsColumn; }
- final List $add() { return add; }
- final Field> $addColumn() { return addColumn; }
- final DataType> $addColumnType() { return addColumnType; }
- final Constraint $addConstraint() { return addConstraint; }
- final boolean $addFirst() { return addFirst; }
- final Field> $addBefore() { return addBefore; }
- final Field> $addAfter() { return addAfter; }
- final Field> $alterColumn() { return alterColumn; }
- final Nullability $alterColumnNullability() { return alterColumnNullability; }
- final DataType> $alterColumnType() { return alterColumnType; }
- final Field> $alterColumnDefault() { return alterColumnDefault; }
- final boolean $alterColumnDropDefault() { return alterColumnDropDefault; }
- final Table> $renameTo() { return renameTo; }
- final Field> $renameColumn() { return renameColumn; }
- final Field> $renameColumnTo() { return renameColumnTo; }
- final Constraint $renameConstraint() { return renameConstraint; }
- final Constraint $renameConstraintTo() { return renameConstraintTo; }
- final List> $dropColumns() { return dropColumns; }
- final Cascade $dropCascade() { return dropCascade; }
- final Constraint $dropConstraint() { return dropConstraint; }
- final ConstraintType $dropConstraintType() { return dropConstraintType; }
+ final Table> $table() { return table; }
+ final boolean $ifExists() { return ifExists; }
+ final boolean $ifExistsColumn() { return ifExistsColumn; }
+ final boolean $ifExistsConstraint() { return ifExistsConstraint; }
+ final boolean $ifNotExistsColumn() { return ifNotExistsColumn; }
+ final List $add() { return add; }
+ final Field> $addColumn() { return addColumn; }
+ final DataType> $addColumnType() { return addColumnType; }
+ final Constraint $addConstraint() { return addConstraint; }
+ final boolean $addFirst() { return addFirst; }
+ final Field> $addBefore() { return addBefore; }
+ final Field> $addAfter() { return addAfter; }
+ final Field> $alterColumn() { return alterColumn; }
+ final Nullability $alterColumnNullability() { return alterColumnNullability; }
+ final DataType> $alterColumnType() { return alterColumnType; }
+ final Field> $alterColumnDefault() { return alterColumnDefault; }
+ final boolean $alterColumnDropDefault() { return alterColumnDropDefault; }
+
+
+
+
+
+
+ final Table> $renameTo() { return renameTo; }
+ final Field> $renameColumn() { return renameColumn; }
+ final Field> $renameColumnTo() { return renameColumnTo; }
+ final Constraint $renameConstraint() { return renameConstraint; }
+ final Constraint $renameConstraintTo() { return renameConstraintTo; }
+ final List> $dropColumns() { return dropColumns; }
+ final Cascade $dropCascade() { return dropCascade; }
+ final Constraint $dropConstraint() { return dropConstraint; }
+ final ConstraintType $dropConstraintType() { return dropConstraintType; }
// ------------------------------------------------------------------------
// XXX: DSL API
@@ -635,6 +647,43 @@ final class AlterTableImpl extends AbstractRowCountQuery implements
return this;
}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@Override
public final AlterTableImpl set(DataType type) {
alterColumnType = type;
@@ -1357,6 +1406,30 @@ final class AlterTableImpl extends AbstractRowCountQuery implements
ctx.end(ALTER_TABLE_ADD);
}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
else if (alterColumn != null) {
ctx.start(ALTER_TABLE_ALTER);
diff --git a/jOOQ/src/main/java/org/jooq/impl/CheckImpl.java b/jOOQ/src/main/java/org/jooq/impl/CheckImpl.java
index 003addab2f..5a57e9c66b 100644
--- a/jOOQ/src/main/java/org/jooq/impl/CheckImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/CheckImpl.java
@@ -57,33 +57,40 @@ final class CheckImpl extends AbstractNamed implements Check table;
final Condition condition;
+ final boolean enforced;
- CheckImpl(Table table, Condition condition) {
- this(table, null, condition);
+ CheckImpl(Table table, Condition condition, boolean enforced) {
+ this(table, null, condition, enforced);
}
- CheckImpl(Table table, Name name, Condition condition) {
+ CheckImpl(Table table, Name name, Condition condition, boolean enforced) {
super(name, null);
this.table = table;
this.condition = condition;
+ this.enforced = enforced;
}
@Override
- public Table getTable() {
+ public final Table getTable() {
return table;
}
@Override
- public Condition condition() {
+ public final Condition condition() {
return condition;
}
@Override
- public Constraint constraint() {
+ public final Constraint constraint() {
return DSL.constraint(getName()).check(condition);
}
+ @Override
+ public final boolean enforced() {
+ return enforced;
+ }
+
@Override
public final void accept(Context> ctx) {
ctx.visit(getUnqualifiedName());
diff --git a/jOOQ/src/main/java/org/jooq/impl/ConstraintImpl.java b/jOOQ/src/main/java/org/jooq/impl/ConstraintImpl.java
index 61dda78a90..2b0e6826a9 100644
--- a/jOOQ/src/main/java/org/jooq/impl/ConstraintImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/ConstraintImpl.java
@@ -51,8 +51,12 @@ import static org.jooq.impl.DSL.name;
import static org.jooq.impl.DSL.table;
import static org.jooq.impl.Keywords.K_CHECK;
import static org.jooq.impl.Keywords.K_CONSTRAINT;
+import static org.jooq.impl.Keywords.K_DISABLE;
+import static org.jooq.impl.Keywords.K_ENABLE;
+import static org.jooq.impl.Keywords.K_ENFORCED;
import static org.jooq.impl.Keywords.K_FOREIGN_KEY;
import static org.jooq.impl.Keywords.K_NONCLUSTERED;
+import static org.jooq.impl.Keywords.K_NOT;
import static org.jooq.impl.Keywords.K_NOT_ENFORCED;
import static org.jooq.impl.Keywords.K_ON_DELETE;
import static org.jooq.impl.Keywords.K_ON_UPDATE;
@@ -141,8 +145,8 @@ implements
/**
* Generated UID
*/
- private static final long serialVersionUID = 1018023703769802616L;
- private static final Clause[] CLAUSES = { CONSTRAINT };
+ private static final long serialVersionUID = 1018023703769802616L;
+ private static final Clause[] CLAUSES = { CONSTRAINT };
@@ -150,14 +154,18 @@ implements
- private Field>[] unique;
- private Field>[] primaryKey;
- private Field>[] foreignKey;
- private Table> referencesTable;
- private Field>[] references;
- private Action onDelete;
- private Action onUpdate;
- private Condition check;
+ private Field>[] unique;
+ private Field>[] primaryKey;
+ private Field>[] foreignKey;
+ private Table> referencesTable;
+ private Field>[] references;
+ private Action onDelete;
+ private Action onUpdate;
+ private Condition check;
+
+
+
+
ConstraintImpl() {
this(null);
@@ -176,6 +184,10 @@ implements
final Action $onUpdate() { return onUpdate; }
final Condition $check() { return check; }
+
+
+
+
// ------------------------------------------------------------------------
// XXX: QueryPart API
// ------------------------------------------------------------------------
@@ -277,6 +289,11 @@ implements
.sql(')');
}
+
+
+
+
+
if (named) {
@@ -293,6 +310,30 @@ implements
}
}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
// ------------------------------------------------------------------------
// XXX: Constraint API
// ------------------------------------------------------------------------
@@ -1107,6 +1148,22 @@ implements
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
enum Action {
NO_ACTION("no action"),
RESTRICT("restrict"),
diff --git a/jOOQ/src/main/java/org/jooq/impl/DDL.java b/jOOQ/src/main/java/org/jooq/impl/DDL.java
index 29db2e96f4..6dc6aae530 100644
--- a/jOOQ/src/main/java/org/jooq/impl/DDL.java
+++ b/jOOQ/src/main/java/org/jooq/impl/DDL.java
@@ -58,6 +58,7 @@ import java.util.List;
import org.jooq.Check;
import org.jooq.Constraint;
+import org.jooq.ConstraintEnforcementStep;
import org.jooq.CreateSequenceFlagsStep;
import org.jooq.CreateTableOnCommitStep;
import org.jooq.DDLExportConfiguration;
@@ -220,7 +221,7 @@ final class DDL {
if (configuration.flags().contains(PRIMARY_KEY))
for (UniqueKey> key : table.getKeys())
if (key.isPrimary())
- result.add(constraint(key.getUnqualifiedName()).primaryKey(key.getFieldsArray()));
+ result.add(enforced(constraint(key.getUnqualifiedName()).primaryKey(key.getFieldsArray()), key.enforced()));
return result;
}
@@ -231,7 +232,7 @@ final class DDL {
if (configuration.flags().contains(UNIQUE))
for (UniqueKey> key : sortKeysIf(table.getKeys(), !configuration.respectConstraintOrder()))
if (!key.isPrimary())
- result.add(constraint(key.getUnqualifiedName()).unique(key.getFieldsArray()));
+ result.add(enforced(constraint(key.getUnqualifiedName()).unique(key.getFieldsArray()), key.enforced()));
return result;
}
@@ -241,7 +242,7 @@ final class DDL {
if (configuration.flags().contains(FOREIGN_KEY))
for (ForeignKey, ?> key : sortKeysIf(table.getReferences(), !configuration.respectConstraintOrder()))
- result.add(constraint(key.getUnqualifiedName()).foreignKey(key.getFieldsArray()).references(key.getKey().getTable(), key.getKey().getFieldsArray()));
+ result.add(enforced(constraint(key.getUnqualifiedName()).foreignKey(key.getFieldsArray()).references(key.getKey().getTable(), key.getKey().getFieldsArray()), key.enforced()));
return result;
}
@@ -251,7 +252,7 @@ final class DDL {
if (configuration.flags().contains(CHECK))
for (Check> check : sortIf(table.getChecks(), !configuration.respectConstraintOrder()))
- result.add(constraint(check.getUnqualifiedName()).check(check.condition()));
+ result.add(enforced(constraint(check.getUnqualifiedName()).check(check.condition()), check.enforced()));
return result;
}
@@ -382,4 +383,13 @@ final class DDL {
return input;
}
+
+ private final Constraint enforced(ConstraintEnforcementStep check, boolean enforced) {
+
+
+
+
+
+ return check;
+ }
}
diff --git a/jOOQ/src/main/java/org/jooq/impl/DDLInterpreter.java b/jOOQ/src/main/java/org/jooq/impl/DDLInterpreter.java
index 6621cbc884..6c44ca427d 100644
--- a/jOOQ/src/main/java/org/jooq/impl/DDLInterpreter.java
+++ b/jOOQ/src/main/java/org/jooq/impl/DDLInterpreter.java
@@ -315,14 +315,14 @@ final class DDLInterpreter {
if (!mrfs.isEmpty())
mu = mrf.uniqueKey(mrfs);
- else if (mrf.primaryKey != null && mrf.primaryKey.keyFields.size() == mfs.size())
+ else if (mrf.primaryKey != null && mrf.primaryKey.fields.size() == mfs.size())
mu = mrf.primaryKey;
if (mu == null)
throw primaryKeyNotExists();
mt.foreignKeys.add(new MutableForeignKey(
- (UnqualifiedName) impl.getUnqualifiedName(), mt, mfs, mu, impl.$onDelete(), impl.$onUpdate()
+ (UnqualifiedName) impl.getUnqualifiedName(), mt, mfs, mu, impl.$onDelete(), impl.$onUpdate(), impl.$enforced()
));
}
@@ -349,7 +349,7 @@ final class DDLInterpreter {
for (boolean check : cascade == CASCADE ? new boolean [] { false } : new boolean [] { true, false }) {
if (table.primaryKey != null) {
- if (intersect(table.primaryKey.keyFields, fields)) {
+ if (intersect(table.primaryKey.fields, fields)) {
cascade(table.primaryKey, fields, check ? RESTRICT : CASCADE);
if (!check)
@@ -382,7 +382,7 @@ final class DDLInterpreter {
while (it2.hasNext()) {
MutableKey key = it2.next();
- if (fields == null || intersect(key.keyFields, fields)) {
+ if (fields == null || intersect(key.fields, fields)) {
if (key instanceof MutableUniqueKey)
cascade((MutableUniqueKey) key, fields, check ? RESTRICT : CASCADE);
@@ -522,14 +522,15 @@ final class DDLInterpreter {
mf.name((UnqualifiedName) query.$renameColumnTo().getUnqualifiedName());
}
else if (query.$renameConstraint() != null) {
- MutableNamed mk = existing.constraint(query.$renameConstraint());
+ MutableConstraint mc = existing.constraint(query.$renameConstraint(), true);
- if (mk == null)
- throw constraintNotExists(query.$renameConstraint());
- else if (existing.constraint(query.$renameConstraintTo()) != null)
+ if (existing.constraint(query.$renameConstraintTo()) != null)
throw constraintAlreadyExists(query.$renameConstraintTo());
else
- mk.name((UnqualifiedName) query.$renameConstraintTo().getUnqualifiedName());
+ mc.name((UnqualifiedName) query.$renameConstraintTo().getUnqualifiedName());
+ }
+ else if (query.$alterConstraint() != null) {
+ existing.constraint(query.$alterConstraint(), true).enforced = query.$alterConstraintEnforced();
}
else if (query.$dropColumns() != null) {
List fields = existing.fields(query.$dropColumns().toArray(EMPTY_FIELD), false);
@@ -671,13 +672,13 @@ final class DDLInterpreter {
if (existing.primaryKey != null)
throw constraintAlreadyExists(impl);
else
- existing.primaryKey = new MutableUniqueKey((UnqualifiedName) impl.getUnqualifiedName(), existing, existing.fields(impl.$primaryKey(), true));
+ existing.primaryKey = new MutableUniqueKey((UnqualifiedName) impl.getUnqualifiedName(), existing, existing.fields(impl.$primaryKey(), true), impl.$enforced());
else if (impl.$unique() != null)
- existing.uniqueKeys.add(new MutableUniqueKey((UnqualifiedName) impl.getUnqualifiedName(), existing, existing.fields(impl.$unique(), true)));
+ existing.uniqueKeys.add(new MutableUniqueKey((UnqualifiedName) impl.getUnqualifiedName(), existing, existing.fields(impl.$unique(), true), impl.$enforced()));
else if (impl.$foreignKey() != null)
addForeignKey(getSchema(impl.$referencesTable().getSchema(), false), existing, impl);
else if (impl.$check() != null)
- existing.checks.add(new MutableCheck((UnqualifiedName) impl.getUnqualifiedName(), existing, impl.$check()));
+ existing.checks.add(new MutableCheck((UnqualifiedName) impl.getUnqualifiedName(), existing, impl.$check(), impl.$enforced()));
else
throw unsupportedQuery(query);
}
@@ -1395,7 +1396,7 @@ final class DDLInterpreter {
final void onDrop() {
for (MutableTable table : tables)
for (MutableForeignKey referencingKey : table.referencingKeys())
- referencingKey.keyTable.foreignKeys.remove(referencingKey);
+ referencingKey.table.foreignKeys.remove(referencingKey);
tables.clear();
sequences.clear();
@@ -1523,8 +1524,8 @@ final class DDLInterpreter {
return result;
}
- final MutableNamed constraint(Constraint constraint) {
- MutableNamed result;
+ final MutableConstraint constraint(Constraint constraint, boolean failIfNotFound) {
+ MutableConstraint result;
if ((result = find(foreignKeys, constraint)) != null)
return result;
@@ -1535,7 +1536,17 @@ final class DDLInterpreter {
if ((result = find(checks, constraint)) != null)
return result;
- return find(primaryKey, constraint);
+ if ((result = find(primaryKey, constraint)) != null)
+ return result;
+
+ if (failIfNotFound)
+ throw constraintNotExists(constraint);
+
+ return null;
+ }
+
+ final MutableNamed constraint(Constraint constraint) {
+ return constraint(constraint, false);
}
final List fields(Field>[] fs, boolean failIfNotFound) {
@@ -1571,11 +1582,11 @@ final class DDLInterpreter {
final MutableUniqueKey uniqueKey(List mrfs) {
if (primaryKey != null)
- if (primaryKey.keyFields.equals(mrfs))
+ if (primaryKey.fields.equals(mrfs))
return primaryKey;
for (MutableUniqueKey mu : uniqueKeys)
- if (mu.keyFields.equals(mrfs))
+ if (mu.fields.equals(mrfs))
return mu;
return null;
@@ -1625,7 +1636,7 @@ final class DDLInterpreter {
List> result = new ArrayList<>();
for (MutableCheck c : MutableTable.this.checks)
- result.add(new CheckImpl<>(this, c.name(), c.condition));
+ result.add(new CheckImpl<>(this, c.name(), c.condition, c.enforced));
return result;
}
@@ -1690,53 +1701,56 @@ final class DDLInterpreter {
}
}
- private abstract class MutableKey extends MutableNamed {
- MutableTable keyTable;
- List keyFields;
+ private abstract class MutableConstraint extends MutableNamed {
+ MutableTable table;
+ boolean enforced;
- MutableKey(UnqualifiedName name, MutableTable table, List fields) {
+ MutableConstraint(UnqualifiedName name, MutableTable table, boolean enforced) {
super(name);
- this.keyTable = table;
- this.keyFields = fields;
+ this.table = table;
+ this.enforced = enforced;
}
@Override
final MutableNamed parent() {
- return keyTable;
+ return table;
+ }
+ }
+
+ private abstract class MutableKey extends MutableConstraint {
+ List fields;
+
+ MutableKey(UnqualifiedName name, MutableTable table, List fields, boolean enforced) {
+ super(name, table, enforced);
+
+ this.fields = fields;
}
- final boolean fieldsEquals(Field>[] fields) {
- if (keyFields.size() != fields.length)
+ final boolean fieldsEquals(Field>[] f) {
+ if (fields.size() != f.length)
return false;
- for (int i = 0; i < keyFields.size(); i++)
- if (!keyFields.get(i).nameEquals((UnqualifiedName) fields[i].getUnqualifiedName()))
+ for (int i = 0; i < fields.size(); i++)
+ if (!fields.get(i).nameEquals((UnqualifiedName) f[i].getUnqualifiedName()))
return false;
return true;
}
}
- private final class MutableCheck extends MutableNamed {
- MutableTable table;
- Condition condition;
+ private final class MutableCheck extends MutableConstraint {
+ Condition condition;
- MutableCheck(UnqualifiedName name, MutableTable table, Condition condition) {
- super(name);
+ MutableCheck(UnqualifiedName name, MutableTable table, Condition condition, boolean enforced) {
+ super(name, table, enforced);
- this.table = table;
this.condition = condition;
}
@Override
final void onDrop() {}
- @Override
- final MutableNamed parent() {
- return table;
- }
-
@Override
final Name qualifiedName() {
@@ -1751,8 +1765,8 @@ final class DDLInterpreter {
private final class MutableUniqueKey extends MutableKey {
List referencingKeys = new MutableNamedList<>();
- MutableUniqueKey(UnqualifiedName name, MutableTable keyTable, List keyFields) {
- super(name, keyTable, keyFields);
+ MutableUniqueKey(UnqualifiedName name, MutableTable table, List fields, boolean enforced) {
+ super(name, table, fields, enforced);
}
@Override
@@ -1766,7 +1780,7 @@ final class DDLInterpreter {
// TODO: Find a better way to identify unnamed constraints.
if (name().empty())
- return super.qualifiedName().append(keyFields.toString());
+ return super.qualifiedName().append(fields.toString());
else
return super.qualifiedName();
}
@@ -1777,14 +1791,14 @@ final class DDLInterpreter {
UniqueKeyImpl result = interpretedUniqueKeys.get(qualifiedName);
if (result == null) {
- MutableTable.InterpretedTable t = keyTable.interpretedTable();
- TableField[] f = new TableField[keyFields.size()];
+ MutableTable.InterpretedTable t = table.interpretedTable();
+ TableField[] f = new TableField[fields.size()];
for (int i = 0; i < f.length; i++)
- f[i] = (TableField) t.field(keyFields.get(i).name());
+ f[i] = (TableField) t.field(fields.get(i).name());
// Add to map before adding bi-directionality to avoid StackOverflowErrors
- interpretedUniqueKeys.put(qualifiedName, result = new UniqueKeyImpl<>(t, name().last(), f));
+ interpretedUniqueKeys.put(qualifiedName, result = new UniqueKeyImpl<>(t, name().last(), f, enforced));
for (MutableForeignKey referencingKey : referencingKeys)
result.references.add((ForeignKey) referencingKey.interpretedKey());
}
@@ -1795,18 +1809,21 @@ final class DDLInterpreter {
private final class MutableForeignKey extends MutableKey {
MutableUniqueKey referencedKey;
+
+ // TODO: Support these
Action onDelete;
Action onUpdate;
MutableForeignKey(
UnqualifiedName name,
- MutableTable keyTable,
- List keyFields,
+ MutableTable table,
+ List fields,
MutableUniqueKey referencedKey,
Action onDelete,
- Action onUpdate
+ Action onUpdate,
+ boolean enforced
) {
- super(name, keyTable, keyFields);
+ super(name, table, fields, enforced);
this.referencedKey = referencedKey;
this.referencedKey.referencingKeys.add(this);
@@ -1835,13 +1852,13 @@ final class DDLInterpreter {
ReferenceImpl result = interpretedForeignKeys.get(qualifiedName);
if (result == null) {
- MutableTable.InterpretedTable t = keyTable.interpretedTable();
- TableField[] f = new TableField[keyFields.size()];
+ MutableTable.InterpretedTable t = table.interpretedTable();
+ TableField[] f = new TableField[fields.size()];
for (int i = 0; i < f.length; i++)
- f[i] = (TableField) t.field(keyFields.get(i).name());
+ f[i] = (TableField) t.field(fields.get(i).name());
- interpretedForeignKeys.put(qualifiedName, result = new ReferenceImpl<>(referencedKey.interpretedKey(), t, name().last(), f));
+ interpretedForeignKeys.put(qualifiedName, result = new ReferenceImpl<>(referencedKey.interpretedKey(), t, name().last(), f, enforced));
}
return result;
diff --git a/jOOQ/src/main/java/org/jooq/impl/DSL.java b/jOOQ/src/main/java/org/jooq/impl/DSL.java
index 5c2a0f3a5b..9ba9ee4132 100644
--- a/jOOQ/src/main/java/org/jooq/impl/DSL.java
+++ b/jOOQ/src/main/java/org/jooq/impl/DSL.java
@@ -149,7 +149,7 @@ import org.jooq.CommonTableExpression;
import org.jooq.Condition;
import org.jooq.Configuration;
import org.jooq.ConnectionProvider;
-import org.jooq.ConstraintFinalStep;
+import org.jooq.ConstraintEnforcementStep;
import org.jooq.ConstraintForeignKeyReferencesStep1;
import org.jooq.ConstraintForeignKeyReferencesStep10;
import org.jooq.ConstraintForeignKeyReferencesStep11;
@@ -5916,7 +5916,7 @@ public class DSL {
* Create an unnamed (system named) PRIMARY KEY constraint.
*/
@Support
- public static ConstraintFinalStep primaryKey(String... fields) {
+ public static ConstraintEnforcementStep primaryKey(String... fields) {
return constraint().primaryKey(fields);
}
@@ -5924,7 +5924,7 @@ public class DSL {
* Create an unnamed (system named) PRIMARY KEY constraint.
*/
@Support
- public static ConstraintFinalStep primaryKey(Name... fields) {
+ public static ConstraintEnforcementStep primaryKey(Name... fields) {
return constraint().primaryKey(fields);
}
@@ -5932,7 +5932,7 @@ public class DSL {
* Create an unnamed (system named) PRIMARY KEY constraint.
*/
@Support
- public static ConstraintFinalStep primaryKey(Field>... fields) {
+ public static ConstraintEnforcementStep primaryKey(Field>... fields) {
return constraint().primaryKey(fields);
}
@@ -6496,7 +6496,7 @@ public class DSL {
* Create an unnamed (system named) UNIQUE constraint.
*/
@Support
- public static ConstraintFinalStep unique(String... fields) {
+ public static ConstraintEnforcementStep unique(String... fields) {
return constraint().unique(fields);
}
@@ -6504,7 +6504,7 @@ public class DSL {
* Create an unnamed (system named) UNIQUE constraint.
*/
@Support
- public static ConstraintFinalStep unique(Name... fields) {
+ public static ConstraintEnforcementStep unique(Name... fields) {
return constraint().unique(fields);
}
@@ -6512,7 +6512,7 @@ public class DSL {
* Create an unnamed (system named) UNIQUE constraint.
*/
@Support
- public static ConstraintFinalStep unique(Field>... fields) {
+ public static ConstraintEnforcementStep unique(Field>... fields) {
return constraint().unique(fields);
}
@@ -6520,7 +6520,7 @@ public class DSL {
* Create an unnamed (system named) CHECK constraint.
*/
@Support({ CUBRID, DERBY, FIREBIRD, H2, HSQLDB, POSTGRES, SQLITE })
- public static ConstraintFinalStep check(Condition condition) {
+ public static ConstraintEnforcementStep check(Condition condition) {
return constraint().check(condition);
}
diff --git a/jOOQ/src/main/java/org/jooq/impl/InformationSchemaMetaImpl.java b/jOOQ/src/main/java/org/jooq/impl/InformationSchemaMetaImpl.java
index 01ceefa761..23bc60c11f 100644
--- a/jOOQ/src/main/java/org/jooq/impl/InformationSchemaMetaImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/InformationSchemaMetaImpl.java
@@ -421,7 +421,7 @@ final class InformationSchemaMetaImpl extends AbstractMeta {
for (CheckConstraint cc : meta.getCheckConstraints()) {
if (constraintName.equals(name(cc.getConstraintCatalog(), cc.getConstraintSchema(), cc.getConstraintName()))) {
- table.checks.add(new CheckImpl<>(table, constraintName, DSL.condition(cc.getCheckClause())));
+ table.checks.add(new CheckImpl<>(table, constraintName, DSL.condition(cc.getCheckClause()), true));
continue tableConstraintLoop;
}
}
diff --git a/jOOQ/src/main/java/org/jooq/impl/Internal.java b/jOOQ/src/main/java/org/jooq/impl/Internal.java
index 5538e94585..f7015b1a05 100644
--- a/jOOQ/src/main/java/org/jooq/impl/Internal.java
+++ b/jOOQ/src/main/java/org/jooq/impl/Internal.java
@@ -100,7 +100,7 @@ public final class Internal {
@SafeVarargs
public static final UniqueKey createUniqueKey(Table table, TableField... fields) {
- return new UniqueKeyImpl<>(table, fields);
+ return new UniqueKeyImpl<>(table, fields, true);
}
/**
@@ -110,7 +110,7 @@ public final class Internal {
@SafeVarargs
public static final UniqueKey createUniqueKey(Table table, String name, TableField... fields) {
- return new UniqueKeyImpl<>(table, name, fields);
+ return new UniqueKeyImpl<>(table, name, fields, true);
}
/**
@@ -130,7 +130,7 @@ public final class Internal {
@SafeVarargs
public static final ForeignKey createForeignKey(UniqueKey key, Table table, String name, TableField... fields) {
- ForeignKey result = new ReferenceImpl<>(key, table, name, fields);
+ ForeignKey result = new ReferenceImpl<>(key, table, name, fields, true);
if (key instanceof UniqueKeyImpl)
((UniqueKeyImpl) key).references.add(result);
@@ -167,7 +167,7 @@ public final class Internal {
* Factory method for check constraints.
*/
public static final Check createCheck(Table table, Name name, String condition) {
- return new CheckImpl<>(table, name, DSL.condition(condition));
+ return new CheckImpl<>(table, name, DSL.condition(condition), true);
}
/**
diff --git a/jOOQ/src/main/java/org/jooq/impl/Keywords.java b/jOOQ/src/main/java/org/jooq/impl/Keywords.java
index 29dfd923ff..4d906c08ce 100644
--- a/jOOQ/src/main/java/org/jooq/impl/Keywords.java
+++ b/jOOQ/src/main/java/org/jooq/impl/Keywords.java
@@ -120,6 +120,7 @@ final class Keywords {
static final Keyword K_DELETE = keyword("delete");
static final Keyword K_DELETE_WHERE = keyword("delete where");
static final Keyword K_DENSE_RANK = keyword("dense_rank");
+ static final Keyword K_DISABLE = keyword("disable");
static final Keyword K_DISTINCT = keyword("distinct");
static final Keyword K_DISTINCT_ON = keyword("distinct on");
static final Keyword K_DO = keyword("do");
@@ -137,11 +138,13 @@ final class Keywords {
static final Keyword K_ELSE = keyword("else");
static final Keyword K_ELSEIF = keyword("elseif");
static final Keyword K_ELSIF = keyword("elsif");
+ static final Keyword K_ENABLE = keyword("enable");
static final Keyword K_END = keyword("end");
static final Keyword K_END_CATCH = keyword("end catch");
static final Keyword K_END_IF = keyword("end if");
static final Keyword K_END_LOOP = keyword("end loop");
static final Keyword K_END_TRY = keyword("end try");
+ static final Keyword K_ENFORCED = keyword("enforced");
static final Keyword K_ENUM = keyword("enum");
static final Keyword K_ESCAPE = keyword("escape");
static final Keyword K_EXCEPT = keyword("except");
diff --git a/jOOQ/src/main/java/org/jooq/impl/MetaImpl.java b/jOOQ/src/main/java/org/jooq/impl/MetaImpl.java
index a6eb254e91..a60f980dc6 100644
--- a/jOOQ/src/main/java/org/jooq/impl/MetaImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/MetaImpl.java
@@ -654,7 +654,7 @@ final class MetaImpl extends AbstractMeta {
fkFields[i] = (TableField) field(record.get(7, String.class));
}
- references.add(new ReferenceImpl<>(new MetaPrimaryKey(pkTable, pkName, pkFields), this, fkName, fkFields));
+ references.add(new ReferenceImpl<>(new MetaPrimaryKey(pkTable, pkName, pkFields), this, fkName, fkFields, true));
}
return references;
@@ -867,6 +867,11 @@ final class MetaImpl extends AbstractMeta {
return true;
}
+ @Override
+ public final boolean enforced() {
+ return true;
+ }
+
@Override
@SuppressWarnings("unchecked")
public final List> getReferences() {
@@ -923,7 +928,7 @@ final class MetaImpl extends AbstractMeta {
for (int i = 0; i < value.size(); i++)
fkFields[i] = (TableField) fkTable.field(value.get(i).get(7, String.class));
- references.add(new ReferenceImpl<>(this, fkTable, fkName, fkFields));
+ references.add(new ReferenceImpl<>(this, fkTable, fkName, fkFields, true));
}
return references;
diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java
index 0f3afab515..2fc3c119f0 100644
--- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java
@@ -361,6 +361,7 @@ import org.jooq.Comparator;
import org.jooq.Condition;
import org.jooq.Configuration;
import org.jooq.Constraint;
+import org.jooq.ConstraintEnforcementStep;
import org.jooq.ConstraintForeignKeyOnStep;
import org.jooq.ConstraintTypeStep;
import org.jooq.CreateIndexFinalStep;
@@ -3610,9 +3611,9 @@ final class ParserImpl implements Parser {
if (!parseKeywordIf(ctx, "CLUSTERED"))
parseKeywordIf(ctx, "NONCLUSTERED");
- constraints.add(inlineConstraint == null
+ constraints.add(parseConstraintEnforcementIf(ctx, inlineConstraint == null
? primaryKey(fieldName)
- : inlineConstraint.primaryKey(fieldName));
+ : inlineConstraint.primaryKey(fieldName)));
primary = true;
unique = true;
continue;
@@ -3621,9 +3622,9 @@ final class ParserImpl implements Parser {
if (!parseKeywordIf(ctx, "KEY"))
parseKeywordIf(ctx, "INDEX");
- constraints.add(inlineConstraint == null
+ constraints.add(parseConstraintEnforcementIf(ctx, inlineConstraint == null
? unique(fieldName)
- : inlineConstraint.unique(fieldName));
+ : inlineConstraint.unique(fieldName)));
unique = true;
continue;
}
@@ -3700,35 +3701,36 @@ final class ParserImpl implements Parser {
return Internal.createIndex(name == null ? NO_NAME : name, table, fields, false);
}
- private static final boolean parseConstraintStateIf(ParserContext ctx) {
- parseKeywordIf(ctx, "ENABLE");
- return true;
+ private static final Constraint parseConstraintEnforcementIf(ParserContext ctx, ConstraintEnforcementStep e) {
+ if ((parseKeywordIf(ctx, "ENABLE") || parseKeywordIf(ctx, "ENFORCED")) && ctx.requireProEdition())
+ return e.enforced();
+ else if ((parseKeywordIf(ctx, "DISABLE") || parseKeywordIf(ctx, "NOT ENFORCED")) && ctx.requireProEdition())
+ return e.notEnforced();
+ else return e;
}
private static final Constraint parsePrimaryKeySpecification(ParserContext ctx, ConstraintTypeStep constraint) {
parseUsingBtreeOrHashIf(ctx);
Field>[] fieldNames = parseKeyColumnList(ctx);
- Constraint e = constraint == null
+ ConstraintEnforcementStep e = constraint == null
? primaryKey(fieldNames)
: constraint.primaryKey(fieldNames);
parseUsingBtreeOrHashIf(ctx);
- parseConstraintStateIf(ctx);
- return e;
+ return parseConstraintEnforcementIf(ctx, e);
}
private static final Constraint parseUniqueSpecification(ParserContext ctx, ConstraintTypeStep constraint) {
parseUsingBtreeOrHashIf(ctx);
Field>[] fieldNames = parseKeyColumnList(ctx);
- Constraint e = constraint == null
+ ConstraintEnforcementStep e = constraint == null
? unique(fieldNames)
: constraint.unique(fieldNames);
parseUsingBtreeOrHashIf(ctx);
- parseConstraintStateIf(ctx);
- return e;
+ return parseConstraintEnforcementIf(ctx, e);
}
private static Field>[] parseKeyColumnList(ParserContext ctx) {
@@ -3754,12 +3756,11 @@ final class ParserImpl implements Parser {
Condition condition = parseCondition(ctx);
parse(ctx, ')');
- Constraint e = constraint == null
+ ConstraintEnforcementStep e = constraint == null
? check(condition)
: constraint.check(condition);
- parseConstraintStateIf(ctx);
- return e;
+ return parseConstraintEnforcementIf(ctx, e);
}
private static final Constraint parseForeignKeySpecification(ParserContext ctx, ConstraintTypeStep constraint) {
@@ -3831,8 +3832,7 @@ final class ParserImpl implements Parser {
throw ctx.expected("DELETE", "UPDATE");
}
- parseConstraintStateIf(ctx);
- return e;
+ return parseConstraintEnforcementIf(ctx, e);
}
private static final Set ALTER_KEYWORDS = new HashSet<>(Arrays.asList("ADD", "ALTER", "COMMENT", "DROP", "MODIFY", "RENAME"));
@@ -3869,8 +3869,11 @@ final class ParserImpl implements Parser {
case 'A':
if (parseKeywordIf(ctx, "ADD"))
return parseAlterTableAdd(ctx, s1, tableName);
- else if (parseKeywordIf(ctx, "ALTER") && (parseKeywordIf(ctx, "COLUMN") || true))
- return parseAlterTableAlterColumn(ctx, s1);
+ else if (parseKeywordIf(ctx, "ALTER"))
+ if (parseKeywordIf(ctx, "CONSTRAINT"))
+ return parseAlterTableAlterConstraint(ctx, s1);
+ else if ((parseKeywordIf(ctx, "COLUMN") || true))
+ return parseAlterTableAlterColumn(ctx, s1);
break;
@@ -3944,8 +3947,11 @@ final class ParserImpl implements Parser {
case 'm':
case 'M':
- if (parseKeywordIf(ctx, "MODIFY") && (parseKeywordIf(ctx, "COLUMN") || true))
- return parseAlterTableAlterColumn(ctx, s1);
+ if (parseKeywordIf(ctx, "MODIFY"))
+ if (parseKeywordIf(ctx, "CONSTRAINT"))
+ return parseAlterTableAlterConstraint(ctx, s1);
+ else if ((parseKeywordIf(ctx, "COLUMN") || true))
+ return parseAlterTableAlterColumn(ctx, s1);
break;
@@ -4139,6 +4145,21 @@ final class ParserImpl implements Parser {
return s1.alter(field).set(type);
}
+ private static final DDLQuery parseAlterTableAlterConstraint(ParserContext ctx, AlterTableStep s1) {
+ ctx.requireProEdition();
+
+
+
+
+
+
+
+
+
+
+ throw ctx.expected("ENABLE", "ENFORCED", "DISABLE", "NOT ENFORCED");
+ }
+
private static final DDLQuery parseAlterType(ParserContext ctx) {
AlterTypeStep s1 = ctx.dsl.alterType(parseName(ctx));
diff --git a/jOOQ/src/main/java/org/jooq/impl/ReferenceImpl.java b/jOOQ/src/main/java/org/jooq/impl/ReferenceImpl.java
index 95c41292d6..02f1e17a5d 100644
--- a/jOOQ/src/main/java/org/jooq/impl/ReferenceImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/ReferenceImpl.java
@@ -70,11 +70,8 @@ final class ReferenceImpl extends AbstractKe
private final UniqueKey key;
-
- @SafeVarargs
-
- ReferenceImpl(UniqueKey key, Table table, String name, TableField... fields) {
- super(table, name, fields);
+ ReferenceImpl(UniqueKey key, Table table, String name, TableField[] fields, boolean enforced) {
+ super(table, name, fields, enforced);
this.key = key;
}
diff --git a/jOOQ/src/main/java/org/jooq/impl/UniqueKeyImpl.java b/jOOQ/src/main/java/org/jooq/impl/UniqueKeyImpl.java
index f19b5f61bb..5408268c23 100644
--- a/jOOQ/src/main/java/org/jooq/impl/UniqueKeyImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/UniqueKeyImpl.java
@@ -60,18 +60,12 @@ final class UniqueKeyImpl extends AbstractKey implements Un
final List> references;
-
- @SafeVarargs
-
- UniqueKeyImpl(Table table, TableField... fields) {
- this(table, null, fields);
+ UniqueKeyImpl(Table table, TableField[] fields, boolean enforced) {
+ this(table, null, fields, enforced);
}
-
- @SafeVarargs
-
- UniqueKeyImpl(Table table, String name, TableField... fields) {
- super(table, name, fields);
+ UniqueKeyImpl(Table table, String name, TableField[] fields, boolean enforced) {
+ super(table, name, fields, enforced);
this.references = new ArrayList<>();
}