提交 dfe3abe2 authored 作者: Thomas Mueller's avatar Thomas Mueller

Self referencing constraints didn't restrict deleting rows that reference itself…

Self referencing constraints didn't restrict deleting rows that reference itself if there is another row that references it.
上级 cc238bdc
...@@ -343,18 +343,21 @@ public class ConstraintReferential extends Constraint { ...@@ -343,18 +343,21 @@ public class ConstraintReferential extends Constraint {
int refIdx = refCol.getColumnId(); int refIdx = refCol.getColumnId();
check.setValue(refIdx, v.convertTo(refCol.getType())); check.setValue(refIdx, v.convertTo(refCol.getType()));
} }
if (!found(session, refIndex, check)) { if (!found(session, refIndex, check, null)) {
throw Message.getSQLException(ErrorCode.REFERENTIAL_INTEGRITY_VIOLATED_PARENT_MISSING_1, throw Message.getSQLException(ErrorCode.REFERENTIAL_INTEGRITY_VIOLATED_PARENT_MISSING_1,
getShortDescription()); getShortDescription());
} }
} }
private boolean found(Session session, Index index, SearchRow check) throws SQLException { private boolean found(Session session, Index index, SearchRow check, Row excluding) throws SQLException {
index.getTable().lock(session, false, false); index.getTable().lock(session, false, false);
Cursor cursor = index.find(session, check, check); Cursor cursor = index.find(session, check, check);
while (cursor.next()) { while (cursor.next()) {
SearchRow found; SearchRow found;
found = cursor.getSearchRow(); found = cursor.getSearchRow();
if (excluding != null && found.getPos() == excluding.getPos()) {
continue;
}
Column[] cols = index.getColumns(); Column[] cols = index.getColumns();
boolean allEqual = true; boolean allEqual = true;
for (int i = 0; i < columns.length && i < cols.length; i++) { for (int i = 0; i < columns.length && i < cols.length; i++) {
...@@ -378,25 +381,6 @@ public class ConstraintReferential extends Constraint { ...@@ -378,25 +381,6 @@ public class ConstraintReferential extends Constraint {
} }
private void checkRow(Session session, Row oldRow) throws SQLException { private void checkRow(Session session, Row oldRow) throws SQLException {
if (refTable == table) {
// special case self referencing constraints: check the deleted row
// first
boolean self = true;
for (int i = 0; i < columns.length; i++) {
Column refCol = refColumns[i].column;
int refIdx = refCol.getColumnId();
Value v = oldRow.getValue(refIdx);
int idx = columns[i].column.getColumnId();
Value r = oldRow.getValue(idx);
if (!database.areEqual(r, v)) {
self = false;
break;
}
}
if (self) {
return;
}
}
SearchRow check = table.getTemplateSimpleRow(false); SearchRow check = table.getTemplateSimpleRow(false);
for (int i = 0; i < columns.length; i++) { for (int i = 0; i < columns.length; i++) {
Column refCol = refColumns[i].column; Column refCol = refColumns[i].column;
...@@ -406,7 +390,7 @@ public class ConstraintReferential extends Constraint { ...@@ -406,7 +390,7 @@ public class ConstraintReferential extends Constraint {
Value v = oldRow.getValue(refIdx).convertTo(col.getType()); Value v = oldRow.getValue(refIdx).convertTo(col.getType());
check.setValue(idx, v); check.setValue(idx, v);
} }
if (found(session, index, check)) { if (found(session, index, check, oldRow)) {
throw Message.getSQLException(ErrorCode.REFERENTIAL_INTEGRITY_VIOLATED_CHILD_EXISTS_1, throw Message.getSQLException(ErrorCode.REFERENTIAL_INTEGRITY_VIOLATED_CHILD_EXISTS_1,
getShortDescription()); getShortDescription());
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论