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 2014/03/11 15:46:17 UTC

svn commit: r1576367 [2/4] - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/error/ engine/org/apache/derby/iapi/sql/compile/ engine/org/apache/derby/iapi/sql/conn/ engine/org/apache/derby/iapi/sql/dictionary/ engine/org/apache/derby/iapi/sq...

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj Tue Mar 11 14:46:15 2014
@@ -10422,60 +10422,97 @@ tableColumnList() throws StandardExcepti
 }
 
 /*
- * This method is called when a comment starting with --derby-properties is found.
- * Such a comment is a special directive to Derby and allows a sql to pass optimizer
- * overrides. Derby looks for propertyName=value [,propertyName=value]* after
- * --derby-properties and returns these properties in a Properties object as a return 
- * value of this method.
- * The param propertiesUseAllowed true indicates that users are allowed to 
- * specify optimizer overrides in the given context. 
- * False means optimizer overrides in the given context are allowed internally 
- * only eg impl/load/import.java specifies property insertMode=replace/bulkInsert
- * in the insert statement. This same property will not be acceptable from an 
- * insert statement from a user sql.
+ * This method is called when a comment starting with "--derby-properties" is
+ * found.  Such a comment is a special directive to Derby and allows an SQL
+ * statement to pass optimizer overrides. Derby looks for
+ *
+ *     propertyName = value* [, propertyName = value]*
+ *
+ * after "--derby-properties" and returns these properties in a Properties
+ * object as a return value of this method.  If the parameter
+ * "propertiesUseAllowed" is true, it indicates that users are allowed to
+ * specify optimizer overrides in the given context.  False means optimizer
+ * overrides in the given context are allowed internally only, e.g. by the
+ * class org.apache.derby.impl.load.Import specifies the property
+ * "insertMode=replace/bulkInsert" in the INSERT statement. This same property
+ * will not be acceptable from an INSERT statement from a user SQL statement.
  */
 Properties
 propertyList(boolean propertiesUseAllowed) throws StandardException :
 {
 	Properties properties = new FormatableProperties();
 	StringTokenizer commaSeparatedProperties;
-	StringTokenizer equalOperatorSeparatedProperty;
+
 }
 {
-	<DERBYDASHPROPERTIES> {
-		//first use StringTokenizer to get tokens which are delimited by ,s
-		commaSeparatedProperties = new StringTokenizer(getToken(1).image,",");
-		while (commaSeparatedProperties.hasMoreTokens()) {
-			//Now verify that tokens delimited by ,s follow propertyName=value pattern
-			String currentProperty = commaSeparatedProperties.nextToken();
-			equalOperatorSeparatedProperty = new StringTokenizer(currentProperty,"=", true);
-			if (equalOperatorSeparatedProperty.countTokens() != 3)
-				throw StandardException.newException(SQLState.PROPERTY_SYNTAX_INVALID);
-			else {
-				String key = equalOperatorSeparatedProperty.nextToken().trim();
-				if (!equalOperatorSeparatedProperty.nextToken().equals("="))
-					throw StandardException.newException(SQLState.PROPERTY_SYNTAX_INVALID);
-				String value = equalOperatorSeparatedProperty.nextToken().trim();
-				verifyImageLength(value);
-				/* Trim off the leading and trailing ', and compress all '' to ' */
-				if (value.startsWith("'") && value.endsWith("'"))
-					value = StringUtil.compressQuotes(value.substring(1, value.length() - 1), SINGLEQUOTES);
-				/* Trim off the leading and trailing ", and compress all "" to " */
-				else if (value.startsWith("\"") && value.endsWith("\""))
-					value = StringUtil.compressQuotes(value.substring(1, value.length() - 1), DOUBLEQUOTES);
-				else 
-					value = value.toUpperCase();
-				// Do not allow user to specify multiple values for the same key
-				if (properties.put(key, value) != null)
-				{
-					throw StandardException.newException(SQLState.LANG_DUPLICATE_PROPERTY, key);
-				}
-		}
-	}
-	//if this property override is supported in internal mode only, then do that verification here.
-	if (!propertiesUseAllowed) 
-		checkInternalFeature("DERBY-PROPERTIES");
-	return properties;
+    <DERBYDASHPROPERTIES> {
+        // First use StringTokenizer to get tokens which are delimited by
+        // commas
+        commaSeparatedProperties = new StringTokenizer(getToken(1).image, ",");
+
+        while (commaSeparatedProperties.hasMoreTokens()) {
+
+            // Now verify that tokens delimited by commas follow
+            // "propertyName=value" pattern
+            String currentProperty = commaSeparatedProperties.nextToken();
+
+            // Use a new tokenizer to parse "propertyName=value". Let it
+            // return the '=' delimiter as well.
+            StringTokenizer equalOperatorSeparatedProperty =
+                new StringTokenizer(currentProperty, "=", true);
+
+            if (equalOperatorSeparatedProperty.countTokens() != 3) {
+                // should see exactly three tokens: propertyName, '=' and
+                // value.
+                throw StandardException.newException(
+                    SQLState.PROPERTY_SYNTAX_INVALID);
+            } else {
+                // ignore blanks around key
+                String key = equalOperatorSeparatedProperty.nextToken().trim();
+
+                if (!equalOperatorSeparatedProperty.nextToken().equals("=")) {
+                    throw StandardException.newException(
+                        SQLState.PROPERTY_SYNTAX_INVALID);
+                }
+
+                // Also ignore blanks around value, canonize to upper case
+                // unless we have surrounding quotes.
+                String value =
+                    equalOperatorSeparatedProperty.nextToken().trim();
+
+                verifyImageLength(value);
+
+                if (value.startsWith("'") && value.endsWith("'")) {
+                    // Trim off the leading and trailing ', and compress all
+                    // '' to '
+                    value = StringUtil.compressQuotes(
+                        value.substring(1, value.length() - 1), SINGLEQUOTES);
+                } else if (value.startsWith("\"") && value.endsWith("\"")) {
+                    // Trim off the leading and trailing ", and compress all
+                    // "" to "
+                    value = StringUtil.compressQuotes(
+                        value.substring(1, value.length() - 1), DOUBLEQUOTES);
+
+                } else {
+                    value = value.toUpperCase();
+                }
+
+                // Do not allow user to specify multiple values for the same
+                // key.
+                if (properties.put(key, value) != null) {
+                    throw StandardException.newException(
+                        SQLState.LANG_DUPLICATE_PROPERTY, key);
+                }
+            }
+        }
+
+        // If this property override is supported in internal mode only, then
+        // do that verification here.
+        if (!propertiesUseAllowed) {
+            checkInternalFeature("DERBY-PROPERTIES");
+        }
+
+        return properties;
 	}
 }
 

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=1576367&r1=1576366&r2=1576367&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 Tue Mar 11 14:46:15 2014
@@ -21,7 +21,6 @@
 
 package org.apache.derby.impl.sql.conn;
 
-import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.IdentityHashMap;
@@ -78,7 +77,6 @@ import org.apache.derby.iapi.sql.execute
 import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;
 import org.apache.derby.iapi.sql.execute.ExecutionStmtValidator;
 import org.apache.derby.iapi.sql.execute.RunTimeStatistics;
-import org.apache.derby.iapi.store.access.BackingStoreHashtable;
 import org.apache.derby.iapi.store.access.TransactionController;
 import org.apache.derby.iapi.store.access.XATransactionController;
 import org.apache.derby.iapi.transaction.TransactionControl;
@@ -89,9 +87,11 @@ import org.apache.derby.impl.sql.Generic
 import org.apache.derby.impl.sql.GenericStatement;
 import org.apache.derby.impl.sql.compile.CompilerContextImpl;
 import org.apache.derby.impl.sql.execute.AutoincrementCounter;
-import org.apache.derby.impl.sql.execute.DeferredDuplicates;
+import org.apache.derby.impl.sql.execute.DeferredConstraintsMemory;
+import org.apache.derby.impl.sql.execute.DeferredConstraintsMemory.CheckInfo;
+import org.apache.derby.impl.sql.execute.DeferredConstraintsMemory.UniquePkInfo;
+import org.apache.derby.impl.sql.execute.DeferredConstraintsMemory.ValidationInfo;
 import org.apache.derby.shared.common.sanity.SanityManager;
-
 /**
  * LanguageConnectionContext keeps the pool of prepared statements,
  * activations, and cursors in use by the current connection.
@@ -316,7 +316,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, BackingStoreHashtable> deferredHashTables;
+    private HashMap<Long, ValidationInfo> deferredHashTables;
 
     /*
        constructor
@@ -3751,7 +3751,8 @@ public class GenericLanguageConnectionCo
 
         final SQLSessionContext ssc = getCurrentSQLSessionContext(a);
         sc.setDeferredAll(ssc.getDeferredAll());
-        sc.setConstraintModes(ssc.getConstraintModes());
+        sc.setConstraintModes(ssc.getUniquePKConstraintModes());
+        sc.setCheckConstraintModes(ssc.getCheckConstraintModes());
 
         StatementContext stmctx = getStatementContext();
 
@@ -3796,24 +3797,67 @@ 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.
-        Set<Map.Entry<Long, BackingStoreHashtable>> es =
-                deferredHashTables.entrySet();
+        Set<Map.Entry<Long, ValidationInfo>> es = deferredHashTables.entrySet();
 
-        for (Map.Entry<Long, BackingStoreHashtable> e : es) {
-            final long indexCID = e.getKey().longValue();
+        for (Map.Entry<Long, ValidationInfo> e : es) {
 
-            boolean effectivelyDeferred = effectivelyDeferred(caller, indexCID);
+            if (e.getValue() instanceof UniquePkInfo) {
 
-            if (effectivelyDeferred ) {
-                // the constraint is also deferred in the calling context
-                continue;
-            }
-            // The constraint must have been deferred inside the routine
-            if (SanityManager.DEBUG) {
-                SanityManager.ASSERT(effectivelyDeferred(nested, indexCID));
-            }
+                final long indexCID = e.getKey().longValue();
+
+                boolean effectivelyDeferred =
+                    effectivelyDeferred(caller, indexCID);
+
+                if (effectivelyDeferred ) {
+                    // the constraint is also deferred in the calling context
+                    continue;
+                }
 
-            doValidateConstraint(e.getKey().longValue(), e.getValue(), true);
+                doValidateUniquePKConstraint(
+                    e.getKey().longValue(),
+                    (UniquePkInfo)e.getValue(),
+                    true);
+
+            } else if (e.getValue() instanceof CheckInfo) {
+
+                final long baseTableCID = e.getKey().longValue();
+                CheckInfo ci = (CheckInfo)e.getValue();
+
+                // check if any of the constraints involved is immediate on
+                // the outside
+                boolean allEffectivelyDeferred = true;
+
+                for (UUID uid : ci.getCulprints()) {
+                    if (!effectivelyDeferred(caller, uid) &&
+                        effectivelyDeferred(nested, uid)) {
+
+                        // at least one check constraint changed back
+                        // from being deferred to immediate, so check
+                        // all immediates
+
+                        // FIXME: could be optimized if we knew
+                        // exactly which constraints failed under the
+                        // deferred regime: that might save us from
+                        // checking in a few cases.
+                        allEffectivelyDeferred = false;
+                        break;
+                    }
+                }
+
+                if (allEffectivelyDeferred) {
+                    continue;
+                }
+
+                doValidateUniqueCheckConstraints(
+                    baseTableCID,
+                    null,
+                    (CheckInfo)e.getValue(),
+                    true);
+            } else {
+                if (SanityManager.DEBUG) {
+                    SanityManager.NOTREACHED();
+                }
+            }
         }
     }
 
@@ -3840,6 +3884,26 @@ public class GenericLanguageConnectionCo
         return effectivelyDeferred;
     }
 
+    private boolean effectivelyDeferred(SQLSessionContext sc, UUID constraintId)
+            throws StandardException {
+
+        final Boolean deferred = sc.isDeferred(constraintId);
+        final boolean effectivelyDeferred;
+        final DataDictionary dd = getDataDictionary();
+
+        if (deferred != null) {
+            effectivelyDeferred = deferred.booleanValue();
+        } else {
+            // no explicit setting applicable, use initial constraint mode
+            final ConstraintDescriptor conDesc =
+                    dd.getConstraintDescriptor(constraintId);
+            effectivelyDeferred = conDesc.initiallyDeferred();
+        }
+
+        return effectivelyDeferred;
+    }
+
+
     /**
      * @see LanguageConnectionContext#setupSubStatementSessionContext(Activation a)
      */
@@ -3944,33 +4008,76 @@ public class GenericLanguageConnectionCo
     }
 
     /**
-     * {@inheritDoc}
-     */
-    public void setDeferred(Activation a, long conglomId, boolean deferred)
-            throws StandardException {
+     * For check constraints
+     *
+     * @param a             activation
+     * @param basetableCID  the conglomerate id of the base table on which
+     *                      the constraint is defined
+     * @param constraintId  the constraint id
+     * @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 whats done in this transaction first
-            validateDeferredConstraint(conglomId);
+            // Moving to immediate, check what's done in this transaction first
+            validateDeferredConstraint(basetableCID, constraintId);
         }
