You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by da...@apache.org on 2013/12/11 12:47:32 UTC

svn commit: r1550113 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/jdbc/metadata.properties testing/org/apache/derbyTesting/functionTests/tests/lang/ConstraintCharacteristicsTest.java

Author: dag
Date: Wed Dec 11 11:47:32 2013
New Revision: 1550113

URL: http://svn.apache.org/r1550113
Log:
DERBY-532 Support deferrable constraints

A patch ("derby-532-fix-metadata-1") that fixes broken database
metadata for deferred constraint indexes: the metadata query used the
method IndexDescriptor#isUnique to determine logical uniqueness, but
it really represents physical uniqueness now. For deferred unique
constraints, the method that should be used is
"isUniqueDeferrable". Added a test, and also added client/server run
of the regression test for deferred constraints.

Before the fix, the added test fixture "testDatabaseMetaData" failed
in that the index in question was identified as non unique, but it is
logically unique and so should be reported as such.


Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/metadata.properties
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ConstraintCharacteristicsTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/metadata.properties
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/metadata.properties?rev=1550113&r1=1550112&r2=1550113&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/metadata.properties (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/metadata.properties Wed Dec 11 11:47:32 2013
@@ -835,7 +835,7 @@ getTypeInfo=\
 # parameter 5 = approximate information allowed if TRUE
 getIndexInfo=\
 	SELECT CAST ('' AS VARCHAR(128)) AS TABLE_CAT, S.SCHEMANAME AS TABLE_SCHEM, T.TABLENAME AS TABLE_NAME, \
-		   (CASE WHEN CONGLOMS.DESCRIPTOR.isUnique() THEN FALSE ELSE TRUE END) AS NON_UNIQUE, \
+           (CASE WHEN CONGLOMS.DESCRIPTOR.isUnique() OR CONGLOMS.DESCRIPTOR.isUniqueDeferrable() THEN FALSE ELSE TRUE END) AS NON_UNIQUE, \
 		   CAST ('' AS VARCHAR(128)) AS INDEX_QUALIFIER, \
 		   CONGLOMS.CONGLOMERATENAME AS INDEX_NAME, \
 		   java.sql.DatabaseMetaData::tableIndexOther AS TYPE, \
@@ -857,7 +857,7 @@ getIndexInfo=\
 				CONGLOMS.DESCRIPTOR.getKeyColumnPosition(COLS.COLUMNNUMBER) ELSE \
 				0 END) <> 0  \
 	  AND ((1=1) OR ? IS NOT NULL) AND S.SCHEMANAME LIKE ? AND T.TABLENAME=? \
-	  AND ( CASE WHEN ? THEN CONGLOMS.DESCRIPTOR.isUnique() ELSE (1=1) END) AND ((1=1) OR ?<>0) \
+      AND ( CASE WHEN ? THEN (CONGLOMS.DESCRIPTOR.isUnique() OR CONGLOMS.DESCRIPTOR.isUniqueDeferrable()) ELSE (1=1) END) AND ((1=1) OR ?<>0) \
 	ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION
 
 ############################################
@@ -1024,7 +1024,7 @@ getBestRowIdentifierUniqueIndex=\
 	FROM SYS.SYSSCHEMAS SCHEMAS, SYS.SYSTABLES TABS, SYS.SYSCONGLOMERATES IDX \
 	WHERE SCHEMAS.SCHEMAID = TABS.SCHEMAID and not IDX.ISCONSTRAINT \
 		AND TABS.TABLEID = IDX.TABLEID  \
