Unverified 提交 fb5b206f authored 作者: Noel Grandin's avatar Noel Grandin 提交者: GitHub

Merge pull request #1092 from grandinj/230_fkconstraint

#230: Renaming a column does not update foreign key  constraint
......@@ -21,6 +21,8 @@ Change Log
<h2>Next Version (unreleased)</h2>
<ul>
<li>Issue #230: Renaming a column does not update foreign key constraint
</li>
<li>Issue #394: Recover tool places COLLATION and BINARY_COLLATION after temporary tables
</li>
<li>Improve the script-based unit testing to check the error code of the exception thrown.
......
......@@ -7,6 +7,7 @@ package org.h2.command.ddl;
import org.h2.api.ErrorCode;
import org.h2.command.CommandInterface;
import org.h2.constraint.ConstraintReferential;
import org.h2.engine.Database;
import org.h2.engine.DbObject;
import org.h2.engine.Right;
......@@ -62,6 +63,7 @@ public class AlterTableRenameColumn extends SchemaCommand {
Column column = table.getColumn(oldName);
session.getUser().checkRight(table, Right.ALL);
table.checkSupportAlter();
// we need to update CHECK constraint
// since it might reference the name of the column
Expression newCheckExpr = column.getCheckConstraint(session, newName);
......@@ -70,6 +72,15 @@ public class AlterTableRenameColumn extends SchemaCommand {
column.addCheckConstraint(session, newCheckExpr);
table.setModified();
db.updateMeta(session, table);
// if we have foreign key constraints pointing at this table, we need to update them
for (DbObject childDbObject : table.getChildren()) {
if (childDbObject instanceof ConstraintReferential) {
ConstraintReferential ref = (ConstraintReferential) childDbObject;
ref.updateOnTableColumnRename();
}
}
for (DbObject child : table.getChildren()) {
if (child.getCreateSQL() != null) {
db.updateMeta(session, child);
......
......@@ -470,6 +470,17 @@ public class ConstraintReferential extends Constraint {
buildDeleteSQL();
}
public void updateOnTableColumnRename() {
if (deleteAction != null) {
deleteSQL = null;
buildDeleteSQL();
}
if (updateAction != null) {
updateSQL = null;
buildUpdateSQL();
}
}
private void buildDeleteSQL() {
if (deleteAction == ConstraintActionType.RESTRICT) {
return;
......
......@@ -85,6 +85,7 @@ public abstract class Table extends SchemaObjectBase {
*/
private final CopyOnWriteArrayList<TableView> dependentViews = new CopyOnWriteArrayList<>();
private ArrayList<TableSynonym> synonyms;
/** Is foreign key constraint checking enabled for this table. */
private boolean checkForeignKeyConstraints = true;
private boolean onCommitDrop, onCommitTruncate;
private volatile Row nullRow;
......@@ -1065,6 +1066,9 @@ public abstract class Table extends SchemaObjectBase {
checkForeignKeyConstraints = enabled;
}
/**
* @return is foreign key constraint checking enabled for this table.
*/
public boolean getCheckForeignKeyConstraints() {
return checkForeignKeyConstraints;
}
......
......@@ -92,6 +92,7 @@ public class TestScript extends TestBase {
testScript("joins.sql");
testScript("range_table.sql");
testScript("altertable-index-reuse.sql");
testScript("altertable-fk.sql");
testScript("default-and-on_update.sql");
testScript("query-optimisations.sql");
String decimal2;
......
-- Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
-- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group
--
-- Check that constraints are properly renamed when we rename a column.
CREATE TABLE user_group (ID decimal PRIMARY KEY NOT NULL);
> ok
CREATE TABLE login_message (ID decimal PRIMARY KEY NOT NULL, user_group_id decimal);
> ok
ALTER TABLE login_message ADD CONSTRAINT FK_LOGIN_MESSAGE
FOREIGN KEY (user_group_id)
REFERENCES user_group(id) ON DELETE CASCADE;
> ok
ALTER TABLE login_message ALTER COLUMN user_group_id RENAME TO user_group_id2;
> ok
INSERT INTO user_group (ID) VALUES (1);
> update count: 1
DELETE FROM user_group;
> update count: 1
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论