db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kahat...@apache.org
Subject svn commit: r744984 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/store/access/btree/BTreeController.java testing/org/apache/derbyTesting/functionTests/tests/lang/NullableUniqueConstraintTest.java
Date Tue, 17 Feb 2009 12:05:13 GMT
Author: kahatlen
Date: Tue Feb 17 12:05:13 2009
New Revision: 744984

URL: http://svn.apache.org/viewvc?rev=744984&view=rev
Log:
DERBY-4027: An attempt was made to access an out of range slot on a page

When a new value is inserted into an index backing a nullable unique
constraint, a check is performed to verify that the adjacent slots do
not contain the same value as the one being inserted. This extra check
is needed because the index backing such a constraint is not unique
(it allows multiple NULL values).

If the spot on which the new value is inserted is at the beginning or
the end of the index page, the last value of the previous page or the
first value of the next page is checked. Currently, the code attempts
to read that value right after the slot pointer has been moved to that
page. This was the cause of the bug, as that page may be empty, and
any pointer to a slot on an empty page is pointing to a non-existent
slot, hence the out-of-range-slot error.

This patch fixes the bug by checking again after moving to another
page that we are attempting to read a valid row. If not, we skip to
the next (or previous, depending on the direction of the traversal)
index page in the chain and look for a duplicate there.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/BTreeController.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NullableUniqueConstraintTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/BTreeController.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/BTreeController.java?rev=744984&r1=744983&r2=744984&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/BTreeController.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/btree/BTreeController.java
Tue Feb 17 12:05:13 2009
@@ -393,6 +393,11 @@
                     if (newLeaf)
                         oldLeaf.release();
                     newLeaf = true;
+                    // DERBY-4027: We have moved to the previous page and need
+                    // to recheck that the slot number is valid (it won't be
+                    // if the page we moved to is empty). Restart from the top
+                    // of the loop body to get the slot number rechecked.
+                    continue;
                 } catch (WaitError we) {
                     throw StandardException.plainWrapException(we);
                 }
@@ -451,6 +456,11 @@
                     return NO_MATCH;
                 //point slot to the first record of new leaf
                 slot = 1;
+                // DERBY-4027: We have moved to the next page and need
+                // to recheck that the slot number is valid (it won't be
+                // if the page we moved to is empty). Restart from the top
+                // of the loop body to get the slot number rechecked.
+                continue;
             }
             rh = leaf.page.fetchFromSlot(null, slot, rows, null, true);
             if (rh != null) {

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NullableUniqueConstraintTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NullableUniqueConstraintTest.java?rev=744984&r1=744983&r2=744984&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NullableUniqueConstraintTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NullableUniqueConstraintTest.java
Tue Feb 17 12:05:13 2009
@@ -456,6 +456,33 @@
                 stmt.executeUpdate("update constraintest set " +
                 "val1 = val2, val2 = val1"));
     }
+
+    /**
+     * Test that repeatedly performing multi-row inserts and deletes spanning
+     * multiple pages works correctly with nullable unique constraint. This
+     * used to cause <tt>ERROR XSDA1: An attempt was made to access an out of
+     * range slot on a page</tt> (DERBY-4027).
+     */
+    public void testMixedInsertDelete() throws SQLException {
+        createStatement().execute(
+                "alter table constraintest add constraint uc unique (val1)");
+        PreparedStatement insert = prepareStatement(
+                "insert into constraintest(val1) values ?");
+        PreparedStatement delete = prepareStatement(
+                "delete from constraintest");
+        // The error happened most frequently in the second iteration, but
+        // it didn't always, so we repeat it ten times to increase the
+        // likelihood of triggering the bug.
+        for (int i = 0; i < 10; i++) {
+            for (int j = 0; j < 1000; j++) {
+                insert.setInt(1, j);
+                insert.addBatch();
+            }
+            insert.executeBatch();
+            assertEquals(1000, delete.executeUpdate());
+        }
+    }
+
     public static void main(String [] args) {
         TestResult tr = new TestResult();
         Test t = suite();



Mime
View raw message