-        getCurrentSQLSessionContext(a).setDeferred(conglomId, deferred);
+
+        getCurrentSQLSessionContext(a).setDeferred(constraintId, deferred);
     }
 
-    public boolean isEffectivelyDeferred(Activation a, long conglomId)
-            throws StandardException {
+    /**
+     * 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,
+            final boolean deferred) throws StandardException {
+
+        if (!deferred) {
+            // Moving to immediate, check what's done in this transaction first
+            validateDeferredConstraint(indexCID, null);
+        }
+
+        getCurrentSQLSessionContext(a).setDeferred(indexCID, deferred);
+
+    }
+
+    public boolean isEffectivelyDeferred(
+            final Activation a,
+            long conglomId) throws StandardException {
+
         return effectivelyDeferred(getCurrentSQLSessionContext(a), conglomId);
     }
 
+    public boolean isEffectivelyDeferred(
+            final Activation a,
+            final UUID constraintId) throws StandardException {
+
+        return effectivelyDeferred(getCurrentSQLSessionContext(a),
+                                   constraintId);
+    }
 
     public void checkIntegrity() throws StandardException {
         validateDeferredConstraints(true);
         clearDeferreds();
     }
 
-    public void invalidateDeferredConstraintsData(long indexCID)
+    public void forgetDeferredConstraintsData(final long conglomId)
             throws StandardException {
         if (deferredHashTables != null &&
-                deferredHashTables.containsKey(Long.valueOf(indexCID))) {
-            deferredHashTables.remove(Long.valueOf(indexCID));
+                deferredHashTables.containsKey(Long.valueOf(conglomId))) {
+            deferredHashTables.remove(Long.valueOf(conglomId));
         }
     }
 
@@ -3985,7 +4092,7 @@ public class GenericLanguageConnectionCo
     /**
      * {@inheritDoc}
      */
-    public void setDeferredAll(Activation a, boolean deferred)
+    public void setDeferredAll(final Activation a, final boolean deferred)
             throws StandardException {
         if (!deferred) {
             validateDeferredConstraints(false);
@@ -4000,49 +4107,86 @@ public class GenericLanguageConnectionCo
     /**
      * {@inheritDoc}
      */
-    public HashMap<Long, BackingStoreHashtable> getDeferredHashTables() {
+    public HashMap<Long, ValidationInfo> getDeferredHashTables() {
         if (deferredHashTables == null) {
-            deferredHashTables = new HashMap<Long, BackingStoreHashtable>();
+            deferredHashTables = new HashMap<Long, ValidationInfo>();
         }
         return deferredHashTables;
     }
 
-    private void validateDeferredConstraints(boolean rollbackOnError)
+    private void validateDeferredConstraints(final boolean rollbackOnError)
             throws StandardException {
+
         if (deferredHashTables == null) {
             // Nothing to do
             return;
         }
 
-        Set<Map.Entry<Long, BackingStoreHashtable>> es =
+        final Set<Map.Entry<Long, ValidationInfo>> es =
                 deferredHashTables.entrySet();
 
-        for (Map.Entry<Long, BackingStoreHashtable> e : es) {
-            doValidateConstraint(e.getKey().longValue(),
-                                 e.getValue(),
-                                 rollbackOnError);
+        for (Map.Entry<Long, ValidationInfo> e : es) {
+            if (e.getValue() instanceof UniquePkInfo) {
+                doValidateUniquePKConstraint(e.getKey().longValue(),
+                        (UniquePkInfo)e.getValue(),
+                        rollbackOnError);
+            } else if (e.getValue() instanceof CheckInfo) {
+                doValidateUniqueCheckConstraints(e.getKey().longValue(),
+                        null,
+                        (CheckInfo)e.getValue(),
+                        rollbackOnError);
+            } else {
+                if (SanityManager.DEBUG) {
+                    SanityManager.NOTREACHED();
+                }
+            }
         }
     }
 
 
-    private void validateDeferredConstraint(long indexCID)
-            throws StandardException {
-        BackingStoreHashtable ht = null;
+    private void validateDeferredConstraint(
+        final long conglomCID,
+        final UUID constraintId) throws StandardException {
+
+        ValidationInfo vi = null;
 
         if (deferredHashTables == null ||
-            (ht = deferredHashTables.get(indexCID)) == null) {
+            (vi = deferredHashTables.get(conglomCID)) == null) {
             // Nothing to do
             return;
         }
-        doValidateConstraint(indexCID, ht, false);
-        deferredHashTables.remove(indexCID);
+
+        if (vi instanceof CheckInfo) {
+            doValidateUniqueCheckConstraints(
+                conglomCID, constraintId, (CheckInfo)vi, false);
+        } else if (vi instanceof UniquePkInfo) {
+            doValidateUniquePKConstraint(conglomCID, (UniquePkInfo)vi, false);
+        } else {
+            if (SanityManager.DEBUG) {
+                SanityManager.NOTREACHED();
+            }
+        }
+
+        deferredHashTables.remove(conglomCID);
     }
 
-    private void doValidateConstraint(
-        long indexCID,
-        BackingStoreHashtable ht,
-        boolean rollbackOnError) throws StandardException {
+    private void doValidateUniquePKConstraint(
+        final long indexCID,
+        final UniquePkInfo ui,
+        final boolean rollbackOnError) throws StandardException {
 
-        DeferredDuplicates.validate(tran, indexCID, this, ht, rollbackOnError);
+        DeferredConstraintsMemory.validateUniquePK(
+                this, indexCID, ui.infoRows, rollbackOnError);
     }
+
+    private void doValidateUniqueCheckConstraints(
+        final long baseTableCID,
+        final UUID constraintId,
+        final CheckInfo ci,
+        final boolean rollbackOnError) throws StandardException {
+
+        DeferredConstraintsMemory.validateCheck(
+                this, baseTableCID, constraintId, ci, rollbackOnError);
+    }
+
 }

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=1576367&r1=1576366&r2=1576367&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 Tue Mar 11 14:46:15 2014
@@ -22,6 +22,7 @@
 package org.apache.derby.impl.sql.conn;
 
 import java.util.HashMap;
+import org.apache.derby.catalog.UUID;
 import org.apache.derby.iapi.sql.conn.SQLSessionContext;
 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
 
@@ -32,13 +33,23 @@ public class SQLSessionContextImpl imple
     private SchemaDescriptor currentDefaultSchema;
 
     /**
-     * Maps a conglomerate id (key) into a Boolean for deferrable constraints.
+     * 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> constraintModes;
+    private HashMap<Long, Boolean> uniquePKConstraintModes;
+
+    /**
+     * Maps a constraint id (key) into a Boolean for deferrable check
+     * 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;
 
     /**
      * True if all deferrable constraints are deferred in this transaction.
@@ -51,10 +62,6 @@ public class SQLSessionContextImpl imple
         currentRole = null;
         currentDefaultSchema = sd;
         this.currentUser = currentUser;
-
-        if (constraintModes != null) {
-            this.constraintModes = new HashMap<Long,Boolean>(constraintModes);
-        }
     }
 
     public void setRole(String role) {
@@ -84,9 +91,15 @@ public class SQLSessionContextImpl imple
     /**
      * {@inheritDoc}
      */
-    public HashMap<Long, Boolean> getConstraintModes() {
-        return constraintModes != null ?
-            new HashMap<Long, Boolean>(constraintModes) :
+    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) :
             null;
     }
 
@@ -94,30 +107,59 @@ public class SQLSessionContextImpl imple
      * {@inheritDoc}
      */
     public void setConstraintModes(HashMap<Long, Boolean> hm) {
-        this.constraintModes = hm != null ?
+        this.uniquePKConstraintModes = hm != null ?
                 new HashMap<Long, Boolean>(hm) : null;
     }
 
+    public void setCheckConstraintModes(HashMap<UUID, Boolean> hm) {
+        this.checkConstraintModes = hm != null ?
+                new HashMap<UUID, Boolean>(hm) : null;
+    }
+
     /**
      * {@inheritDoc}
      */
     public void setDeferred(long conglomId, boolean deferred) {
-        if (constraintModes == null) {
-            constraintModes = new HashMap<Long, Boolean>();
+        if (uniquePKConstraintModes == null) {
+            uniquePKConstraintModes = new HashMap<Long, Boolean>();
         }
 
-        constraintModes.put(Long.valueOf(conglomId),
+        uniquePKConstraintModes.put(Long.valueOf(conglomId),
                                 Boolean.valueOf(deferred));
     }
 
+    public void setDeferred(UUID constraintId, boolean deferred) {
+        if (checkConstraintModes == null) {
+            checkConstraintModes = new HashMap<UUID, Boolean>();
+        }
+
+        checkConstraintModes.put(constraintId, Boolean.valueOf(deferred));
+    }
+
     /**
      * {@inheritDoc}
      */
     public Boolean isDeferred(long conglomId) {
         Boolean v = null;
 
-        if (constraintModes != null) {
-            v = constraintModes.get(Long.valueOf(conglomId));
+        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 (v != null) {
@@ -129,12 +171,17 @@ public class SQLSessionContextImpl imple
         }
     }
 
+
     /**
      * {@inheritDoc}
      */
     public void resetConstraintModes() {
-        if (constraintModes != null) {
-            constraintModes.clear();
+        if (uniquePKConstraintModes != null) {
+            uniquePKConstraintModes.clear();
+        }
+
+        if (checkConstraintModes != null) {
+            checkConstraintModes.clear();
         }
 
         deferredAll = null;
@@ -147,8 +194,12 @@ public class SQLSessionContextImpl imple
         deferredAll = deferred;
         // This now overrides any individual constraint setting, so
         // clear those.
-        if (constraintModes != null) {
-            constraintModes.clear();
+        if (uniquePKConstraintModes != null) {
+            uniquePKConstraintModes.clear();
+        }
+
+        if (checkConstraintModes != null) {
+            checkConstraintModes.clear();
         }
     }
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterConstraintConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterConstraintConstantAction.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterConstraintConstantAction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterConstraintConstantAction.java Tue Mar 11 14:46:15 2014
@@ -160,7 +160,6 @@ public class AlterConstraintConstantActi
                             "DEFERRED CONSTRAINTS");
 
             if (constraintType == DataDictionary.FOREIGNKEY_CONSTRAINT ||
-                constraintType == DataDictionary.CHECK_CONSTRAINT ||
                 constraintType == DataDictionary.NOTNULL_CONSTRAINT ||
                 !characteristics[2] /* not enforced */) {
 

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=1576367&r1=1576366&r2=1576367&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 Tue Mar 11 14:46:15 2014
@@ -22,6 +22,7 @@
 package org.apache.derby.impl.sql.execute;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Properties;
 
@@ -314,6 +315,27 @@ class AlterTableConstantAction extends D
 		int							numRows = 0;
         boolean						tableScanned = false;
 
+        if (compressTable || truncateTable) {
+            final HashMap<Long, DeferredConstraintsMemory.ValidationInfo> vis =
+                    lcc.getDeferredHashTables();
+            td = dd.getTableDescriptor(tableId);
+            final DeferredConstraintsMemory.ValidationInfo vi =
+                    vis.get(td.getHeapConglomerateId());
+
+            if (td == null) {
+                throw StandardException.newException(
+                    SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, tableName);
+            }
+
+            if (vi != null &&
+                vi instanceof DeferredConstraintsMemory.CheckInfo) {
+                // We can not use row locations when re-visiting offending
+                // rows in this table, since we are truncating or compressing.
+                ((DeferredConstraintsMemory.CheckInfo)vi).
+                    setInvalidatedRowLocations();
+            }
+        }
+
         //Following if is for inplace compress. Compress using temporary
         //tables to do the compression is done later in this method.
 		if (compressTable)
@@ -420,6 +442,7 @@ class AlterTableConstantAction extends D
 		else
 			dm.invalidateFor(td, DependencyManager.ALTER_TABLE, lcc);
 
+
 		// Are we working on columns?
 		if (columnInfo != null)
 		{
@@ -546,10 +569,18 @@ class AlterTableConstantAction extends D
                  conIndex++)
 			{
 				ConstraintConstantAction cca = constraintActions[conIndex];
+                boolean isCheckInitiallyDeferred = false;
 
 				if (cca instanceof CreateConstraintConstantAction)
 				{
-					int constraintType = cca.getConstraintType();
+                    final CreateConstraintConstantAction ccca =
+                            (CreateConstraintConstantAction)cca;
+
+                    int constraintType = ccca.getConstraintType();
+
+                    isCheckInitiallyDeferred =
+                        (constraintType == DataDictionary.CHECK_CONSTRAINT) &&
+                        ccca.isInitiallyDeferred();
 
 					/* Some constraint types require special checking:
 					 *   Check		 - table must be empty, for now
@@ -586,6 +617,14 @@ class AlterTableConstantAction extends D
 								tableScanned = true;
 								numRows = getSemiRowCount(tc);
 							}
+
+                            if (isCheckInitiallyDeferred) {
+                                // Need to do this early to get UUID
+                                // assigned
+                                constraintActions[conIndex].
+                                        executeConstantAction(activation);
+                            }
+
 							if (numRows > 0)
 							{
 								/*
@@ -594,11 +633,15 @@ class AlterTableConstantAction extends D
 								** is ok to do the check now rather than try
 								** to lump together several checks.	
 								*/
+
 								ConstraintConstantAction.validateConstraint(
                                     cca.getConstraintName(),
                                     ((CreateConstraintConstantAction)cca).getConstraintText(),
+                                    cca.getConstraintId(),
                                     td,
-                                    lcc, true);
+                                    lcc,
+                                    true,
+                                    isCheckInitiallyDeferred);
 							}
 							break;
 					}
@@ -619,7 +662,10 @@ class AlterTableConstantAction extends D
 					}
 				}
 
-				constraintActions[conIndex].executeConstantAction(activation);
+                if (!isCheckInitiallyDeferred) {
+                    constraintActions[conIndex].
+                        executeConstantAction(activation);
+                } // else it is done early, see above.
 			}
 		}
 
@@ -3144,7 +3190,12 @@ class AlterTableConstantAction extends D
 		return (numIndexes > 0);
 	}
 
-	/**
+    public boolean needsRowLocationForDeferredCheckConstraints()
+    {
+        return false;
+    }
+
+    /**
 	 * @see RowLocationRetRowSource#rowLocation
 	 * @exception StandardException on error
 	 */
@@ -3518,11 +3569,13 @@ class AlterTableConstantAction extends D
 		if (foundNullable && numRows > 0)
 		{
 			if (!ConstraintConstantAction.validateConstraint(
-									(String) null,
-									constraintText.toString(),
-									td,
-									lcc,
-									false))
+                    (String) null,
+                    constraintText.toString(),
+                    null, /* not used for not nullable constraints yet */
+                    td,
+                    lcc,
+                    false,
+                    false /* not used for not nullable constraints yet */))
 			{	
 				if (errorMsg.equals(SQLState.LANG_NULL_DATA_IN_PRIMARY_KEY_OR_UNIQUE_CONSTRAINT))
 				{	//alter table add primary key
@@ -3623,4 +3676,11 @@ class AlterTableConstantAction extends D
 			return null;
 	}
 
+    public void offendingRowLocation(
+            RowLocation rl, long containdId) throws StandardException {
+        if (SanityManager.DEBUG) {
+            SanityManager.NOTREACHED();
+        }
+    }
+
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CardinalityCounter.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CardinalityCounter.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CardinalityCounter.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CardinalityCounter.java Tue Mar 11 14:46:15 2014
@@ -26,6 +26,7 @@ import org.apache.derby.iapi.error.Stand
 import org.apache.derby.iapi.store.access.RowLocationRetRowSource;
 import org.apache.derby.iapi.types.DataValueDescriptor;
 import org.apache.derby.iapi.types.RowLocation;
+import org.apache.derby.shared.common.sanity.SanityManager;
 
 /**
  * This is a decorator (in Design Patterns Terminology)
@@ -53,6 +54,18 @@ class CardinalityCounter implements RowL
 		return rowSource.needsRowLocation();
 	}
 
+
+    public boolean needsRowLocationForDeferredCheckConstraints()
+    {
+        return rowSource.needsRowLocationForDeferredCheckConstraints();
+    }
+
+    public void offendingRowLocation(
+            RowLocation rl, long containdId) throws StandardException {
+        rowSource.offendingRowLocation(rl, containdId);
+    }
+
+
 	/** @see RowLocationRetRowSource#rowLocation */
 	public void rowLocation(RowLocation rl) throws StandardException
 	{ 

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=1576367&r1=1576366&r2=1576367&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 Tue Mar 11 14:46:15 2014
@@ -21,11 +21,13 @@
 
 package org.apache.derby.impl.sql.execute;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
 import org.apache.derby.catalog.UUID;
 import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.reference.SQLState;
 import org.apache.derby.iapi.services.io.FormatableBitSet;
-import org.apache.derby.shared.common.sanity.SanityManager;
 import org.apache.derby.iapi.sql.PreparedStatement;
 import org.apache.derby.iapi.sql.ResultSet;
 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
@@ -34,12 +36,17 @@ import org.apache.derby.iapi.sql.diction
 import org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor;
 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
 import org.apache.derby.iapi.sql.execute.ExecRow;
+import org.apache.derby.iapi.store.access.BackingStoreHashtable;
 import org.apache.derby.iapi.store.access.ConglomerateController;
 import org.apache.derby.iapi.store.access.GroupFetchScanController;
 import org.apache.derby.iapi.store.access.ScanController;
 import org.apache.derby.iapi.store.access.TransactionController;
 import org.apache.derby.iapi.types.DataValueDescriptor;
 import org.apache.derby.iapi.types.NumberDataValue;
+import org.apache.derby.impl.sql.execute.DeferredConstraintsMemory.CheckInfo;
+import org.apache.derby.impl.sql.execute.DeferredConstraintsMemory.ValidationInfo;
+import org.apache.derby.impl.store.access.heap.HeapRowLocation;
+import org.apache.derby.shared.common.sanity.SanityManager;
 /**
  *	This class  describes actions that are ALWAYS performed for a
  *	constraint creation at Execution time.
@@ -56,6 +63,7 @@ public abstract class ConstraintConstant
 	protected	String			schemaName;
 	protected	UUID			schemaId;
 	protected  IndexConstantAction indexAction;
+    protected   UUID            constraintId;
 
 	// CONSTRUCTORS
 	/**
@@ -110,6 +118,15 @@ public abstract class ConstraintConstant
 	  */
     public	String	getConstraintName() { return constraintName; }
 
+    /**
+     * Get the constraint id of the constraint
+     * @return constraint id
+     */
+    public UUID getConstraintId() {
+        return constraintId;
+    }
+
+
 	/**
 	  *	Get the associated index constant action.
 	  *
@@ -252,9 +269,12 @@ public abstract class ConstraintConstant
 	 *
 	 * @param constraintName	constraint name
 	 * @param constraintText	constraint text
+     * @param constraintId      constraint id
 	 * @param td				referenced table
 	 * @param lcc				the language connection context
 	 * @param isCheckConstraint	the constraint is a check constraint
+     * @param isInitiallyDeferred {@code true} if the constraint is
+     *                          initially deferred
      *
 	 * @return true if null constraint passes, false otherwise
 	 *
@@ -264,9 +284,11 @@ public abstract class ConstraintConstant
 	(
 		String							constraintName,
 		String							constraintText,
+        UUID                            constraintId,
 		TableDescriptor					td,
 		LanguageConnectionContext		lcc,
-		boolean							isCheckConstraint
+        boolean                         isCheckConstraint,
+        boolean                         isInitiallyDeferred
 	)
 		throws StandardException
 	{
@@ -306,10 +328,40 @@ public abstract class ConstraintConstant
 			*/
 			if ((value != null) && (value.longValue() != 0))
 			{	
-				//check constraint violated
-				if (isCheckConstraint)
-					throw StandardException.newException(SQLState.LANG_ADD_CHECK_CONSTRAINT_FAILED, 
-						constraintName, td.getQualifiedName(), value.toString());
+                // The query yielded a valid value > 0, so we must conclude the
+                // check constraint is violated.
+                if (isCheckConstraint) {
+                    if (isInitiallyDeferred) {
+                        // Remember the violation
+                        List<UUID> violatingConstraints = new ArrayList<UUID>();
+                        violatingConstraints.add(constraintId);
+
+                        // FIXME: We don't know the row locations of the
+                        // violating rows, so for now, just pretend we know one,
+                        // then invalidate the row location information forcing
+                        // full table check at validation time
+                        DeferredConstraintsMemory.rememberCheckViolations(
+                                lcc,
+                                td.getHeapConglomerateId(),
+                                td.getSchemaName(),
+                                td.getName(),
+                                null,
+                                violatingConstraints,
+                                new HeapRowLocation() /* dummy */);
+                        HashMap<Long, ValidationInfo>
+                                hashTables = lcc.getDeferredHashTables();
+                        CheckInfo ci = (CheckInfo)hashTables.get(
+                                Long.valueOf(td.getHeapConglomerateId()));
+                        ci.setInvalidatedRowLocations();
+
+                    } else {
+                        throw StandardException.newException(
+                                SQLState.LANG_ADD_CHECK_CONSTRAINT_FAILED,
+                                constraintName,
+                                td.getQualifiedName(),
+                                value.toString());
+                    }
+                }
 				/*
 				 * for not null constraint violations exception will be thrown in caller
 				 * check constraint will not get here since exception is thrown

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=1576367&r1=1576366&r2=1576367&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 Tue Mar 11 14:46:15 2014
@@ -282,7 +282,7 @@ public class CreateConstraintConstantAct
 			indexId = conglomDesc.getUUID();
 		}
 
-		UUID constraintId = uuidFactory.createUUID();
+        UUID constrId=  uuidFactory.createUUID();
 
         boolean[] defaults = new boolean[]{
             ConstraintDefinitionNode.DEFERRABLE_DEFAULT,
@@ -296,7 +296,6 @@ public class CreateConstraintConstantAct
                                 "DEFERRED CONSTRAINTS");
 
                 if (constraintType == DataDictionary.FOREIGNKEY_CONSTRAINT ||
-                    constraintType == DataDictionary.CHECK_CONSTRAINT ||
                     constraintType == DataDictionary.NOTNULL_CONSTRAINT ||
                     !characteristics[2] /* not enforced */) {
 
@@ -322,7 +321,7 @@ public class CreateConstraintConstantAct
                                 characteristics[0], //deferable,
                                 characteristics[1], //initiallyDeferred,
 								genColumnPositions(td, false), //int[],
-								constraintId, 
+                                constrId,
 								indexId, 
 								sd,
                                 characteristics[2],
@@ -337,7 +336,7 @@ public class CreateConstraintConstantAct
                                 characteristics[0], //deferable,
                                 characteristics[1], //initiallyDeferred,
 								genColumnPositions(td, false), //int[],
-								constraintId, 
+                                constrId,
 								indexId, 
 								sd,
                                 characteristics[2],
@@ -351,7 +350,7 @@ public class CreateConstraintConstantAct
 								td, constraintName,
                                 characteristics[0], //deferable,
                                 characteristics[1], //initiallyDeferred,
-								constraintId, 
+                                constrId,
 								constraintText, 
 								new ReferencedColumnsDescriptorImpl(genColumnPositions(td, false)), //int[],
 								sd,
@@ -372,7 +371,7 @@ public class CreateConstraintConstantAct
                                 characteristics[0], //deferable,
                                 characteristics[1], //initiallyDeferred,
 								genColumnPositions(td, false), //int[],
-								constraintId,
+                                constrId,
 								indexId,
 								sd,
 								referencedConstraint,
@@ -470,6 +469,8 @@ public class CreateConstraintConstantAct
 						getTableDescriptor(),
 				DependencyManager.CREATE_CONSTRAINT, lcc);
 		}
+
+        this.constraintId = constrId;
 	}
 	
 	/**
@@ -482,6 +483,11 @@ public class CreateConstraintConstantAct
 		return (constraintType == DataDictionary.FOREIGNKEY_CONSTRAINT);
 	}
 
+
+    boolean isInitiallyDeferred() {
+        return characteristics[1];
+    }
+
 	/**
 	 * Generate an array of column positions for the column list in
 	 * the constraint.

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=1576367&r1=1576366&r2=1576367&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 Tue Mar 11 14:46:15 2014
@@ -826,18 +826,17 @@ class CreateIndexConstantAction extends 
                     numColumnOrderings = unique ? baseColumnPositions.length :
                             baseColumnPositions.length + 1;
 
-					sortObserver = 
-                        new UniqueIndexSortObserver(
-                                tc,
-                                lcc,
-                                DeferredDuplicates.UNDEFINED_CONGLOMERATE,
-                                true, 
-                                uniqueDeferrable,
-                                initiallyDeferred,
-                                indexOrConstraintName,
-                                indexTemplateRow,
-                                true,
-                                td.getName());
+                    sortObserver = new UniqueIndexSortObserver(
+                        tc,
+                        lcc,
+                        DeferredConstraintsMemory.UNDEFINED_CONGLOMERATE,
+                        true,
+                        uniqueDeferrable,
+                        initiallyDeferred,
+                        indexOrConstraintName,
+                        indexTemplateRow,
+                        true,
+                        td.getName());
 				}
 				else 
                 {
@@ -854,16 +853,16 @@ class CreateIndexConstantAction extends 
 					//use sort operator which treats nulls unequal
 					sortObserver = 
                         new UniqueWithDuplicateNullsIndexSortObserver(
-                                tc,
-                                lcc,
-                                DeferredDuplicates.UNDEFINED_CONGLOMERATE,
-                                true, 
-                                hasDeferrableChecking,
-                                initiallyDeferred,
-                                indexOrConstraintName,
-                                indexTemplateRow,
-                                true,
-                                td.getName());
+                            tc,
+                            lcc,
+                            DeferredConstraintsMemory.UNDEFINED_CONGLOMERATE,
+                            true,
+                            hasDeferrableChecking,
+                            initiallyDeferred,
+                            indexOrConstraintName,
+                            indexTemplateRow,
+                            true,
+                            td.getName());
 				}
 			}
 			else
@@ -915,7 +914,7 @@ class CreateIndexConstantAction extends 
 					(long[]) null);
 
             if (initiallyDeferred) {
-                DeferredDuplicates.associateDuplicatesWithConglomerate(
+                DeferredConstraintsMemory.associateDuplicatesWithConglomerate(
                     lcc, conglomId);
             }
 		}

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DMLWriteResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DMLWriteResultSet.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DMLWriteResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DMLWriteResultSet.java Tue Mar 11 14:46:15 2014
@@ -22,10 +22,10 @@
 package org.apache.derby.impl.sql.execute;
 
 import java.io.InputStream;
+import org.apache.derby.catalog.UUID;
 import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.services.io.FormatableBitSet;
 import org.apache.derby.iapi.services.io.StreamStorable;
-import org.apache.derby.shared.common.sanity.SanityManager;
 import org.apache.derby.iapi.sql.Activation;
 import org.apache.derby.iapi.sql.ResultColumnDescriptor;
 import org.apache.derby.iapi.sql.ResultDescription;
@@ -38,11 +38,12 @@ import org.apache.derby.iapi.store.acces
 import org.apache.derby.iapi.transaction.TransactionControl;
 import org.apache.derby.iapi.types.DataTypeDescriptor;
 import org.apache.derby.iapi.types.DataValueDescriptor;
+import org.apache.derby.shared.common.sanity.SanityManager;
 
 /**
  * For INSERT/UPDATE/DELETE impls.  Used to tag them.
  */
-abstract class DMLWriteResultSet extends NoRowsResultSetImpl 
+abstract public class DMLWriteResultSet extends NoRowsResultSetImpl
 {
 	protected WriteCursorConstantAction constantAction;
 	protected int[] baseRowReadMap;
@@ -353,5 +354,12 @@ abstract class DMLWriteResultSet extends
 
         return row;
     }
-    
+
+    public void rememberConstraint(UUID cid) throws StandardException {
+        if (SanityManager.DEBUG) {
+            // This method should be overriden by InsertResultSet and
+            // UpdateResultSet, other shouldn't need it.
+            SanityManager.NOTREACHED();
+        }
+    }
 }

Added: 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=1576367&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DeferredConstraintsMemory.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/DeferredConstraintsMemory.java Tue Mar 11 14:46:15 2014
@@ -0,0 +1,588 @@
+/*
+
+   Derby - Class org.apache.derby.impl.sql.execute.DeferredConstraintsMemory
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derby.impl.sql.execute;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.derby.catalog.UUID;
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.services.io.FormatableBitSet;
+import org.apache.derby.iapi.sql.PreparedStatement;
+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.DataDictionary;
+import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
+import org.apache.derby.iapi.sql.execute.ExecRow;
+import org.apache.derby.iapi.store.access.BackingStoreHashtable;
+import org.apache.derby.iapi.store.access.ScanController;
+import org.apache.derby.iapi.store.access.TransactionController;
+import org.apache.derby.iapi.types.DataValueDescriptor;
+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
+ * mode is deferred, any violation of the constraint should not be flagged
+ * until the constraint mode is switched back to immediate, which may happen by
+ * explicitly setting the constraint mode to immediate, or implicitly at commit
+ * time. It may also happen implicitly when returning from a stored procedure
+ * if the constraint mode is immediate in the caller context.
+ * <p>
+ * The approach taken in Derby to support deferred constraints is to make a note
+ * when the violation happens (at insert or update time), and then remember that
+ * violation until the mode switches back as described above.  We note exactly
+ * which rows cause violations, so checking can happen as quickly as possible
+ * when we get there. The core mechanism used to remember the violations as well
+ * as the deferred checking is embodied in this class.
+ *
+ */
+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
+     * hash table (which may spill to disk) for later checking,
+     * typically on transaction commit, or upon request.
+     *
+     * @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 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)
+     * @throws StandardException standard error policy
+     */
+    public static BackingStoreHashtable rememberDuplicate(
+            final LanguageConnectionContext lcc,
+                  BackingStoreHashtable deferredRowsHashTable,
+            final long indexCID,
+            final DataValueDescriptor[] insertRow) throws StandardException {
+
+        // Don't copy the RowLocation, we don't need it:
+        final int keyLength = insertRow.length -1 ;
+
+        if (deferredRowsHashTable == null) {
+            // Use the backing hashtable for this index's deferred rows
+            // by checking the transaction's map of such backing hash
+            // tables (one per index conglomerate).  Use it if it
+            // exists, else make a new one.
+
+            final HashMap<Long, ValidationInfo> hashTables =
+                lcc.getDeferredHashTables();
+            final ValidationInfo vi = hashTables.get(Long.valueOf(indexCID));
+
+            if (vi == null) {
+                deferredRowsHashTable =
+                  makeDeferredHashTable(lcc.getTransactionExecute(), keyLength);
+
+                hashTables.put(
+                    Long.valueOf(indexCID),
+                    new UniquePkInfo(deferredRowsHashTable));
+            } else {
+                deferredRowsHashTable = vi.infoRows;
+            }
+        }
+
+        DataValueDescriptor[] hashRowArray = new DataValueDescriptor[keyLength];
+        System.arraycopy(insertRow, 0, hashRowArray, 0, keyLength);
+        deferredRowsHashTable.putRow(true, hashRowArray, null);
+
+        return deferredRowsHashTable;
+    }
+
+    /**
+     * Save the row location of an offending row (one or more check constraints
+     * were violated) in a hash table (which may spill to disk) for later
+     * checking, typically on transaction commit, or upon request.
+     *
+     * 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 schemaName the schema of the target table
+     * @param tableName the target table name
+     * @param deferredCheckViolations
+     *                  client cached value
+     * @param lcc       the language connection context
+     * @param violatingCheckConstraints offending constraint(s)
+     * @param offendingRow the duplicate row to be saved in the hash table
+     *                  for later checking
+     * @return the hash table (for caching by client to minimize lookups)
+     * @throws StandardException standard error policy
+     */
+    public static BackingStoreHashtable rememberCheckViolations(
+            final LanguageConnectionContext lcc,
+            final long basetableCID,
+            final String schemaName,
+            final String tableName,
+                  BackingStoreHashtable deferredCheckViolations,
+            final List<UUID> violatingCheckConstraints,
+            final RowLocation offendingRow) throws StandardException {
+
+        if (violatingCheckConstraints.isEmpty()) {
+            return null;
+        }
+
+        if (deferredCheckViolations == null) {
+            // Use the backing hashtable for this base tables deferred rows
+            // by checking the transaction's map of such backing hash
+            // tables (one per base table conglomerate).  Use it if it
+            // exists, else make a new one.
+
+            final HashMap<Long, ValidationInfo> hashTables =
+                    lcc.getDeferredHashTables();
+            final CheckInfo vi =
+                    (CheckInfo)hashTables.get(Long.valueOf(basetableCID));
+
+            if (vi == null) {
+                // size 1 below: the row location in the target table of the
+                // offending row
+                deferredCheckViolations =
+                        makeDeferredHashTable(lcc.getTransactionExecute(), 1);
+
+                hashTables.put(Long.valueOf(basetableCID),
+                               new CheckInfo(deferredCheckViolations,
+                                   schemaName,
+                                   tableName,
+                                   violatingCheckConstraints));
+            } else {
+                vi.addCulprits(violatingCheckConstraints);
+                deferredCheckViolations = vi.infoRows;
+            }
+        }
+
+        final DataValueDescriptor[] hashRowArray = new DataValueDescriptor[1];
+        hashRowArray[0] = new SQLRef(offendingRow).cloneValue(true);
+        deferredCheckViolations.putRow(true, hashRowArray, null);
+
+        return deferredCheckViolations;
+    }
+
+
+    /**
+     * 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) {
+
+        final HashMap<Long, ValidationInfo> hashTables =
+                    lcc.getDeferredHashTables();
+
+        if (hashTables == null) {
+            return; // no duplicates recorded in this transaction
+        }
+
+        final ValidationInfo ht = hashTables.remove(
+                Long.valueOf(UNDEFINED_CONGLOMERATE));
+
+        if (ht != null) {
+            hashTables.put(indexCID, ht);
+        } // else no duplicates recorded for this index
+    }
+
+    /**
+     * The conglomerate id for an index with deferred row checking needs
+     * updating in the memory if the underlying index is rebuilt, for example
+     * 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) {
+
+        final HashMap<Long, ValidationInfo> hashTables =
+                    lcc.getDeferredHashTables();
+
+        if (hashTables == null) {
+            return; // no duplicates recorded in this transaction
+        }
+
+        final ValidationInfo ht = hashTables.remove(
+                Long.valueOf(oldIndexCID));
+
+        if (ht != null) {
+            hashTables.put(Long.valueOf(newIndexCID), ht);
+        }
+    }
+
+    private static BackingStoreHashtable makeDeferredHashTable(
+            final TransactionController tc,
+            final int cols) throws StandardException {
+
+        // key: all columns (these are index rows, or a row containing a
+        // row location)
+        final int[] keyCols = new int[cols];
+
+        for (int i = 0; i < cols; i++) {
+            keyCols[i] = i;
+        }
+
+        return new BackingStoreHashtable(
+                tc,
+                null,
+                keyCols,
+                true, // remove duplicates: no need for more copies:
+                      // one is enough to know what to look for on commit
+                -1,
+                HashScanResultSet.DEFAULT_MAX_CAPACITY,
+                HashScanResultSet.DEFAULT_INITIAL_CAPACITY,
+                HashScanResultSet.DEFAULT_MAX_CAPACITY,
+                false,
+                false);
+    }
+
+    private static BackingStoreHashtable makeDeferredCheck(
+            final TransactionController tc,
+            final int cols) throws StandardException {
+
+        // key: all columns (these are index rows)
+        final int[] keyCols = new int[cols];
+
+        for (int i = 0; i < cols; i++) {
+            keyCols[i] = i;
+        }
+
+        return new BackingStoreHashtable(
+                tc,
+                null,
+                keyCols,
+                true, // remove duplicates: no need for more copies:
+                      // one is enough to know what to look for on commit
+                -1,
+                HashScanResultSet.DEFAULT_MAX_CAPACITY,
+                HashScanResultSet.DEFAULT_INITIAL_CAPACITY,
+                HashScanResultSet.DEFAULT_MAX_CAPACITY,
+                false,
+                false);
+    }
+
+    /**
+     * 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 ht        Cached saved rows if any
+     * @param rollbackOnError {@code true} if we should roll back the
+     *                  transaction if we see a violation of the constraint
+     * @throws StandardException
+     */
+    public static 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();
+
+        while (e.hasMoreElements()) {
+            final DataValueDescriptor[] key =
+                    (DataValueDescriptor[])e.nextElement();
+
+            // FIXME: This is not very efficient: we could sort the rows in the
+            // hash table, and then check all rows using a single scan.
+            ScanController indexSC = null;
+            boolean sawException = false;
+
+            try {
+                indexSC = tc.openScan(
+                    indexCID,
+                    false,
+                    0, // read only
+                    TransactionController.MODE_RECORD,
+                    TransactionController.ISOLATION_READ_COMMITTED_NOHOLDLOCK,
+                    (FormatableBitSet)null, // retrieve all fields
+                    key,
+                    ScanController.GE, // startSearchOp
+                    null,
+                    key,
+                    ScanController.GT);
+
+                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());
+                    } // else exactly one row contains key: OK
+                } else {
+                    // No rows contain key: OK, must have been deleted later
+                    // in transaction, or we got here due to pessimistic
+                    // assumption on a timeout while checking on the insert.
+                }
+            } catch (StandardException se) {
+                sawException = true;
+                throw se;
+            } finally {
+                // Clean up resource usage
+                try {
+                    if (indexSC != null) {
+                        indexSC.close();
+                    }
+                } catch (StandardException ie) {
+                    if (!sawException) {
+                        throw ie;
+                    } // else: can't let it shadow preceding exception
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Validate one or more CHECK constraints on a table.
+     * <p>
+     * Implementation note: We remember violations for a row by storing its row
+     * location in a disk based hash table, similar to what we do for the index
+     * location for primary key and unique constraints. As far as which
+     * constraints caused which violations, constraints are only presently
+     * remembered as having caused "one or more violations", i.e. for any
+     * violating row, we do not know at checking time exactly which constraint
+     * caused a problem for that exact row. So, for any given constraint which
+     * was violated in the transaction we visit all rows which had one or more
+     * violations and check again. This could be improved upon by remembering
+     * for each violating row the exact set of constraint(s) that saw a
+     * violation. Still, this is much faster than a full table scan in most use
+     * cases.  We use a special internal query option to achieve this.  The row
+     * locations may not be usable if Derby does a compress or otherwise makes
+     * them invalid. In that case we resort to a full table scan.
+     * @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
+     *                     constraints, i.e.  at commit or if we have {@code
+     *                     SET CONSTRAINT ALL IMMEDIATE}.
+     * @param ci           The constraints info for the table we need
+     *                     to perform the check on.
+     * @param rollbackOnError If {@code true} and a violation occurs, throw
+     *                     and exception that will cause rollback.
+     * @throws StandardException
+     *                     Default error policy
+     */
+    public static void validateCheck(
+            final LanguageConnectionContext lcc,
+            final long baseTableCID,
+            final UUID constraintId,
+            final CheckInfo ci,
+            final boolean rollbackOnError) throws StandardException {
+
+        final TransactionController tc = lcc.getTransactionExecute();
+        final DataDictionary dd = lcc.getDataDictionary();
+        final SchemaDescriptor sd = dd.getSchemaDescriptor(
+                ci.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;
+            }
+        }
+
+        final TableDescriptor td = dd.getTableDescriptor(ci.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();
+            }
+        } else {
+            for (UUID id : ci.culprits) {
+                if (constraintId == null || constraintId.equals(id)) {
+                    final ConstraintDescriptor cd =
+                        dd.getConstraintDescriptor(id);
+                    final StringBuilder checkStmt = new StringBuilder();
+                    checkStmt.append("SELECT 1 FROM ");
+                    checkStmt.append(td.getQualifiedName());
+
+                    // If a compress has happened in this transaction, we can't
+                    // trust the rowLocations, so make a full table scan. If
+                    // not, we optimize by using a special result set type
+                    // which utilized the saved away row locations for the
+                    // offending rows, so we only visit those when checking.
+                    // I.e. other rows are known to be good a priori.
+                    if (!ci.isInvalidated()) {
+                        checkStmt.append(
+                            " --DERBY-PROPERTIES joinStrategy=nestedLoop, " +
+                                "                    index=null, " +
+                                "                    validateCheckConstraint=");
+                        checkStmt.append(Long.toString(baseTableCID));
+                        checkStmt.append('\n');
+                    }
+
+                    checkStmt.append(" WHERE NOT(");
+                    checkStmt.append(cd.getConstraintText());
+                    checkStmt.append(')');
+
+                    BasicNoPutResultSetImpl rs = null;
+                    final PreparedStatement ps = lcc.prepareInternalStatement(
+                        lcc.getDefaultSchema(),
+                        checkStmt.toString(),
+                        true,
+                        true);
+                    try {
+                        rs = (BasicNoPutResultSetImpl)ps.execute(
+                            ps.getActivation(lcc, false), false, 0L);
+                        final ExecRow row = rs.getNextRowCore();
+
+                        if (row != null) {
+                            //check constraint violated
+
+                            throw StandardException.newException(
+                                rollbackOnError ?
+                                    SQLState.LANG_DEFERRED_CHECK_CONSTRAINT_T :
+                                    SQLState.LANG_DEFERRED_CHECK_CONSTRAINT_S,
+                                cd.getConstraintName(),
+                                td.getName(),
+                                cd.getConstraintText());
+                        }
+                    } finally {
+                        if (rs != null) {
+                            try {
+                                rs.close();
+                            } catch (StandardException e) {}
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Class hierarchy carrying the information we need to validate
+     * some deferred constraint. For unique and primary key constraints, we
+     * only need the index row. For check constraints we need the target table
+     * name, schema name and some other info also.
+     */
+    abstract public static class ValidationInfo {
+        public final BackingStoreHashtable infoRows;
+
+        public ValidationInfo(final BackingStoreHashtable infoRows) {
+            this.infoRows = infoRows;
+        }
+    }
+
+    /**
+     * Info needed for unique and primary key constraints
+     */
+    public static class UniquePkInfo extends ValidationInfo {
+        public UniquePkInfo(final BackingStoreHashtable infoRows) {
+            super(infoRows);
+        }
+    }
+
+    /**
+     * Info needed for check constraints
+     */
+    public static class CheckInfo extends ValidationInfo {
+        final private String schemaName;
+        final private String tableName;
+
+        private List<UUID> culprits; // constraints that were violated
+                                     // for this table so far
+        private boolean invalidatedDueToCompress;
+
+        public CheckInfo(
+                final BackingStoreHashtable infoRows,
+                final String schemaName,
+                final String tableName,
+                final List<UUID> culprits) {
+
+            super(infoRows);
+            this.schemaName = schemaName;
+            this.tableName = tableName;
+            this.culprits = new ArrayList<UUID>(culprits);
+        }
+
+        public void setInvalidatedRowLocations() {
+            invalidatedDueToCompress = true;
+        }
+
+        public boolean isInvalidated() {
+            return invalidatedDueToCompress;
+        }
+
+        public void addCulprits(List<UUID> newCulprits) {
+            final Set<UUID> old = new HashSet<UUID>(culprits);
+            old.addAll(newCulprits);
+            culprits = new ArrayList<UUID>(old);
+        }
+
+        public List<UUID> getCulprints() {
+            return culprits;
+        }
+    }
+}

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericConstantActionFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericConstantActionFactory.java?rev=1576367&r1=1576366&r2=1576367&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericConstantActionFactory.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericConstantActionFactory.java Tue Mar 11 14:46:15 2014
@@ -754,7 +754,7 @@ public class GenericConstantActionFactor
 	}
 
 	/**
-	 *	Make the ConstantAction for a Replicated INSERT statement.
+     *  Make the ConstantAction for a INSERT statement.
 	 *
 	 *  @param conglomId		Conglomerate ID.
 	 *  @param heapSCOCI		StaticCompiledOpenConglomInfo for target heap.
@@ -766,7 +766,10 @@ public class GenericConstantActionFactor
 	 *	@param deferred			True means deferred insert
 	 *  @param tableIsPublished	true if table is published, false otherwise
 	 *  @param tableID			table id
-	 *  @param targetProperties	Properties on the target table
+     *  @param hasDeferrableChecks
+     *                          The target table has deferrable CHECK
+     *                          constraints
+     *  @param targetProperties Properties on the target table
 	 *	@param fkInfo			Array of structures containing foreign key info, 
 	 *							if any (may be null)
 	 *	@param triggerInfo		Array of structures containing trigger info, 
@@ -792,7 +795,8 @@ public class GenericConstantActionFactor
 								StaticCompiledOpenConglomInfo[] indexSCOCIs,
 								String[]			indexNames,
 								boolean				deferred,
-								boolean				tableIsPublished,
+                                boolean             tableIsPublished,
+                                boolean             hasDeferrableChecks,
 								UUID				tableID,
 								int					lockMode,
 								Object         		insertToken,
@@ -819,6 +823,7 @@ public class GenericConstantActionFactor
 										indexSCOCIs,
 										indexNames,
 										deferred,
+                                        hasDeferrableChecks,
 										targetProperties,
 										tableID,
 										lockMode,
@@ -904,14 +909,14 @@ public class GenericConstantActionFactor
 
 
 	/**
-	 *	Make the ConstantAction for a Replicated DELETE statement.
+     *  Make the ConstantAction for an UPDATE statement.
 	 *
-	 *  @param conglomId			Conglomerate ID.
-	 *  @param tableType			type of this table
+     *  @param targetTableDesc      Descriptor for the updated table
 	 *	@param heapSCOCI			StaticCompiledOpenConglomInfo for heap.
 	 *  @param irgs					Index descriptors
 	 *  @param indexCIDS			Conglomerate IDs of indices
-	 *	@param indexSCOCIs	StaticCompiledOpenConglomInfos for indexes.
+     *  @param indexSCOCIs          StaticCompiledOpenConglomInfos for indexes.
+     *  @param indexNames
 	 *	@param deferred				True means deferred update
 	 *	@param targetUUID			UUID of target table
 	 *	@param lockMode				The lock mode to use
@@ -919,6 +924,7 @@ public class GenericConstantActionFactor
 	 *  @param tableIsPublished		true if table is published, false otherwise
 	 *	@param changedColumnIds		Array of ids of changes columns
 	 *  @param keyPositions     	positions of primary key columns in base row
+     *  @param updateToken
 	 *	@param fkInfo				Array of structures containing foreign key info, 
 	 *								if any (may be null)
 	 *	@param triggerInfo			Array of structures containing trigger info, 
@@ -930,12 +936,12 @@ public class GenericConstantActionFactor
 	 *	@param positionedUpdate		is this a positioned update
 	 *  @param singleRowSource		Whether or not source is a single row source
 	 *  @param underMerge   True if this is an action of a MERGE statement.
+     *  @return                     The constant action constructed
 	 *
 	 *  @exception StandardException Thrown on failure
 	 */
 	public	UpdateConstantAction	getUpdateConstantAction(
-								long				conglomId,
-								int					tableType,
+                                TableDescriptor     targetTableDesc,
 								StaticCompiledOpenConglomInfo heapSCOCI,
 								IndexRowGenerator[]	irgs,
 								long[]				indexCIDS,
@@ -950,7 +956,7 @@ public class GenericConstantActionFactor
 								Object         		updateToken,
 								FKInfo[]			fkInfo,
 								TriggerInfo			triggerInfo,
-								FormatableBitSet				baseRowReadList,
+                                FormatableBitSet    baseRowReadList,
 								int[]				baseRowReadMap,
 								int[]				streamStorableHeapColIds,
 								int					numColumns,
@@ -961,7 +967,7 @@ public class GenericConstantActionFactor
 			throws StandardException
 	{
 		return new UpdateConstantAction(
-										conglomId,
+                                        targetTableDesc,
 										heapSCOCI,
 										irgs,
 										indexCIDS,

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=1576367&r1=1576366&r2=1576367&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 Tue Mar 11 14:46:15 2014
@@ -66,14 +66,24 @@ public class GenericResultSetFactory imp
 		@see ResultSetFactory#getInsertResultSet
 		@exception StandardException thrown on error
 	 */
-	public ResultSet getInsertResultSet(NoPutResultSet source, GeneratedMethod generationClauses,
-                                        GeneratedMethod checkGM, int fullTemplate)
+    public ResultSet getInsertResultSet(NoPutResultSet source,
+                                        GeneratedMethod generationClauses,
+                                        GeneratedMethod checkGM,
+                                        int fullTemplate,
+                                        String schemaName,
+                                        String tableName)
 		throws StandardException
 	{
 		Activation activation = source.getActivation();
 		getAuthorizer(activation).authorize(activation, Authorizer.SQL_WRITE_OP);
-        return new InsertResultSet(
-                source, generationClauses, checkGM, fullTemplate, activation);
+
+        return new InsertResultSet(source,
+                                   generationClauses,
+                                   checkGM,
+                                   fullTemplate,
+                                   schemaName,
+                                   tableName,
+                                   activation);
 	}
 
 	/**
@@ -226,6 +236,8 @@ public class GenericResultSetFactory imp
         int cloneMapItem,
 		boolean reuseResult,
 		boolean doesProjection,
+        boolean validatingCheckConstraint,
+        long validatingBaseTableCID,
 		double optimizerEstimatedRowCount,
 		double optimizerEstimatedCost)
 			throws StandardException
@@ -235,6 +247,8 @@ public class GenericResultSetFactory imp
             constantRestriction, mapRefItem, cloneMapItem,
 			reuseResult,
 			doesProjection,
+            validatingCheckConstraint,
+            validatingBaseTableCID,
 		    optimizerEstimatedRowCount,
 			optimizerEstimatedCost);
 	}
@@ -666,7 +680,65 @@ public class GenericResultSetFactory imp
 								optimizerEstimatedCost);
 	}
 
-	/**
+    public NoPutResultSet getValidateCheckConstraintResultSet(
+                                    Activation activation,
+                                    long conglomId,
+                                    int scociItem,
+                                    int resultRowTemplate,
+                                    int resultSetNumber,
+                                    GeneratedMethod startKeyGetter,
+                                    int startSearchOperator,
+                                    GeneratedMethod stopKeyGetter,
+                                    int stopSearchOperator,
+                                    boolean sameStartStopPosition,
+                                    Qualifier[][] qualifiers,
+                                    String tableName,
+                                    String userSuppliedOptimizerOverrides,
+                                    String indexName,
+                                    boolean isConstraint,
+                                    boolean forUpdate,
+                                    int colRefItem,
+                                    int indexColItem,
+                                    int lockMode,
+                                    boolean tableLocked,
+                                    int isolationLevel,
+                                    boolean oneRowScan,
+                                    double optimizerEstimatedRowCount,
+                                    double optimizerEstimatedCost)
+            throws StandardException
+    {
+        StaticCompiledOpenConglomInfo scoci =
+            (StaticCompiledOpenConglomInfo)(activation.getPreparedStatement().
+                                            getSavedObject(scociItem));
+        return new ValidateCheckConstraintResultSet(
+                                conglomId,
+                                scoci,
+                                activation,
+                                resultRowTemplate,
+                                resultSetNumber,
+                                startKeyGetter,
+                                startSearchOperator,
+                                stopKeyGetter,
+                                stopSearchOperator,
+                                sameStartStopPosition,
+                                qualifiers,
+                                tableName,
+                                userSuppliedOptimizerOverrides,
+                                indexName,
+                                isConstraint,
+                                forUpdate,
+                                colRefItem,
+                                indexColItem,
+                                lockMode,
+                                tableLocked,
+                                isolationLevel,
+                                1,  // rowsPerRead is 1 if not a bulkTableScan
+                                oneRowScan,
+                                optimizerEstimatedRowCount,
+                                optimizerEstimatedCost);
+    }
+
+    /**
     	Table/Index scan where rows are read in bulk
 		@see ResultSetFactory#getBulkTableScanResultSet
 		@exception StandardException thrown on error