db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d..@apache.org
Subject svn commit: r1614777 [1/2] - in /db/derby/code/trunk/java: engine/org/apache/derby/catalog/ engine/org/apache/derby/iapi/sql/conn/ engine/org/apache/derby/iapi/sql/dictionary/ engine/org/apache/derby/iapi/sql/execute/ engine/org/apache/derby/impl/sql/c...
Date Wed, 30 Jul 2014 21:51:55 GMT
Author: dag
Date: Wed Jul 30 21:51:54 2014
New Revision: 1614777

URL: http://svn.apache.org/r1614777
Log:
DERBY-6670 Rollback to savepoint allows violation of deferrable constraints

Patch derby-6670-2-c. This patch is a rewrite of the prototype patch
derby-6665-01-ae-deferredCheckAndDroppedFK.diff which moves from using
physical conglomerate ids as keys in the internal identification of
constraints and their indexes for deferrable constraints to

- UUID for the constraints for primary key, unique and foreign key
- UUID for base table (or constraint dependening on where in the code)
  for check constraints

This is essentially only a refactoring which simplifies the code. But
it also makes possible the fix for this issue, which is to stop
removing the deferrable constraint violation information when
constraints are dropped (directory or as a result of the table being
dropped), since a rollback to savepoint might undo drops, at which
point we need the violation information again. The solution is to make
the validation code robust against the absence of dictionary objects
(tables, constraints): if at commit or "set immediate", the objects
are gone we know there is no checking to be done.

The patch also adds rollback to savepoint test cases in
ConstraintCharacteristicsTest#testDerby6670_a, including the repro for
this issue.

