[jOOQ/jOOQ#8528] Interpret DROP COLUMN CASCADE | RESTRICT

This commit is contained in:
Lukas Eder 2019-10-16 11:59:57 +02:00
parent ff6b6dd204
commit f864009ff0
2 changed files with 55 additions and 27 deletions

View File

@ -292,7 +292,8 @@ final class AlterTableImpl extends AbstractRowCountQuery implements
final Field<?> $renameColumnTo() { return renameColumnTo; }
final Constraint $renameConstraint() { return renameConstraint; }
final Constraint $renameConstraintTo() { return renameConstraintTo; }
final List<Field<?>> $dropColumns() { return dropColumns; };
final List<Field<?>> $dropColumns() { return dropColumns; }
final boolean $dropColumnsCascade() { return dropColumnCascade; }
final Constraint $dropConstraint() { return dropConstraint; }
final ConstraintType $dropConstraintType() { return dropConstraintType; }

View File

@ -269,9 +269,24 @@ final class DDLInterpreter {
));
}
private final void dropColumns(MutableTable table, List<MutableField> fields) {
private final void dropColumns(MutableTable table, List<MutableField> fields, boolean cascade) {
Iterator<MutableIndex> it1 = table.indexes.iterator();
for (boolean check : cascade ? new boolean [] { false } : new boolean [] { true, false }) {
if (table.primaryKey != null) {
if (intersect(table.primaryKey.keyFields, fields)) {
cascade(table.primaryKey, fields, !check);
if (!check)
table.primaryKey = null;
}
}
dropColumnsCascadeLocalConstraints(table.uniqueKeys, fields, check);
}
dropColumnsCascadeLocalConstraints(table.foreignkeys, fields, false);
indexLoop:
while (it1.hasNext()) {
for (MutableSortField msf : it1.next().fields) {
@ -282,33 +297,45 @@ final class DDLInterpreter {
}
}
if (table.primaryKey != null)
if (intersect(table.primaryKey.keyFields, fields))
table.primaryKey = null;
Iterator<MutableUniqueKey> it2 = table.uniqueKeys.iterator();
ukLoop:
while (it2.hasNext()) {
if (intersect(it2.next().keyFields, fields)) {
it2.remove();
continue ukLoop;
}
}
Iterator<MutableForeignKey> it3 = table.foreignkeys.iterator();
fkLoop:
while (it3.hasNext()) {
if (intersect(it3.next().keyFields, fields)) {
it3.remove();
continue fkLoop;
}
}
// Actual removal
table.fields.removeAll(fields);
}
private final void dropColumnsCascadeLocalConstraints(List<? extends MutableKey> keys, List<MutableField> fields, boolean check) {
Iterator<? extends MutableKey> it2 = keys.iterator();
while (it2.hasNext()) {
MutableKey key = it2.next();
if (intersect(key.keyFields, fields)) {
if (key instanceof MutableUniqueKey)
cascade((MutableUniqueKey) key, fields, !check);
if (!check)
it2.remove();
}
}
}
private final void cascade(MutableUniqueKey key, List<MutableField> fields, boolean cascade) {
for (MutableTable mt : tables()) {
Iterator<MutableForeignKey> it = mt.foreignkeys.iterator();
while (it.hasNext()) {
MutableForeignKey mfk = it.next();
if (mfk.referencedKey.equals(key)) {
if (cascade)
it.remove();
else if (fields.size() == 1)
throw new DataDefinitionException("Cannot drop column " + fields.get(0) + " because other objects depend on it");
else
throw new DataDefinitionException("Cannot drop columns " + fields + " because other objects depend on them");
}
}
}
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private final void accept0(AlterTableImpl query) {
Table<?> table = query.$table();
@ -423,7 +450,7 @@ final class DDLInterpreter {
if (fields.size() < dropColumns.size() && !query.$ifExistsColumn())
existing.fields(dropColumns.toArray(EMPTY_FIELD), true);
dropColumns(existing, fields);
dropColumns(existing, fields, query.$dropColumnsCascade());
}
else if (dropConstraint != null) {
ConstraintImpl impl = (ConstraintImpl) dropConstraint;