From dfe3abe20023b94df8004b4e025e9991a83ee264 Mon Sep 17 00:00:00 2001 From: Thomas Mueller <thomasmueller@users.noreply.github.com> Date: Mon, 20 Oct 2008 20:34:32 +0000 Subject: [PATCH] Self referencing constraints didn't restrict deleting rows that reference itself if there is another row that references it. --- .../h2/constraint/ConstraintReferential.java | 28 ++++--------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/h2/src/main/org/h2/constraint/ConstraintReferential.java b/h2/src/main/org/h2/constraint/ConstraintReferential.java index 748d704c0..3a47be219 100644 --- a/h2/src/main/org/h2/constraint/ConstraintReferential.java +++ b/h2/src/main/org/h2/constraint/ConstraintReferential.java @@ -343,18 +343,21 @@ public class ConstraintReferential extends Constraint { int refIdx = refCol.getColumnId(); 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, 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); Cursor cursor = index.find(session, check, check); while (cursor.next()) { SearchRow found; found = cursor.getSearchRow(); + if (excluding != null && found.getPos() == excluding.getPos()) { + continue; + } Column[] cols = index.getColumns(); boolean allEqual = true; for (int i = 0; i < columns.length && i < cols.length; i++) { @@ -378,25 +381,6 @@ public class ConstraintReferential extends Constraint { } 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); for (int i = 0; i < columns.length; i++) { Column refCol = refColumns[i].column; @@ -406,7 +390,7 @@ public class ConstraintReferential extends Constraint { Value v = oldRow.getValue(refIdx).convertTo(col.getType()); 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, getShortDescription()); } -- 2.18.1