-		AND (CASE WHEN IDX.DESCRIPTOR IS NULL THEN (1=0) ELSE IDX.DESCRIPTOR.isUnique() END)  \
+        AND (CASE WHEN IDX.DESCRIPTOR IS NULL THEN (1=0) ELSE (IDX.DESCRIPTOR.isUnique() OR IDX.DESCRIPTOR.isUniqueDeferrable()) END)  \
 		AND ((1=1) OR ? IS NOT NULL) \
 		AND (SCHEMAS.SCHEMANAME LIKE ?) \
 		AND (TABS.TABLENAME=?) \

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ConstraintCharacteristicsTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ConstraintCharacteristicsTest.java?rev=1550113&r1=1550112&r2=1550113&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ConstraintCharacteristicsTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ConstraintCharacteristicsTest.java Wed Dec 11 11:47:32 2013
@@ -22,6 +22,7 @@
 package org.apache.derbyTesting.functionTests.tests.lang;
 
 import java.sql.Connection;
+import java.sql.DatabaseMetaData;
 import java.sql.DriverManager;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
@@ -46,10 +47,12 @@ import org.apache.derby.iapi.sql.conn.La
 import org.apache.derby.impl.jdbc.EmbedConnection;
 import org.apache.derby.impl.sql.GenericPreparedStatement;
 import org.apache.derbyTesting.junit.BaseJDBCTestCase;
+import org.apache.derbyTesting.junit.CleanDatabaseTestSetup;
 import org.apache.derbyTesting.junit.J2EEDataSource;
 import org.apache.derbyTesting.junit.JDBC;
 import org.apache.derbyTesting.junit.SupportFilesSetup;
 import org.apache.derbyTesting.junit.SystemPropertyTestSetup;
+import org.apache.derbyTesting.junit.TestConfiguration;
 import org.apache.derbyTesting.junit.XATestUtil;
 
 public class ConstraintCharacteristicsTest extends BaseJDBCTestCase
@@ -62,14 +65,25 @@ public class ConstraintCharacteristicsTe
                                            // import/export
     static String expImpDataWithNullsFile; // file used to perform
                                            // import/export
-    static boolean exportFilesCreated = false;
+    static boolean exportFilesCreatedEmbedded = false;
+    static boolean exportFilesCreatedClient = false;
 
     public ConstraintCharacteristicsTest(String name) {
         super(name);
     }
 