Also removed the release of violation information at a successful
change to immediate constraint mode as part of a SET CONSTRAINTS
statement, since a rollback to savepoint might re-introduce the
violations. New test cases added for this, too (#testDerby6670_b).

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/catalog/UUID.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/SQLSessionContext.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/ConstraintDescriptor.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ResultSetFactory.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/FromBaseTable.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ProjectRestrictNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/SQLSessionContextImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstraintConstantAction.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateConstraintConstantAction.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateIndexConstantAction.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DeferredConstraintsMemory.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/FKInfo.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ForeignKeyRIChecker.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericResultSetFactory.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexChanger.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexConstantAction.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ProjectRestrictResultSet.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RIBulkChecker.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ReferencedKeyRIChecker.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/SetConstraintsConstantAction.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UniqueIndexSortObserver.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UniqueWithDuplicateNullsIndexSortObserver.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateResultSet.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ValidateCheckConstraintResultSet.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ConstraintCharacteristicsTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/catalog/UUID.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/catalog/UUID.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/catalog/UUID.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/catalog/UUID.java Wed Jul 30 21:51:54 2014
@@ -35,6 +35,9 @@ package org.apache.derby.catalog;
 
 public interface UUID extends java.io.Externalizable
 {
+    /** NULL UUID */
+    static  final   String  NULL = "NULL";
+
 	/**
 	  UUID_BYTE_LENGTH
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java Wed Jul 30 21:51:54 2014
@@ -38,6 +38,7 @@ import org.apache.derby.iapi.sql.compile
 import org.apache.derby.iapi.sql.compile.OptTrace;
 import org.apache.derby.iapi.sql.compile.OptimizerFactory;
 import org.apache.derby.iapi.sql.depend.Provider;
+import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor;
 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
@@ -1275,53 +1276,20 @@ public interface LanguageConnectionConte
                                        FormatableBitSet map);
 
     /**
-     * Set the constraint mode for this primary key or unique constraint to
-     * {@code deferred}.
+     * Set the constraint mode for this constraint to {@code deferred}.
      * If {@code deferred} is {@code false}, to immediate checking,
      * if {@code true} to deferred checking.
      *
      * @param a         Activation
-     * @param conglomId The conglomerate id of the backing index for the
-     *                  constraint .
+     * @param cd        The descriptor of the constraint
      * @param deferred  The new constraint mode
      * @throws StandardException
      */
     public void setConstraintDeferred(Activation a,
-                                    long conglomId,
+                                    ConstraintDescriptor cd,
                                     boolean deferred) throws StandardException;
 
     /**
-     * Set the constraint mode for this check constraint to {@code deferred}.
-     * If {@code deferred} is {@code false}, to immediate checking,
-     * if {@code true} to deferred checking.
-     *
-     * @param a         Activation
-     * @param baseTableCID conglomerate id of constraint's base table
-     * @param constraintId The constraint id
-     * @param deferred  The new constraint mode
-     * @throws StandardException
-     */
-    public void setConstraintDeferred(Activation a,
-                                 long baseTableCID,
-                                 UUID constraintId,
-                                 boolean deferred) throws StandardException;
-
-
-    /**
-     * Determines if a unique or primary key constraint currently has deferred
-     * mode.
-     *
-     * @param sc       The session context for which we are asking the status
-     * @param indexCID The conglomerate id of the supporting index of the
-     *                 constraint.
-     * @return         {@code true} if the constraint is deferred
-     * @throws StandardException
-     *                 Standard error policy
-     */
-    public boolean isEffectivelyDeferred(SQLSessionContext sc, long indexCID)
-            throws StandardException;
-
-    /**
      * Determines if a check or foreign key constraint has deferred
      * mode.
      *
@@ -1355,7 +1323,7 @@ public interface LanguageConnectionConte
      * constraints.
      * @return the set
      */
-    HashMap<Long, DeferredConstraintsMemory.ValidationInfo>
+    HashMap<UUID, DeferredConstraintsMemory.ValidationInfo>
         getDeferredHashTables();
 
     /**
@@ -1367,17 +1335,6 @@ public interface LanguageConnectionConte
     public void checkIntegrity() throws StandardException;
 
     /**
-     * Forget any violating rows for the deferred constraint associated
-     * by conglomId,
-     * @param conglomId The conglomerate identifier of the backing
-     *        index, or a base table conglomerate id of it is a CHECK
-     *        constraint.
-     * @throws StandardException
-     */
-    public void forgetDeferredConstraintsData(long conglomId)
-            throws StandardException;
-
-    /**
      * Get the SQL session context of the given activation.
      * @param activation The activation
      * @return           The SQL session object

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/SQLSessionContext.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/SQLSessionContext.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/SQLSessionContext.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/SQLSessionContext.java Wed Jul 30 21:51:54 2014
@@ -105,39 +105,14 @@ public interface SQLSessionContext {
      * The caller is responsible for any cloning needed.
      * @return constraint modes map
      */
-    public HashMap<Long, Boolean> getUniquePKConstraintModes();
-
-    /**
-     * Get a handle to the session's check constraint modes.
-     * The caller is responsible for any cloning needed.
-     * @return constraint modes map
-     */
-    public HashMap<UUID, Boolean> getCheckConstraintModes();
+    public HashMap<UUID, Boolean> getConstraintModes();
 
     /**
      * Initialize a inferior session context with the constraint mode map
      * of the parent session context.
      * @param hm constraint mode map
      */
-    public void setConstraintModes(HashMap<Long, Boolean> hm);
-
-    /**
-     * Initialize a inferior session context with the check constraint mode map
-     * of the parent session context.
-     * @param hm constraint mode map
-     */
-    public void setCheckConstraintModes(HashMap<UUID, Boolean> hm);
-
-    /**
-     * Set the constraint mode for this constraint/index to {@code deferred}.
-     * If {@code deferred} is {@code false}, to immediate checking,
-     * if {@code true} to deferred checking.
-     *
-     * @param conglomId The conglomerate id of the backing index for the
-     *                  constraint .
-     * @param deferred  The new constraint mode
-     */
-    public void setDeferred(long conglomId, boolean deferred);
+    public void setConstraintModes(HashMap<UUID, Boolean> hm);
 
     /**
      * Set the constraint mode for this constraint to {@code deferred}.
@@ -156,16 +131,6 @@ public interface SQLSessionContext {
      * If the constraint mode hasn't been set for this constraint,
      * return {@code null}. The constraint mode is the effectively the initial
      * constraint mode in this case.
-     */
-    public Boolean isDeferred(long conglomId);
-
-    /**
-     * Return {@code Boolean.TRUE} if the constraint mode for this
-     * constraint/index has been set to deferred, {@code Boolean.FALSE} if
-     * it has been set to immediate.  Any ALL setting is considered also.
-     * If the constraint mode hasn't been set for this constraint,
-     * return {@code null}. The constraint mode is the effectively the initial
-     * constraint mode in this case.
      *
      * @param constraintId the constraint id
      * @return {@code Boolean.TRUE} if the constraint mode for this

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/ConstraintDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/ConstraintDescriptor.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/ConstraintDescriptor.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/ConstraintDescriptor.java Wed Jul 30 21:51:54 2014
@@ -735,15 +735,10 @@ public abstract class ConstraintDescript
             // information since they point to the same physical index.
             for (ConglomerateDescriptor cd : conglomDescs) {
                 if (cd.isConstraint()) {
-                    lcc.forgetDeferredConstraintsData(
-                            cd.getConglomerateNumber());
                     newBackingConglomCD = cd.drop(lcc, table);
                     break;
                 }
             }
-        } else {
-            lcc.forgetDeferredConstraintsData(
-                    getTableDescriptor().getHeapConglomerateId());
         }
 
         table.removeConstraintDescriptor(this);

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ResultSetFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ResultSetFactory.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ResultSetFactory.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ResultSetFactory.java Wed Jul 30 21:51:54 2014
@@ -319,7 +319,7 @@ public interface ResultSetFactory {
 		@param doesProjection	Whether or not this PRN does a projection
         @param validatingCheckConstraint {@code true if this PRN is used to
             for validating a deferred check constraint}.
-        @param validatingBaseTableCID The conglomerate id for the table being
+        @param validatingBaseTableUUIDString The uuid for the table being
             validated.
 		@param optimizerEstimatedRowCount	Estimated total # of rows by
 											optimizer
@@ -337,7 +337,7 @@ public interface ResultSetFactory {
 		boolean reuseResult,
 		boolean doesProjection,
         boolean validatingCheckConstraint,
-        long validatingBaseTableCID,
+        String validatingBaseTableUUIDString,
 		double optimizerEstimatedRowCount,
 		double optimizerEstimatedCost) throws StandardException;
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/DMLModStatementNode.java Wed Jul 30 21:51:54 2014
@@ -1028,6 +1028,7 @@ abstract class DMLModStatementNode exten
                     pkIndexId,              // referenced backing index uuid
                     pkIndexConglom.getConglomerateNumber(),
                                             // referenced backing index conglom
+                    refcd.getUUID(),
                     refcd.deferrable(),     // referenced constraint is
                                             // deferrable?
                     uuids,                  // fk backing index uuids

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/FromBaseTable.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/FromBaseTable.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/FromBaseTable.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/FromBaseTable.java Wed Jul 30 21:51:54 2014
@@ -135,10 +135,10 @@ class FromBaseTable extends FromTable
 
     /*
     ** Used to validate deferred check constraints.
-    ** It is the conglomerate number of the target inserted into or updated
+    ** It is the uuid of the target table inserted into or updated
     ** when a violation was detected but deferred.
     */
-    private long            targetTableCID;
+    private String          targetTableUUIDString;
     private boolean         validatingCheckConstraint = false;
 
 	/* We may turn off bulk fetch for a variety of reasons,
@@ -875,7 +875,7 @@ class FromBaseTable extends FromTable
             String key = (String)e.nextElement();
             String value = (String) tableProperties.get(key);
             if (key.equals("validateCheckConstraint")) {
-                targetTableCID = getLongProperty(value, key);
+                targetTableUUIDString = value;
                 validatingCheckConstraint = true;
                 return true;
             }
@@ -3000,7 +3000,7 @@ class FromBaseTable extends FromTable
                         SQLState.LANG_SYNTAX_ERROR, "validateCheckConstraint");
             }
 
-            result.setValidatingCheckConstraints(targetTableCID);
+            result.setValidatingCheckConstraints(targetTableUUIDString);
         }
         return result;
 	}

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ProjectRestrictNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ProjectRestrictNode.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ProjectRestrictNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ProjectRestrictNode.java Wed Jul 30 21:51:54 2014
@@ -24,6 +24,7 @@ package	org.apache.derby.impl.sql.compil
 import java.util.HashSet;
 import java.util.Properties;
 import java.util.Set;
+import org.apache.derby.catalog.UUID;
 import org.apache.derby.catalog.types.ReferencedColumnsDescriptorImpl;
 import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.reference.ClassName;
@@ -94,7 +95,7 @@ class ProjectRestrictNode extends Single
      * constraints.
      */
     private boolean validatingCheckConstraints = false;
-    private long validatingBaseTableCID;
+    private String validatingBaseTableUUIDString;
 	/**
      * Constructor for a ProjectRestrictNode.
 	 *
@@ -1587,7 +1588,14 @@ class ProjectRestrictNode extends Single
 		mb.push(getResultColumns().reusableResult());
 		mb.push(doesProjection);
         mb.push(validatingCheckConstraints);
-        mb.push(validatingBaseTableCID);
+        if ( validatingBaseTableUUIDString == null )
+        {
+            mb.push( UUID.NULL );
+        }
+        else
+        {
+            mb.push(validatingBaseTableUUIDString);
+        }
 		mb.push(getCostEstimate().rowCount());
 		mb.push(getCostEstimate().getEstimatedCost());
 
@@ -1897,8 +1905,8 @@ class ProjectRestrictNode extends Single
         childResult.pushOffsetFetchFirst( offset, fetchFirst, hasJDBClimitClause );
     }
 
-    void setValidatingCheckConstraints(long baseTableCID) {
+    void setValidatingCheckConstraints( String baseTableUUIDString ) {
         validatingCheckConstraints = true;
-        validatingBaseTableCID = baseTableCID;
+        validatingBaseTableUUIDString = baseTableUUIDString;
     }
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java Wed Jul 30 21:51:54 2014
@@ -65,6 +65,7 @@ import org.apache.derby.iapi.sql.conn.SQ
 import org.apache.derby.iapi.sql.conn.StatementContext;
 import org.apache.derby.iapi.sql.depend.DependencyManager;
 import org.apache.derby.iapi.sql.depend.Provider;
+import org.apache.derby.iapi.sql.dictionary.CheckConstraintDescriptor;
 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptorList;
 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor;
@@ -313,7 +314,7 @@ public class GenericLanguageConnectionCo
      * saved for deferred constraints in this transaction, keyed by the
      * conglomerate id. Checked at commit time, then discarded.
      */
-    private HashMap<Long, ValidationInfo> deferredHashTables;
+    private HashMap<UUID, ValidationInfo> deferredHashTables;
 
     /*
        constructor
@@ -3748,8 +3749,7 @@ public class GenericLanguageConnectionCo
 
         final SQLSessionContext ssc = getCurrentSQLSessionContext(a);
         sc.setDeferredAll(ssc.getDeferredAll());
-        sc.setConstraintModes(ssc.getUniquePKConstraintModes());
-        sc.setCheckConstraintModes(ssc.getCheckConstraintModes());
+        sc.setConstraintModes(ssc.getConstraintModes());
 
         StatementContext stmctx = getStatementContext();
 
@@ -3792,33 +3792,9 @@ public class GenericLanguageConnectionCo
         // Check all constraints that were deferred inside the routine
         // but whose constraint mode is immediate on the outside. If
         // any of these violate the constraints, roll back.
-        for (Map.Entry<Long, ValidationInfo> e : deferredHashTables.entrySet())
-        {
-            e.getValue().possiblyValidateOnReturn(e, this, nested, caller);
-        }
-    }
-
-    public boolean isEffectivelyDeferred(SQLSessionContext sc, long indexCID)
-            throws StandardException {
-
-        Boolean deferred = sc.isDeferred(indexCID);
-        boolean effectivelyDeferred;
-        final DataDictionary dd = getDataDictionary();
-
-        if (deferred != null) {
-            effectivelyDeferred = deferred.booleanValue();
-        } else {
-            // no explicit setting applicable, use initial constraint mode
-            final ConglomerateDescriptor cd =
-                    dd.getConglomerateDescriptor(indexCID);
-            final TableDescriptor td =
-                    dd.getTableDescriptor(cd.getTableID());
-            final ConstraintDescriptor conDesc =
-                    dd.getConstraintDescriptor(td, cd.getUUID());
-            effectivelyDeferred = conDesc.initiallyDeferred();
+        for (ValidationInfo info : deferredHashTables.values()) {
+            info.possiblyValidateOnReturn(this, nested, caller);
         }
-
-        return effectivelyDeferred;
     }
 
     public boolean isEffectivelyDeferred(SQLSessionContext sc, UUID constraintId)
@@ -3945,49 +3921,24 @@ public class GenericLanguageConnectionCo
     }
 
     /**
-     * For check constraints
+     * Set the constraint mode to deferred for the specified constraint.
      *
      * @param a             activation
-     * @param basetableCID  the conglomerate id of the base table on which
-     *                      the constraint is defined
-     * @param constraintId  the constraint id
+     * @param cd            the constraint descriptor
      * @param deferred      the constraint mode
      * @throws StandardException standard error policy
      */
     public void setConstraintDeferred(
             final Activation a,
-            final long basetableCID,
-            final UUID constraintId,
-            final boolean deferred) throws StandardException {
-
-        if (!deferred) {
-            // Moving to immediate, check what's done in this transaction first
-            validateDeferredConstraint(basetableCID, constraintId);
-        }
-
-        getCurrentSQLSessionContext(a).setDeferred(constraintId, deferred);
-    }
-
-    /**
-     * For unique and primary key constraints
-     *
-     * @param a         activation
-     * @param indexCID  the conglomerate id of the supporting index
-     * @param deferred  constraint mode
-     * @throws StandardException standard error policy
- */
-    public void setConstraintDeferred(
-            final Activation a,
-            final long indexCID,
+            ConstraintDescriptor cd,
             final boolean deferred) throws StandardException {
 
         if (!deferred) {
             // Moving to immediate, check what's done in this transaction first
-            validateDeferredConstraint(indexCID, null);
+            validateDeferredConstraint(cd);
         }
 
-        getCurrentSQLSessionContext(a).setDeferred(indexCID, deferred);
-
+        getCurrentSQLSessionContext(a).setDeferred(cd.getUUID(), deferred);
     }
 
     public void checkIntegrity() throws StandardException {
@@ -3995,14 +3946,6 @@ public class GenericLanguageConnectionCo
         clearDeferreds();
     }
 
-    public void forgetDeferredConstraintsData(final long conglomId)
-            throws StandardException {
-        if (deferredHashTables != null &&
-                deferredHashTables.containsKey(Long.valueOf(conglomId))) {
-            deferredHashTables.remove(Long.valueOf(conglomId));
-        }
-    }
-
     /**
      * Clear deferred information for this transaction.
      */
@@ -4016,20 +3959,25 @@ public class GenericLanguageConnectionCo
         if (!deferred) {
             validateDeferredConstraints(false);
 
-            // No violations, so reset the memory
-            deferredHashTables = null;
+            // No violations, bug can't forget since we might roll back to a
+            // savepoint that migh re-introduce the violations
+            // DERBY-6670
+            // deferredHashTables = null;
         }
         getCurrentSQLSessionContext(a).setDeferredAll(
             Boolean.valueOf(deferred));
     }
 
-    public HashMap<Long, ValidationInfo> getDeferredHashTables() {
+    public HashMap<UUID, ValidationInfo> getDeferredHashTables() {
         if (deferredHashTables == null) {
-            deferredHashTables = new HashMap<Long, ValidationInfo>();
+            deferredHashTables = new HashMap<UUID, ValidationInfo>();
         }
         return deferredHashTables;
     }
 
+    /**
+     * Validate all deferred constraints.
+     */
     private void validateDeferredConstraints(final boolean rollbackOnError)
             throws StandardException {
 
@@ -4038,29 +3986,41 @@ public class GenericLanguageConnectionCo
             return;
         }
 
-        final Set<Map.Entry<Long, ValidationInfo>> es =
-                deferredHashTables.entrySet();
-
-        for (Map.Entry<Long, ValidationInfo> e : es) {
-            final long cid = e.getKey().longValue();
-            e.getValue().validateConstraint(this, cid, null, rollbackOnError);
+        for (ValidationInfo info : deferredHashTables.values()) {
+            info.validateConstraint(this, null, rollbackOnError);
         }
     }
 
+    /**
+     * Validate a deferred constraint.
+     *
+     * @param cd the descriptor of the constraint to validate
+     */
+    private void validateDeferredConstraint(ConstraintDescriptor cd)
+            throws StandardException {
+
+        if (deferredHashTables == null) {
+            // Nothing to do.
+            return;
+        }
 
-    private void validateDeferredConstraint(
-        final long conglomCID,
-        final UUID constraintId) throws StandardException {
+        // For CHECK constraints, the key is the table id. All other
+        // constraints use the constraint id as key.
+        UUID key = cd.hasBackingIndex() ? cd.getUUID() : cd.getTableId();
 
-        ValidationInfo vi = null;
+        ValidationInfo vi = deferredHashTables.get(key);
 
-        if (deferredHashTables == null ||
-            (vi = deferredHashTables.get(conglomCID)) == null) {
+        if (vi == null) {
             // Nothing to do
             return;
         }
 
-        vi.validateConstraint(this, conglomCID, constraintId, false);
-        deferredHashTables.remove(conglomCID);
+        vi.validateConstraint(this, cd.getUUID(), false);
+
+        // No violations, bug can't forget since we might roll back to a
+        // savepoint that migh re-introduce the violations
+        // DERBY-6670-
+        //
+        // deferredHashTables.remove(key);
     }
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/SQLSessionContextImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/SQLSessionContextImpl.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/SQLSessionContextImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/SQLSessionContextImpl.java Wed Jul 30 21:51:54 2014
@@ -33,23 +33,13 @@ public class SQLSessionContextImpl imple
     private SchemaDescriptor currentDefaultSchema;
 
     /**
-     * Maps a conglomerate id (key) into a Boolean for deferrable primary/unique
-     * constraints.
-     * There is a 1-1 correspondence for these backing indexes, they are not
-     * shared). If the Boolean value is {@code FALSE}, we have immediate
-     * checking, if it is {@code TRUE} we have deferred checking. Cf. SQL
-     * SET CONSTRAINT.
-     */
-    private HashMap<Long, Boolean> uniquePKConstraintModes;
-
-    /**
-     * Maps a constraint id (key) into a Boolean for deferrable check
+     * Maps a constraint id (key) into a Boolean for deferrable
      * constraints.
      * If the Boolean value is {@code FALSE}, we have immediate
      * checking, if it is {@code TRUE} we have deferred checking. Cf. SQL
      * SET CONSTRAINT.
      */
-    private HashMap<UUID, Boolean> checkConstraintModes;
+    private HashMap<UUID, Boolean> constraintModes;
 
     /**
      * True if all deferrable constraints are deferred in this transaction.
@@ -91,75 +81,39 @@ public class SQLSessionContextImpl imple
     /**
      * {@inheritDoc}
      */
-    public HashMap<Long, Boolean> getUniquePKConstraintModes() {
-        return uniquePKConstraintModes != null ?
-            new HashMap<Long, Boolean>(uniquePKConstraintModes) :
-            null;
-    }
-
-    public HashMap<UUID, Boolean> getCheckConstraintModes() {
-        return checkConstraintModes != null ?
-            new HashMap<UUID, Boolean>(checkConstraintModes) :
+    public HashMap<UUID, Boolean> getConstraintModes() {
+        return constraintModes != null ?
+            new HashMap<UUID, Boolean>(constraintModes) :
             null;
     }
 
     /**
      * {@inheritDoc}
      */
-    public void setConstraintModes(HashMap<Long, Boolean> hm) {
-        this.uniquePKConstraintModes = hm != null ?
-                new HashMap<Long, Boolean>(hm) : null;
-    }
-
-    public void setCheckConstraintModes(HashMap<UUID, Boolean> hm) {
-        this.checkConstraintModes = hm != null ?
+    public void setConstraintModes(HashMap<UUID, Boolean> hm) {
+        this.constraintModes = hm != null ?
                 new HashMap<UUID, Boolean>(hm) : null;
     }
 
     /**
      * {@inheritDoc}
      */
-    public void setDeferred(long conglomId, boolean deferred) {
-        if (uniquePKConstraintModes == null) {
-            uniquePKConstraintModes = new HashMap<Long, Boolean>();
-        }
-
-        uniquePKConstraintModes.put(Long.valueOf(conglomId),
-                                Boolean.valueOf(deferred));
-    }
-
     public void setDeferred(UUID constraintId, boolean deferred) {
-        if (checkConstraintModes == null) {
-            checkConstraintModes = new HashMap<UUID, Boolean>();
+        if (constraintModes == null) {
+            constraintModes = new HashMap<UUID, Boolean>();
         }
 
-        checkConstraintModes.put(constraintId, Boolean.valueOf(deferred));
+        constraintModes.put(constraintId, Boolean.valueOf(deferred));
     }
 
     /**
      * {@inheritDoc}
      */
-    public Boolean isDeferred(long conglomId) {
-        Boolean v = null;
-
-        if (uniquePKConstraintModes != null) {
-            v = uniquePKConstraintModes.get(Long.valueOf(conglomId));
-        }
-
-        if (v != null) {
-            return v; // Trumps ALL setting since it must have been
-                      // set later otherwise it would have been
-                      // deleted
-        } else {
-            return deferredAll;
-        }
-    }
-
     public Boolean isDeferred(UUID constraintId) {
         Boolean v = null;
 
-        if (checkConstraintModes != null) {
-            v = checkConstraintModes.get(constraintId);
+        if (constraintModes != null) {
+            v = constraintModes.get(constraintId);
         }
 
         if (v != null) {
@@ -176,12 +130,8 @@ public class SQLSessionContextImpl imple
      * {@inheritDoc}
      */
     public void resetConstraintModes() {
-        if (uniquePKConstraintModes != null) {
-            uniquePKConstraintModes.clear();
-        }
-
-        if (checkConstraintModes != null) {
-            checkConstraintModes.clear();
+        if (constraintModes != null) {
+            constraintModes.clear();
         }
 
         deferredAll = null;
@@ -194,12 +144,8 @@ public class SQLSessionContextImpl imple
         deferredAll = deferred;
         // This now overrides any individual constraint setting, so
         // clear those.
-        if (uniquePKConstraintModes != null) {
-            uniquePKConstraintModes.clear();
-        }
-
-        if (checkConstraintModes != null) {
-            checkConstraintModes.clear();
+        if (constraintModes != null) {
+            constraintModes.clear();
         }
     }
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java Wed Jul 30 21:51:54 2014
@@ -2788,12 +2788,6 @@ class AlterTableConstantAction extends D
 		// Drop the old conglomerate
 		tc.dropConglomerate(indexConglomerateNumbers[index]);
 
-        DeferredConstraintsMemory.updateIndexCIDs(
-                lcc,
-                truncateTable,
-                indexConglomerateNumbers[index],
-                newIndexCongloms[index]);
-
 	}
 
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstraintConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstraintConstantAction.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstraintConstantAction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstraintConstantAction.java Wed Jul 30 21:51:54 2014
@@ -352,7 +352,7 @@ public abstract class ConstraintConstant
                         CheckInfo newCi[] = new CheckInfo[1];
                         DeferredConstraintsMemory.rememberCheckViolations(
                                 lcc,
-                                td.getHeapConglomerateId(),
+                                td.getObjectID(),
                                 td.getSchemaName(),
                                 td.getName(),
                                 null,

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateConstraintConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateConstraintConstantAction.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateConstraintConstantAction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateConstraintConstantAction.java Wed Jul 30 21:51:54 2014
@@ -237,6 +237,8 @@ public class CreateConstraintConstantAct
 		 */
 		UUIDFactory uuidFactory = dd.getUUIDFactory();
         
+        UUID constrId = uuidFactory.createUUID();
+
 		/* Create the index, if there's one for this constraint */
 		if (indexAction != null)
 		{
@@ -248,6 +250,7 @@ public class CreateConstraintConstantAct
 			}
 			else { backingIndexName = indexAction.getIndexName(); }
 
+            indexAction.setConstraintID( constrId );
 
 			/* Create the index */
 			indexAction.executeConstantAction(activation);
@@ -282,8 +285,6 @@ public class CreateConstraintConstantAct
 			indexId = conglomDesc.getUUID();
 		}
 
-        UUID constrId=  uuidFactory.createUUID();
-
         boolean[] defaults = new boolean[]{
             ConstraintDefinitionNode.DEFERRABLE_DEFAULT,
             ConstraintDefinitionNode.INITIALLY_DEFERRED_DEFAULT,

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateIndexConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateIndexConstantAction.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateIndexConstantAction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateIndexConstantAction.java Wed Jul 30 21:51:54 2014
@@ -838,9 +838,8 @@ class CreateIndexConstantAction extends 
                             baseColumnPositions.length + 1;
 
                     sortObserver = new UniqueIndexSortObserver(
-                        tc,
                         lcc,
-                        DeferredConstraintsMemory.UNDEFINED_CONGLOMERATE,
+                        constraintID,
                         true,
                         uniqueDeferrable,
                         initiallyDeferred,
@@ -864,9 +863,8 @@ class CreateIndexConstantAction extends 
 					//use sort operator which treats nulls unequal
 					sortObserver = 
                         new UniqueWithDuplicateNullsIndexSortObserver(
-                            tc,
                             lcc,
-                            DeferredConstraintsMemory.UNDEFINED_CONGLOMERATE,
+                            constraintID,
                             true,
                             (hasDeferrableChecking && 
                             constraintType != DataDictionary.FOREIGNKEY_CONSTRAINT),
@@ -925,10 +923,6 @@ class CreateIndexConstantAction extends 
 					rowSource,
 					(long[]) null);
 
-            if (initiallyDeferred) {
-                DeferredConstraintsMemory.associateDuplicatesWithConglomerate(
-                    lcc, conglomId);
-            }
 		}
 		finally
 		{

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DeferredConstraintsMemory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DeferredConstraintsMemory.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DeferredConstraintsMemory.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DeferredConstraintsMemory.java Wed Jul 30 21:51:54 2014
@@ -25,7 +25,6 @@ import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import org.apache.derby.catalog.UUID;
 import org.apache.derby.iapi.error.StandardException;
@@ -34,10 +33,11 @@ import org.apache.derby.iapi.sql.Activat
 import org.apache.derby.iapi.sql.PreparedStatement;
 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
 import org.apache.derby.iapi.sql.conn.SQLSessionContext;
-import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor;
 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
 import org.apache.derby.iapi.sql.dictionary.ForeignKeyConstraintDescriptor;
+import org.apache.derby.iapi.sql.dictionary.KeyConstraintDescriptor;
+import org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor;
 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
 import org.apache.derby.iapi.sql.execute.ExecRow;
@@ -48,7 +48,6 @@ import org.apache.derby.iapi.types.DataV
 import org.apache.derby.iapi.types.RowLocation;
 import org.apache.derby.iapi.types.SQLRef;
 import org.apache.derby.shared.common.reference.SQLState;
-import org.apache.derby.shared.common.sanity.SanityManager;
 
 /**
  * This class provides support for deferrable constraints. When the constraint
@@ -68,14 +67,6 @@ import org.apache.derby.shared.common.sa
  */
 final public class DeferredConstraintsMemory
 {
-    /**
-     * For unique and primary key constraints, sometimes we need to save
-     * duplicate rows before we know the id of the constraint index, so we
-     * assign the duplicates row a temporary constraint id
-     * (UNDEFINED_CONGLOMERATE) and fix it up later.
-     * @see #associateDuplicatesWithConglomerate
-     */
-    public final static long UNDEFINED_CONGLOMERATE = -1;
 
     /**
      * Save the contents of an constraint supporting index row in a
@@ -85,8 +76,7 @@ final public class DeferredConstraintsMe
      * @param lcc       the language connection context
      * @param deferredRowsHashTable
      *                  client cached value
-     * @param indexCID  the identity of the index conglomerate which supports
-     *                  the deferred constraint
+     * @param constraintId the id of the unique or primary key constraint
      * @param insertRow the duplicate row to be saved in the hash table
      *                  for later checking
      * @return the hash table (for caching by client to minimize lookups)
@@ -95,7 +85,7 @@ final public class DeferredConstraintsMe
     public static BackingStoreHashtable rememberDuplicate(
             final LanguageConnectionContext lcc,
                   BackingStoreHashtable deferredRowsHashTable,
-            final long indexCID,
+            UUID constraintId,
             final DataValueDescriptor[] insertRow) throws StandardException {
 
         // Don't copy the RowLocation, we don't need it:
@@ -107,17 +97,17 @@ final public class DeferredConstraintsMe
             // tables (one per index conglomerate).  Use it if it
             // exists, else make a new one.
 
-            final HashMap<Long, ValidationInfo> hashTables =
+            final HashMap<UUID, ValidationInfo> hashTables =
                 lcc.getDeferredHashTables();
-            final ValidationInfo vi = hashTables.get(Long.valueOf(indexCID));
+            final ValidationInfo vi = hashTables.get(constraintId);
 
             if (vi == null) {
                 deferredRowsHashTable =
                   makeDeferredHashTable(lcc.getTransactionExecute(), keyLength);
 
                 hashTables.put(
-                    Long.valueOf(indexCID),
-                    new UniquePkInfo(deferredRowsHashTable));
+                    constraintId,
+                    new UniquePkInfo(deferredRowsHashTable, constraintId));
             } else {
                 deferredRowsHashTable = vi.infoRows;
             }
@@ -138,8 +128,7 @@ final public class DeferredConstraintsMe
      * The row locations are subject to invalidation, cf.
      * {@code CheckInfo#setInvalidatedRowLocations}.
      *
-     * @param basetableCID  the identity of the base table conglomerate for
-     *                  which we have seen a violated deferred check constraint
+     * @param basetableId the id of the target table
      * @param schemaName the schema of the target table
      * @param tableName the target table name
      * @param deferredCheckViolations
@@ -154,7 +143,7 @@ final public class DeferredConstraintsMe
      */
     public static BackingStoreHashtable rememberCheckViolations(
             final LanguageConnectionContext lcc,
-            final long basetableCID,
+            UUID  basetableId,
             final String schemaName,
             final String tableName,
                   BackingStoreHashtable deferredCheckViolations,
@@ -172,10 +161,9 @@ final public class DeferredConstraintsMe
             // tables (one per base table conglomerate).  Use it if it
             // exists, else make a new one.
 
-            final HashMap<Long, ValidationInfo> hashTables =
+            final HashMap<UUID, ValidationInfo> hashTables =
                     lcc.getDeferredHashTables();
-            final CheckInfo vi =
-                    (CheckInfo)hashTables.get(Long.valueOf(basetableCID));
+            final CheckInfo vi = (CheckInfo) hashTables.get(basetableId);
 
             if (vi == null) {
                 // size 1 below: the row location in the target table of the
@@ -186,7 +174,7 @@ final public class DeferredConstraintsMe
                                    schemaName,
                                    tableName,
                                    violatingCheckConstraints);
-                hashTables.put(Long.valueOf(basetableCID), ci);
+                hashTables.put(basetableId, ci);
                 result[0] = ci;
             } else {
                 vi.addCulprits(violatingCheckConstraints);
@@ -205,12 +193,11 @@ final public class DeferredConstraintsMe
 
     public static Enumeration<Object> getDeferredCheckConstraintLocations(
             Activation activation,
-            long validatingBaseTableCID) throws StandardException {
+            UUID validatingBaseTableUUID) throws StandardException {
 
         CheckInfo ci = (DeferredConstraintsMemory.CheckInfo)activation.
                 getLanguageConnectionContext().
-                getDeferredHashTables().get(
-                    Long.valueOf(validatingBaseTableCID));
+                getDeferredHashTables().get( validatingBaseTableUUID );
         return ci.infoRows.elements();
     }
 
@@ -220,8 +207,6 @@ final public class DeferredConstraintsMe
      *
      * @param lcc the language connection context
      * @param deferredRowsHashTable cached client copy
-     * @param siCID the conglomerate ID of the supporting index of the FK
-     * @param rtCID the conglomerate id of the index of the referenced table
      * @param fkId the UUID of the foreign key constraint
      * @param indexRow the row in the supporting index which contains
      *        the key which is not present in the referenced index.
@@ -233,8 +218,6 @@ final public class DeferredConstraintsMe
     public static BackingStoreHashtable rememberFKViolation(
             final LanguageConnectionContext lcc,
                   BackingStoreHashtable deferredRowsHashTable,
-            final long siCID,
-            final long rtCID,
             final UUID fkId,
             final DataValueDescriptor[] indexRow,
             String schemaName,
@@ -246,17 +229,17 @@ final public class DeferredConstraintsMe
             // tables (one per index conglomerate).  Use it if it
             // exists, else make a new one.
 
-            final HashMap<Long, ValidationInfo> hashTables =
+            final HashMap<UUID, ValidationInfo> hashTables =
                 lcc.getDeferredHashTables();
-            final ValidationInfo vi = hashTables.get(Long.valueOf(siCID));
+            final ValidationInfo vi = hashTables.get(fkId);
 
             if (vi == null) {
                 deferredRowsHashTable = makeDeferredHashTable(
                     lcc.getTransactionExecute(), indexRow.length);
 
                 hashTables.put(
-                    Long.valueOf(siCID),
-                    new ForeignKeyInfo(deferredRowsHashTable, fkId, rtCID,
+                    fkId,
+                    new ForeignKeyInfo(deferredRowsHashTable, fkId,
                                        schemaName, tableName));
             } else {
                 deferredRowsHashTable = vi.infoRows;
@@ -271,59 +254,6 @@ final public class DeferredConstraintsMe
         return deferredRowsHashTable;
     }
 
-    /**
-     * After having belatedly learned the identity of the conglomerate, we now
-     * associate the conglomerate id information with the saved duplicates
-     * memory. Used for unique and primary key constraints.
-     * See {@link #UNDEFINED_CONGLOMERATE}.
-     *
-     * @param lcc language connection context
-     * @param indexCID the id of the index conglomerate supporting the
-     *                 deferred constraint
-     */
-    public static void associateDuplicatesWithConglomerate(
-            final LanguageConnectionContext lcc,
-            final long indexCID) {
-        updateKey(lcc, UNDEFINED_CONGLOMERATE, indexCID);
-    }
-
-    private static void updateKey(
-        LanguageConnectionContext lcc,
-        long oldCID,
-        long newCID) {
-
-        final HashMap<Long, ValidationInfo> hashTables =
-                    lcc.getDeferredHashTables();
-
-        if (hashTables == null) {
-            return; // no duplicates recorded in this transaction
-        }
-
-        final ValidationInfo ht = hashTables.remove(Long.valueOf(oldCID));
-
-        if (ht != null) {
-            hashTables.put(newCID, ht);
-        }
-    }
-
-    /**
-     * The conglomerate id for an index with deferred row checking needs
-     * updating in the memory if the underlying index is rebuilt
-     * on bulk insert for import.
-     *
-     * @param lcc the language connection context needed to find the
-     *            deferred rows information if any
-     * @param oldIndexCID the old id of the supporting index
-     * @param newIndexCID the new id of the supporting index after recreation
-     */
-    public static void updateIndexCID(
-            final LanguageConnectionContext lcc,
-            final long oldIndexCID,
-            final long newIndexCID) {
-
-        updateKey(lcc, oldIndexCID, newIndexCID);
-    }
-
     private static BackingStoreHashtable makeDeferredHashTable(
             final TransactionController tc,
             final int cols) throws StandardException {
@@ -350,79 +280,17 @@ final public class DeferredConstraintsMe
                 false);
     }
 
-    /**
-     * Update the conglomerate ids of supporting indexes, when they change,
-     * under truncate and compress.
-     *
-     * @param lcc       the language connection context
-     * @param truncate  if {@code true} we are in a TRUNCATE TABLE context
-     * @param oldCID    the old conglomerate id of a supporting index
-     * @param newCID    the old conglomerate id of a supporting index
-     * @throws StandardException
-     */
-    public static void updateIndexCIDs(
-            LanguageConnectionContext lcc,
-            boolean truncate,
-            long oldCID,
-            long newCID) throws StandardException {
-
-        // Handle reference to the old index conglomerate ID for
-        // deferred constraints
-        final HashMap<Long, ValidationInfo> vis = lcc.getDeferredHashTables();
-
-        if (vis == null) {
-            return;
-        }
-
-        if (truncate) {
-            // Invalidate any deferred constraints information based on this
-            // index.
-            final ValidationInfo vi =  vis.get(oldCID);
-
-            if (vi != null &&
-                    (vi instanceof UniquePkInfo ||
-                     vi instanceof ForeignKeyInfo)) {
-                lcc.forgetDeferredConstraintsData(oldCID);
-            }
-        } else {
-            final ValidationInfo vi =  vis.get(oldCID);
-
-            if (vi != null && vi instanceof UniquePkInfo){
-                updateKey(lcc, oldCID, newCID);
-            }
-        }
-
-        // Update conglomerate information for deferred foreign keys involved
-        // with this index re-creation.
-        for (Map.Entry<Long, ValidationInfo> e : vis.entrySet()) {
-            final ValidationInfo vi = e.getValue();
-
-            if (vi instanceof ForeignKeyInfo) {
-                final ForeignKeyInfo fki = (ForeignKeyInfo)vi;
-
-                if (fki.getRtCID() == oldCID) {
-                    fki.updateRtCID(newCID);
-
-                } else if (e.getKey().longValue() == oldCID) {
-                    updateKey(lcc, oldCID, newCID);
-                }
-            }
-        }
-
-    }
-
-
     public static void compressOrTruncate(
             LanguageConnectionContext lcc,
             UUID tableId,
             String tableName) throws StandardException {
 
-        final HashMap<Long, DeferredConstraintsMemory.ValidationInfo> vis =
+        final HashMap<UUID, DeferredConstraintsMemory.ValidationInfo> vis =
                 lcc.getDeferredHashTables();
         final TableDescriptor td =
                 lcc.getDataDictionary().getTableDescriptor(tableId);
         final DeferredConstraintsMemory.ValidationInfo vi =
-                vis.get(td.getHeapConglomerateId());
+                vis.get( tableId );
 
         if (td == null) {
             throw StandardException.newException(
@@ -452,14 +320,12 @@ final public class DeferredConstraintsMe
         }
 
         public abstract void possiblyValidateOnReturn(
-                Map.Entry<Long, ValidationInfo> e,
                 LanguageConnectionContext lcc,
                 SQLSessionContext nested,
                 SQLSessionContext caller) throws StandardException;
 
         public abstract void validateConstraint(
                 LanguageConnectionContext lcc,
-                long conglomerateId,
                 UUID constraintId,
                 boolean rollbackOnError) throws StandardException;
     }
@@ -468,57 +334,66 @@ final public class DeferredConstraintsMe
      * Info needed for unique and primary key constraints
      */
     private static class UniquePkInfo extends ValidationInfo {
+        private final UUID constraintId;
 
-        public UniquePkInfo(final BackingStoreHashtable infoRows) {
+        public UniquePkInfo(BackingStoreHashtable infoRows, UUID constraintId) {
             super(infoRows);
+            this.constraintId = constraintId;
         }
 
+        @Override
         public final void possiblyValidateOnReturn(
-                Map.Entry<Long, ValidationInfo> e,
                 LanguageConnectionContext lcc,
                 SQLSessionContext nested,
                 SQLSessionContext caller) throws StandardException {
 
-                final long indexCID = e.getKey().longValue();
-
-                if (lcc.isEffectivelyDeferred(caller, indexCID)) {
+                if (lcc.isEffectivelyDeferred(caller, constraintId)) {
                     // the constraint is also deferred in the calling context
                     return;
                 }
 
-                validateUniquePK(lcc, indexCID, e.getValue().infoRows, true);
+                validateUniquePK(lcc, infoRows, true);
         }
 
         /**
          * Validate one primary key or unique constraint
          *
          * @param lcc       The language connection context
-         * @param indexCID The conglomerate id of the index backing the
-         *                 constraint
          * @param constraintId Not used by this constraint type
          * @param rollbackOnError {@code true} if we should roll back the
          *                  transaction if we see a violation of the constraint
          * @throws StandardException
          */
+        @Override
         public final void validateConstraint(
                 LanguageConnectionContext lcc,
-                long indexCID,
                 UUID constraintId,
                 boolean rollbackOnError) throws StandardException {
 
             validateUniquePK(
-                    lcc, indexCID, this.infoRows, rollbackOnError);
+                    lcc, this.infoRows, rollbackOnError);
         }
 
-        private static void validateUniquePK(
+        private void validateUniquePK(
                 final LanguageConnectionContext lcc,
-                final long indexCID,
                 final BackingStoreHashtable ht,
                 final boolean rollbackOnError) throws StandardException {
 
             final TransactionController tc = lcc.getTransactionExecute();
             final Enumeration<?> e = ht.elements();
 
+            DataDictionary dd = lcc.getDataDictionary();
+            KeyConstraintDescriptor cd = (KeyConstraintDescriptor)
+                    dd.getConstraintDescriptor(constraintId);
+
+            if (cd == null) {
+                // Constraint dropped, nothing to do.
+                return;
+            }
+
+            long indexCID = cd.getIndexConglomerateDescriptor(dd)
+                              .getConglomerateNumber();
+
             while (e.hasMoreElements()) {
                 final DataValueDescriptor[] key =
                         (DataValueDescriptor[])e.nextElement();
@@ -545,22 +420,14 @@ final public class DeferredConstraintsMe
                     if (indexSC.next()) {
                         if (indexSC.next()) {
                             // two matching rows found, constraint violated
-                            final DataDictionary dd = lcc.getDataDictionary();
-                            final ConglomerateDescriptor cd =
-                                dd.getConglomerateDescriptor(indexCID);
-                            final TableDescriptor td =
-                                dd.getTableDescriptor(cd.getTableID());
-                            final ConstraintDescriptor conDesc =
-                                dd.getConstraintDescriptor(td, cd.getUUID());
-
                             throw StandardException.newException(
                                 rollbackOnError ?
                                 SQLState.
                                     LANG_DEFERRED_DUPLICATE_KEY_CONSTRAINT_T :
                                 SQLState.
                                     LANG_DEFERRED_DUPLICATE_KEY_CONSTRAINT_S,
-                                conDesc.getConstraintName(),
-                                td.getName());
+                                cd.getConstraintName(),
+                                cd.getTableDescriptor().getName());
                         } // else exactly one row contains key: OK
                     } else {
                         // No rows contain key: OK, must have been deleted later
@@ -627,14 +494,12 @@ final public class DeferredConstraintsMe
             return culprits;
         }
 
+        @Override
         public void possiblyValidateOnReturn(
-                Map.Entry<Long, ValidationInfo> e,
                 LanguageConnectionContext lcc,
                 SQLSessionContext nested,
                 SQLSessionContext caller) throws StandardException {
 
-            final long baseTableCID = e.getKey().longValue();
-
             // check if any of the constraints involved is immediate on
             // the outside
             boolean allEffectivelyDeferred = true;
@@ -660,7 +525,7 @@ final public class DeferredConstraintsMe
                 return;
             }
 
-            validateCheck(lcc, baseTableCID, null, true);
+            validateCheck(lcc, null, true);
         }
 
         /**
@@ -684,8 +549,6 @@ final public class DeferredConstraintsMe
          * @see ValidateCheckConstraintResultSet
          *
          * @param lcc          The language connection context
-         * @param baseTableCID The conglomerate id of the base table for which
-         *                     we want to validate check constraints.
          * @param constraintId If not {@code null}, check only for this
          *                     constraint.  This is used when switching mode to
          *                     immediate.  If {@code null}, we check all check
@@ -696,18 +559,17 @@ final public class DeferredConstraintsMe
          * @throws StandardException
          *                     Default error policy
          */
+        @Override
         public final void validateConstraint(
                 LanguageConnectionContext lcc,
-                long baseTableCID,
                 UUID constraintId,
                 boolean rollbackOnError) throws StandardException {
 
-            validateCheck(lcc, baseTableCID, constraintId, rollbackOnError);
+            validateCheck(lcc, constraintId, rollbackOnError);
         }
 
         private void validateCheck(
                 final LanguageConnectionContext lcc,
-                final long baseTableCID,
                 final UUID constraintId,
                 final boolean rollbackOnError) throws StandardException {
 
@@ -717,32 +579,26 @@ final public class DeferredConstraintsMe
                     schemaName, tc, true);
 
             if (sd == null) {
-                if (SanityManager.DEBUG) {
-                    // dropping of a schema shouold drop any tables and their
-                    // constraints, which in turn should drop any deferred
-                    // constraint memory of them.
-                    SanityManager.NOTREACHED();
-                } else {
-                    return;
-                }
+                // Schema dropped, nothing to do
+                return;
             }
 
             final TableDescriptor td = dd.getTableDescriptor(tableName, sd, tc);
 
             if (td == null) {
-                if (SanityManager.DEBUG) {
-                    // dropping of a table shouold drop any
-                    // constraints, which in turn should drop any deferred
-                    // constraint memory of them. Renaming of a table with
-                    // constrants is not presently allowed. FIXME: use UUID
-                    // instead of string here, more stable reference.
-                    SanityManager.NOTREACHED();
-                }
+                // Nothing to do, table dropped
             } else {
+                final String baseTableUUIDString = td.getUUID().toString();
                 for (UUID id : culprits) {
                     if (constraintId == null || constraintId.equals(id)) {
                         final ConstraintDescriptor cd =
                                 dd.getConstraintDescriptor(id);
+
+                        if (cd == null) {
+                            // Constraint dropped, nothing to do.
+                            break;
+                        }
+
                         final StringBuilder checkStmt = new StringBuilder();
                         checkStmt.append("SELECT 1 FROM ");
                         checkStmt.append(td.getQualifiedName());
@@ -759,7 +615,7 @@ final public class DeferredConstraintsMe
                                " --DERBY-PROPERTIES joinStrategy=nestedLoop, " +
                                "                    index=null, " +
                                "                    validateCheckConstraint=");
-                            checkStmt.append(Long.toString(baseTableCID));
+                            checkStmt.append( baseTableUUIDString );
                             checkStmt.append('\n');
                         }
 
@@ -809,24 +665,17 @@ final public class DeferredConstraintsMe
          */
         private final UUID fkId;
 
-        /**
-         * The conglomerate id of the index of the referenced table
-         */
-        private long rtCID;
-
         final private String schemaName;
         final private String tableName;
 
         public ForeignKeyInfo(
                 final BackingStoreHashtable infoRows,
                 UUID fkId,
-                long rtCID,
                 String schemaName,
                 String tableName) {
 
             super(infoRows);
             this.fkId = fkId;
-            this.rtCID = rtCID;
             this.tableName = tableName;
             this.schemaName = schemaName;
         }
@@ -835,16 +684,8 @@ final public class DeferredConstraintsMe
             return fkId;
         }
 
-        public void updateRtCID(long rtCID) {
-            this.rtCID = rtCID;
-        }
-
-        public long getRtCID() {
-            return rtCID;
-        }
-
+        @Override
         public void possiblyValidateOnReturn(
-                Map.Entry<Long, ValidationInfo> e,
                 LanguageConnectionContext lcc,
                 SQLSessionContext nested,
                 SQLSessionContext caller) throws StandardException {
@@ -854,23 +695,21 @@ final public class DeferredConstraintsMe
                 return;
             }
 
-            final long indexCID = e.getKey().longValue();
-            validateForeignKey(lcc, indexCID, true);
+            validateForeignKey(lcc, true);
         }
 
+        @Override
         public final void validateConstraint(
                 LanguageConnectionContext lcc,
-                long conglomerateId,
                 UUID constraintId,
                 boolean rollbackOnError) throws StandardException {
 
-            validateForeignKey(lcc, conglomerateId, rollbackOnError);
+            validateForeignKey(lcc, rollbackOnError);
 
         }
 
         private void validateForeignKey(
             LanguageConnectionContext lcc,
-            long indexCID,
             boolean rollbackOnError) throws StandardException {
 
             // First check if the offending row is still present,
@@ -879,6 +718,28 @@ final public class DeferredConstraintsMe
 
             TransactionController tc = lcc.getTransactionExecute();
 
+            DataDictionary dd = lcc.getDataDictionary();
+
+            ForeignKeyConstraintDescriptor cd =
+                (ForeignKeyConstraintDescriptor)
+                    dd.getConstraintDescriptor(fkId);
+
+            // If the foreign key has been dropped, there is nothing to do.
+            // See DERBY-6670
+            //
+            if (cd == null) {
+                return;
+            }
+
+            ReferencedKeyConstraintDescriptor rcd =
+                    cd.getReferencedConstraint();
+
+            long[] cids = {
+                cd.getIndexConglomerateDescriptor(dd).getConglomerateNumber(),
+                rcd.getIndexConglomerateDescriptor(dd).getConglomerateNumber()
+
+            };
+
             final Enumeration<?> e = infoRows.elements();
 
             while (e.hasMoreElements()) {
@@ -890,8 +751,6 @@ final public class DeferredConstraintsMe
                 ScanController indexSC = null;
                 boolean violation = false;
 
-                long[] cids = new long[]{indexCID, getRtCID()};
-
                 for (int idx = 0; idx < 2; idx++) {
                     boolean sawException = false;
 
@@ -949,21 +808,12 @@ final public class DeferredConstraintsMe
                 }
 
                 if (violation) {
-                    final DataDictionary dd = lcc.getDataDictionary();
-
                     final SchemaDescriptor sd =
                             dd.getSchemaDescriptor(schemaName, tc, true);
 
                     final TableDescriptor td  =
                             dd.getTableDescriptor(tableName, sd, tc);
 
-                    final ForeignKeyConstraintDescriptor cd =
-                            (ForeignKeyConstraintDescriptor)dd.
-                                    getConstraintDescriptor(getFkId());
-
-                    final ConstraintDescriptor rcd = dd.getConstraintDescriptor(
-                            cd.getReferencedConstraintId());
-
                     final TableDescriptor rtd = rcd.getTableDescriptor();
 
                     throw StandardException.newException(

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/FKInfo.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/FKInfo.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/FKInfo.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/FKInfo.java Wed Jul 30 21:51:54 2014
@@ -72,6 +72,7 @@ public class FKInfo implements Formatabl
     int                 type;
     UUID                refUUID; // index index conglomerate uuid
     long                refConglomNumber;
+    UUID                refConstraintID;
     boolean             refConstraintIsDeferrable;
     int                 stmtType;
     RowLocation         rowLocation;
@@ -102,6 +103,7 @@ public class FKInfo implements Formatabl
 	 * @param type either FKInfo.REFERENCED_KEY or FKInfo.FOREIGN_KEY
      * @param refUUID UUID of the referenced constraint's supporting index
      * @param refConglomNumber conglomerate number of the referenced key
+     * @param refConstraintID UUID of the referenced constraint
      * @param refConstraintIsDeferrable {@code true} iff the referenced key
      *                                  constraint is deferrable
 	 * @param fkUUIDs an array of fkUUIDs of backing indexes.  if
@@ -130,6 +132,7 @@ public class FKInfo implements Formatabl
 					int					type,
 					UUID				refUUID,
 					long				refConglomNumber,
+                    UUID                refConstraintID,
                     boolean             refConstraintIsDeferrable,
 					UUID[]				fkUUIDs,
 					long[]				fkConglomNumbers,
@@ -148,6 +151,7 @@ public class FKInfo implements Formatabl
 		this.type = type;
 		this.refUUID = refUUID;
 		this.refConglomNumber = refConglomNumber;
+        this.refConstraintID = refConstraintID;
         this.refConstraintIsDeferrable = refConstraintIsDeferrable;
         this.fkUUIDs = ArrayUtil.copy(fkUUIDs);
         this.fkConglomNumbers = ArrayUtil.copy(fkConglomNumbers);
@@ -283,6 +287,7 @@ public class FKInfo implements Formatabl
 		out.writeInt(stmtType);
 		out.writeObject(refUUID);
 		out.writeLong(refConglomNumber);
+        out.writeObject(refConstraintID);
         out.writeBoolean(refConstraintIsDeferrable);
 
 		ArrayUtil.writeArray(out, fkConstraintNames);
@@ -324,6 +329,7 @@ public class FKInfo implements Formatabl
 			stmtType = in.readInt();
 			refUUID = (UUID)in.readObject();
 			refConglomNumber = in.readLong();
+            refConstraintID = (UUID)in.readObject();
             refConstraintIsDeferrable = in.readBoolean();
 
 			fkConstraintNames = new String[ArrayUtil.readArrayLength(in)];

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ForeignKeyRIChecker.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ForeignKeyRIChecker.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ForeignKeyRIChecker.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ForeignKeyRIChecker.java Wed Jul 30 21:51:54 2014
@@ -118,8 +118,6 @@ public class ForeignKeyRIChecker extends
                         DeferredConstraintsMemory.rememberFKViolation(
                                 lcc,
                                 deferredRowsHashTable,
-                                fkInfo.fkConglomNumbers[0],
-                                fkInfo.refConglomNumber,
                                 fkInfo.fkIds[0],
                                 indexQualifierRow.getRowArray(),
                                 fkInfo.schemaName,

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericResultSetFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericResultSetFactory.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericResultSetFactory.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericResultSetFactory.java Wed Jul 30 21:51:54 2014
@@ -21,6 +21,7 @@
 
 package org.apache.derby.impl.sql.execute;
 
+import org.apache.derby.catalog.UUID;
 import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.services.loader.GeneratedMethod;
 import org.apache.derby.shared.common.sanity.SanityManager;
@@ -237,18 +238,26 @@ public class GenericResultSetFactory imp
 		boolean reuseResult,
 		boolean doesProjection,
         boolean validatingCheckConstraint,
-        long validatingBaseTableCID,
+        String validatingBaseTableUUIDString,
 		double optimizerEstimatedRowCount,
 		double optimizerEstimatedCost)
 			throws StandardException
 	{
+        UUID    validatingBaseTableUUID = UUID.NULL.equals( validatingBaseTableUUIDString ) ?
+            null :
+            source.getActivation()
+            .getLanguageConnectionContext()
+            .getDataDictionary()
+            .getUUIDFactory()
+            .recreateUUID( validatingBaseTableUUIDString );
+
 		return new ProjectRestrictResultSet(source, source.getActivation(), 
 			restriction, projection, resultSetNumber, 
             constantRestriction, mapRefItem, cloneMapItem,
 			reuseResult,
 			doesProjection,
             validatingCheckConstraint,
-            validatingBaseTableCID,
+            validatingBaseTableUUID,
 		    optimizerEstimatedRowCount,
 			optimizerEstimatedCost);
 	}

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexChanger.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexChanger.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexChanger.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexChanger.java Wed Jul 30 21:51:54 2014
@@ -21,7 +21,6 @@
 
 package org.apache.derby.impl.sql.execute;
 
-import java.sql.SQLException;
 import java.util.Properties;
 import org.apache.derby.catalog.UUID;
 import org.apache.derby.iapi.error.StandardException;
@@ -34,8 +33,10 @@ import org.apache.derby.iapi.sql.ResultD
 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor;
+import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList;
 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
 import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;
+import org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor;
 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
 import org.apache.derby.iapi.sql.execute.CursorResultSet;
 import org.apache.derby.iapi.sql.execute.ExecIndexRow;
@@ -433,6 +434,25 @@ class IndexChanger
 		}
 	}
 
+    private UUID uniqueConstraintId; // cached copy
+
+    // Return the id of the corresponding unique or primary key
+    // constraint. Note: this only works because deferrable constraints
+    // do not share an index with other constraints and explicit indexes, so the
+    // mapping back from index conglomerate to constraint is one-to-one.
+    private UUID getUniqueConstraintId() throws StandardException {
+        if (uniqueConstraintId == null) {
+            DataDictionary dd = lcc.getDataDictionary();
+            ConglomerateDescriptor cd = dd.getConglomerateDescriptor(indexCID);
+            uniqueConstraintId =
+                    dd.getConstraintDescriptor(
+                    dd.getTableDescriptor(cd.getTableID()),
+                    cd.getUUID()).getUUID();
+        }
+
+        return uniqueConstraintId;
+    }
+
 	/**
 	 * Insert the given row into the given conglomerate and check for duplicate
 	 * key error.
@@ -470,7 +490,9 @@ class IndexChanger
             // constitute duplicates (not always the case), and check those keys
             // again at commit time.
             final boolean deferred = lcc.isEffectivelyDeferred(
-                    lcc.getCurrentSQLSessionContext(activation), indexCID);
+                    lcc.getCurrentSQLSessionContext(activation),
+                    getUniqueConstraintId());
+            // TODO add assert getUniqueConstraintId() != null
 
             ScanController idxScan = tc.openScan(
                     indexCID,
@@ -524,9 +546,7 @@ class IndexChanger
             }
 
             if (duplicate) {
-                if (lcc.isEffectivelyDeferred(
-                        lcc.getCurrentSQLSessionContext(activation),
-                        indexCID)) {
+                if (deferred) {
                     // Save duplicate row so we can check at commit time there is
                     // no longer any duplicate.
 
@@ -534,7 +554,7 @@ class IndexChanger
                         DeferredConstraintsMemory.rememberDuplicate(
                             lcc,
                             deferredDuplicates,
-                            indexCID,
+                            getUniqueConstraintId(),
                             row.getRowArray());
                 } else { // the constraint is not deferred, so throw
                     insertStatus = ConglomerateController.ROWISDUPLICATE;

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexConstantAction.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexConstantAction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/IndexConstantAction.java Wed Jul 30 21:51:54 2014
@@ -37,6 +37,9 @@ public abstract class IndexConstantActio
 	String				tableName;
 	String				schemaName;
 
+    /** Set by CreateConstraintConstantAction */
+    protected transient   UUID    constraintID;
+
 	// CONSTRUCTORS
 
 	/**
@@ -84,4 +87,14 @@ public abstract class IndexConstantActio
 	{
 		this.indexName = indexName;
 	}
+
+    /**
+     * Set the id for the constraint which may be driving this index action.
+     * This is called by CreateConstraintConstantAction.
+     * @param constraintID The id of the constraint
+     */
+    public void setConstraintID(UUID constraintID) {
+        this.constraintID = constraintID;
+    }
+
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/InsertResultSet.java Wed Jul 30 21:51:54 2014
@@ -50,8 +50,10 @@ import org.apache.derby.iapi.sql.diction
 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor;
+import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList;
 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
 import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;
+import org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor;
 import org.apache.derby.iapi.sql.dictionary.StatisticsDescriptor;
 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
 import org.apache.derby.iapi.sql.dictionary.TriggerDescriptor;
@@ -298,7 +300,7 @@ class InsertResultSet extends DMLWriteRe
             deferredChecks =
                     DeferredConstraintsMemory.rememberCheckViolations(
                             lcc,
-                            heapConglom,
+                            constants.targetUUID,
                             schemaName,
                             tableName,
                             deferredChecks,
@@ -1113,7 +1115,7 @@ class InsertResultSet extends DMLWriteRe
                     deferredChecks =
                         DeferredConstraintsMemory.rememberCheckViolations(
                             lcc,
-                            heapConglom,
+                            constants.targetUUID,
                             schemaName,
                             tableName,
                             deferredChecks,
@@ -1235,7 +1237,7 @@ class InsertResultSet extends DMLWriteRe
                         deferredChecks =
                             DeferredConstraintsMemory.rememberCheckViolations(
                                 lcc,
-                                heapConglom,
+                                constants.targetUUID,
                                 schemaName,
                                 tableName,
                                 deferredChecks,
@@ -1927,6 +1929,7 @@ class InsertResultSet extends DMLWriteRe
             boolean deferred = false;
             boolean deferrable = false;
 
+            UUID uniqueDeferrableConstraintId = null;
             if (cd.isConstraint())
             {
                 // so, the index is backing up a constraint
@@ -1937,8 +1940,9 @@ class InsertResultSet extends DMLWriteRe
                 indexOrConstraintName = conDesc.getConstraintName();
                 deferred = lcc.isEffectivelyDeferred(
                         lcc.getCurrentSQLSessionContext(activation),
-                        cd.getConglomerateNumber());
+                        conDesc.getUUID());
                 deferrable = conDesc.deferrable();
+                uniqueDeferrableConstraintId = conDesc.getUUID();
             }
 
             if (indDes.isUnique() || indDes.isUniqueDeferrable())
@@ -1949,9 +1953,8 @@ class InsertResultSet extends DMLWriteRe
 
 				sortObserver = 
                     new UniqueIndexSortObserver(
-                            tc,
                             lcc,
-                            cd.getConglomerateNumber(),
+                            uniqueDeferrableConstraintId,
                             false, // don't clone rows
                             deferrable,
                             deferred,
@@ -1972,9 +1975,8 @@ class InsertResultSet extends DMLWriteRe
                 //use sort operator which treats nulls unequal
                 sortObserver =
                         new UniqueWithDuplicateNullsIndexSortObserver(
-                        tc,
                         lcc,
-                        cd.getConglomerateNumber(),
+                        uniqueDeferrableConstraintId,
                         true,
                         deferrable,
                         deferred,
@@ -2173,12 +2175,6 @@ class InsertResultSet extends DMLWriteRe
 			// Drop the old conglomerate
 			tc.dropConglomerate(constants.indexCIDS[index]);
 
-            // We recreated the index, so any old deferred constraints
-            // information supported by the dropped index needs to be updated
-            // with the new index.
-            DeferredConstraintsMemory.updateIndexCID(
-                    lcc, constants.indexCIDS[index], newIndexCongloms[index]);
-
 			indexConversionTable.put(new Long(constants.indexCIDS[index]),
 									new Long(newIndexCongloms[index]));
 		}
@@ -2495,6 +2491,7 @@ class InsertResultSet extends DMLWriteRe
                 boolean deferred = false;
                 boolean uniqueDeferrable = false;
 
+                UUID uniqueDeferrableConstraintId = null;
 				if (cd.isConstraint()) 
 				{
                     // so, the index is backing up a constraint
@@ -2503,14 +2500,14 @@ class InsertResultSet extends DMLWriteRe
 					indexOrConstraintName = conDesc.getConstraintName();
                     deferred = lcc.isEffectivelyDeferred(
                             lcc.getCurrentSQLSessionContext(activation),
-                            cd.getConglomerateNumber());
+                            conDesc.getUUID());
                     uniqueDeferrable = conDesc.deferrable();
+                    uniqueDeferrableConstraintId = conDesc.getUUID();
 				}
 				sortObserver = 
                     new UniqueIndexSortObserver(
-                            tc,
                             lcc,
-                            cd.getConglomerateNumber(),
+                            uniqueDeferrableConstraintId,
                             false, // don't clone rows
                             uniqueDeferrable,
                             deferred,

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ProjectRestrictResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ProjectRestrictResultSet.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ProjectRestrictResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ProjectRestrictResultSet.java Wed Jul 30 21:51:54 2014
@@ -22,6 +22,7 @@
 package org.apache.derby.impl.sql.execute;
 
 import java.util.Enumeration;
+import org.apache.derby.catalog.UUID;
 import org.apache.derby.catalog.types.ReferencedColumnsDescriptorImpl;
 import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.services.loader.GeneratedMethod;
@@ -72,7 +73,7 @@ class ProjectRestrictResultSet extends N
 
 	private ExecRow projRow;
     private final boolean validatingCheckConstraint;
-    private final long validatingBaseTableCID;
+    private final UUID validatingBaseTableUUID;
     Enumeration<Object> rowLocations;
 
     // class interface
@@ -88,7 +89,7 @@ class ProjectRestrictResultSet extends N
 					boolean reuseResult,
 					boolean doesProjection,
                     boolean validatingCheckConstraint,
-                    long validatingBaseTableCID,
+                    UUID validatingBaseTableUUID,
 				    double optimizerEstimatedRowCount,
 					double optimizerEstimatedCost) 
 		throws StandardException
@@ -109,7 +110,7 @@ class ProjectRestrictResultSet extends N
 		this.reuseResult = reuseResult;
 		this.doesProjection = doesProjection;
         this.validatingCheckConstraint = validatingCheckConstraint;
-        this.validatingBaseTableCID = validatingBaseTableCID;
+        this.validatingBaseTableUUID = validatingBaseTableUUID;
 
 		// Allocate a result row if all of the columns are mapped from the source
 		if (projection == null)
@@ -172,7 +173,7 @@ class ProjectRestrictResultSet extends N
         if (validatingCheckConstraint) {
             rowLocations = DeferredConstraintsMemory.
                 getDeferredCheckConstraintLocations(
-                        activation, validatingBaseTableCID);
+                        activation, validatingBaseTableUUID);
         }
 
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RIBulkChecker.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RIBulkChecker.java?rev=1614777&r1=1614776&r2=1614777&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RIBulkChecker.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RIBulkChecker.java Wed Jul 30 21:51:54 2014
@@ -290,8 +290,6 @@ public class RIBulkChecker 
                     DeferredConstraintsMemory.rememberFKViolation(
                             lcc,
                             deferredRowsHashTable,
-                            fkCID,
-                            pkCID,
                             constraintId,
                             foreignKeyRow,
                             schemaName,



Mime
View raw message