+
     public static Test suite() {
-        TestSuite suite = new TestSuite("ConstraintCharacteristicsTest");
+        String nameRoot = "ConstraintCharacteristicsTest";
+        TestSuite suite = new TestSuite(nameRoot);
+        suite.addTest(baseSuite(nameRoot + ":embedded"));
+        suite.addTest(TestConfiguration.clientServerDecorator(
+                baseSuite(nameRoot + ":client")));
+        return suite;
+    }
+
+    private static Test baseSuite(String name) {
+        TestSuite suite = new TestSuite(name);
         suite.addTest(new ConstraintCharacteristicsTest(
                           "testSyntaxAndBinding"));
 
@@ -77,12 +91,14 @@ public class ConstraintCharacteristicsTe
         // feature completed: remove then
         Properties systemProperties = new Properties();
         systemProperties.setProperty("derby.constraintsTesting", "true");
-
+        systemProperties.setProperty("derby.locks.waitTimeout", "2");
         TestSuite s = new TestSuite("WithLenientChecking");
 
        s.addTest(new ConstraintCharacteristicsTest(
            "testLocking"));
        s.addTest(new ConstraintCharacteristicsTest(
+           "testDatabaseMetaData"));
+       s.addTest(new ConstraintCharacteristicsTest(
            "testCreateConstraintDictionaryEncodings"));
        s.addTest(new ConstraintCharacteristicsTest(
            "testAlterConstraintDictionaryEncodings"));
@@ -116,12 +132,19 @@ public class ConstraintCharacteristicsTe
         createStatement().
                 executeUpdate("create table referenced(i int primary key)");
 
-        if (!exportFilesCreated) {
+        if ((usingEmbedded() && !exportFilesCreatedEmbedded) ||
+            (usingDerbyNetClient() && !exportFilesCreatedClient)) {
+
+            // We have to do this once for embedded and once for client/server
+            if (usingEmbedded()) {
+                exportFilesCreatedEmbedded = true;
+            } else {
+                exportFilesCreatedClient = true;
+            }
 
             // Create a file for import that contains duplicate rows,
             // see testImport and testDerby6374.
             //
-            exportFilesCreated = true;
             expImpDataFile =
                 SupportFilesSetup.getReadWrite("t.data").getPath();
             expImpDataWithNullsFile =
@@ -289,6 +312,11 @@ public class ConstraintCharacteristicsTe
      * @throws SQLException
      */
     public void testAlterConstraintInvalidation() throws SQLException {
+        if (usingDerbyNetClient()) {
+            // Skip, since we need to see inside an embedded connection here
+            return;
+        }
+
         Connection c = getConnection();
         Statement s = c.createStatement();
 
@@ -332,6 +360,24 @@ public class ConstraintCharacteristicsTe
             "set constraints all",
             "set constraints c"};
 
+
+    public void testDatabaseMetaData() throws SQLException {
+        //
+        // Test that our index is still reported as unique even if we implement
+        // it as physically non-unique when deferrable: logically it is still a
+        // unique index.
+        Statement s = createStatement();
+        s.executeUpdate(
+            "create table t(i int not null " +
+            "    constraint c primary key deferrable initially immediate)");
+        DatabaseMetaData dbmd = s.getConnection().getMetaData();
+        ResultSet rs = dbmd.getIndexInfo(null, null, "T", false, false);
+        rs.next();
+        assertEquals("false", rs.getString("NON_UNIQUE"));
+    }
+
+
+
     public void testLocking() throws SQLException {
         Statement s = createStatement();
         s.executeUpdate(
@@ -373,6 +419,9 @@ public class ConstraintCharacteristicsTe
                 assertSQLState(LOCK_TIMEOUT, e);
             }
         } finally {
+            if (usingDerbyNetClient()) {
+                c2.rollback();
+            }
             c2.close();
         }
         commit();
@@ -913,11 +962,15 @@ public class ConstraintCharacteristicsTe
                 fail("Expected XA prepare to fail due to constraint violation");
             } catch (XAException xe) {
                 assertEquals(xe.errorCode, XAException.XA_RBINTEGRITY);
-                Throwable t = xe.getCause();
-                assertTrue(t != null && t instanceof SQLException);
-                assertSQLState(
-                        LANG_DEFERRED_CONSTRAINTS_VIOLATION,
-                        (SQLException)t);
+
+                if (!usingDerbyNetClient()) {
+                    Throwable t = xe.getCause();
+                    assertTrue(t != null && t instanceof SQLException);
+                    assertSQLState(
+                            LANG_DEFERRED_CONSTRAINTS_VIOLATION,
+                            (SQLException)t);
+                }
+
                 assertXidRolledBack(xar, xid);
             }
 
@@ -932,15 +985,22 @@ public class ConstraintCharacteristicsTe
                 fail("Expected XA commit to fail due to constraint violation");
             } catch (XAException xe) {
                 assertEquals(xe.errorCode, XAException.XA_RBINTEGRITY);
-                Throwable t = xe.getCause();
-                assertTrue(t != null && t instanceof SQLException);
-                assertSQLState(
-                        LANG_DEFERRED_CONSTRAINTS_VIOLATION,
-                        (SQLException)t);
+
+                if (!usingDerbyNetClient()) {
+                    Throwable t = xe.getCause();
+                    assertTrue(t != null && t instanceof SQLException);
+                    assertSQLState(
+                            LANG_DEFERRED_CONSTRAINTS_VIOLATION,
+                            (SQLException)t);
+                }
+
                 assertXidRolledBack(xar, xid);
             }
 
         } finally {
+            if (usingDerbyNetClient()) {
+                xaconn.getConnection().rollback();
+            }
             xaconn.close();
         }
     }