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/04/29 02:23:53 UTC

svn commit: r1590849 [2/3] - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/sql/conn/ engine/org/apache/derby/iapi/sql/dictionary/ engine/org/apache/derby/iapi/types/ engine/org/apache/derby/impl/sql/compile/ engine/org/apache/derby/impl/sq...

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=1590849&r1=1590848&r2=1590849&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 Tue Apr 29 00:23:52 2014
@@ -21,28 +21,20 @@
 
 package org.apache.derby.impl.sql.execute;
 
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.StreamCorruptedException;
+import java.util.Vector;
 import org.apache.derby.catalog.UUID;
-
 import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;
-
-import org.apache.derby.iapi.types.RowLocation;
-
-import org.apache.derby.iapi.services.monitor.Monitor;
-
-import org.apache.derby.shared.common.sanity.SanityManager;
-import org.apache.derby.iapi.services.io.StoredFormatIds;
-import org.apache.derby.iapi.services.io.FormatIdUtil;
 import org.apache.derby.iapi.services.io.ArrayUtil;
+import org.apache.derby.iapi.services.io.FormatIdUtil;
 import org.apache.derby.iapi.services.io.Formatable;
-
-import java.io.StreamCorruptedException;
-import java.io.ObjectOutput;
-import java.io.ObjectInput;
-import java.io.IOException;
-
-import java.util.Vector;
+import org.apache.derby.iapi.services.io.StoredFormatIds;
+import org.apache.derby.iapi.services.monitor.Monitor;
+import org.apache.derby.iapi.types.RowLocation;
+import org.apache.derby.shared.common.sanity.SanityManager;
 
 /**
  * This is a simple class used to store the run time information
@@ -60,7 +52,7 @@ public class FKInfo implements Formatabl
 	**	also write/read them with the writeExternal()/readExternal()
 	**	methods.
 	**
-	**	If, inbetween releases, you add more fields to this class,
+    **  If, between releases, you add more fields to this class,
 	**	then you should bump the version number emitted by the getTypeFormatId()
 	**	method.  OR, since this is something that is used
 	**	in stored prepared statements, it is ok to change it
@@ -75,18 +67,24 @@ public class FKInfo implements Formatabl
 	/*
 	** See the constructor for the meaning of these fields
 	*/
-    String[]            fkConstraintNames;
+    String              schemaName;
     String              tableName;
     int                 type;
-    UUID                refUUID;
+    UUID                refUUID; // index index conglomerate uuid
     long                refConglomNumber;
-    private UUID[]      fkUUIDs;
+    int                 stmtType;
+    RowLocation         rowLocation;
+
+    // These arrays all have the same cardinality, either 1 (foreign key), or
+    // the number of FKs referencing this referenced key
+    String[]            fkConstraintNames;
+    private UUID[]      fkUUIDs; // the index conglomerate uuids
     long[]              fkConglomNumbers;
+    UUID[]              fkIds; // the constraint uuids
     boolean[]           fkIsSelfReferencing;
     int[]               colArray;
-    int                 stmtType;
-    RowLocation         rowLocation;
     int[]               raRules;
+    boolean[]           deferrable;
 
 	/**
 	 * Niladic constructor for Formattable
@@ -94,32 +92,36 @@ public class FKInfo implements Formatabl
 	public FKInfo() {}
 
 	/**
-	 * Consructor for FKInfo
+     * Constructor for FKInfo
 	 *
 	 * @param fkConstraintNames the foreign key constraint names
+     * @param schemaName the name of the schema of the table being modified
 	 * @param tableName	the name of the table being modified
 	 * @param stmtType	the type of the statement: e.g. StatementType.INSERT
 	 * @param type either FKInfo.REFERENCED_KEY or FKInfo.FOREIGN_KEY
 	 * @param refUUID UUID of the referenced constraint
-	 * @param refConglomNumber congomerate number of the referenced key
+     * @param refConglomNumber conglomerate number of the referenced key
 	 * @param fkUUIDs an array of fkUUIDs of backing indexes.  if
 	 *			FOREIGN_KEY, then just one element, the backing
-	 *			index of the referrenced keys.  if REFERENCED_KEY,
+     *          index of the referenced keys.  if REFERENCED_KEY,
 	 *			then all the foreign keys
 	 * @param fkConglomNumbers array of conglomerate numbers, corresponds
 	 *			to fkUUIDs
 	 * @param fkIsSelfReferencing array of conglomerate booleans indicating
-	 *			whether the fk references a key in the same table
+     *          whether the foreign key references a key in the same table
 	 * @param colArray map of columns to the base row that DML
 	 * 			is changing.  1 based.  Note that this maps the
 	 *			constraint index to a row in the target table of
-	 *			the current dml operation.
+     *          the current DML operation.
 	 * @param rowLocation a row location template for the target table
 	 *			used to pass in a template row to tc.openScan()
+     * @param raRules referential action rules
+     * @param deferrable the corresponding constraint is deferrable
 	 */
 	public FKInfo(
 					String[]			fkConstraintNames,
-					String				tableName,
+                    String              schemaName,
+                    String              tableName,
 					int					stmtType,
 					int					type,
 					UUID				refUUID,
@@ -129,11 +131,14 @@ public class FKInfo implements Formatabl
 					boolean[]			fkIsSelfReferencing,
 					int[]				colArray,
 					RowLocation			rowLocation,
-					int[]               raRules
+                    int[]               raRules,
+                    boolean[]           deferrable,
+                    UUID[]              fkIds
 					)
 	{
         this.fkConstraintNames = ArrayUtil.copy(fkConstraintNames);
 		this.tableName = tableName;
+        this.schemaName = schemaName;
 		this.stmtType = stmtType;
 		this.type = type;
 		this.refUUID = refUUID;
@@ -144,6 +149,8 @@ public class FKInfo implements Formatabl
         this.colArray = ArrayUtil.copy(colArray);
 		this.rowLocation = rowLocation;
         this.raRules = ArrayUtil.copy(raRules);
+        this.deferrable = ArrayUtil.copy(deferrable);
+        this.fkIds = ArrayUtil.copy(fkIds);
 
 		if (SanityManager.DEBUG)
 		{
@@ -175,7 +182,7 @@ public class FKInfo implements Formatabl
 	 *
  	 * @param fkInfo	        array of fkinfos
 	 * @param cols	            array of columns
-	 * @param addAllTypeIsFK	take all with type == FORIEGN_KEY
+     * @param addAllTypeIsFK    take all with type == FOREIGN_KEY
 	 *
 	 * @return array of relevant fkinfos
 	 */
@@ -276,7 +283,7 @@ public class FKInfo implements Formatabl
 		ArrayUtil.writeBooleanArray(out, fkIsSelfReferencing);
 		ArrayUtil.writeIntArray(out, colArray);
 		ArrayUtil.writeIntArray(out, raRules);
-		
+        ArrayUtil.writeBooleanArray(out, deferrable);
 	}
 
 	/**
@@ -318,6 +325,7 @@ public class FKInfo implements Formatabl
 			fkIsSelfReferencing = ArrayUtil.readBooleanArray(in);
 			colArray = ArrayUtil.readIntArray(in);
 			raRules = ArrayUtil.readIntArray(in);
+            deferrable = ArrayUtil.readBooleanArray(in);
 		}
 		catch (StandardException exception)
 		{
@@ -330,7 +338,7 @@ public class FKInfo implements Formatabl
 	 *
 	 *	@return	the formatID of this class
 	 */
-	public	int	getTypeFormatId()	{ return StoredFormatIds.FK_INFO_V01_ID; }
+    public  int getTypeFormatId()   { return StoredFormatIds.FK_INFO_V01_ID; }
 
 	//////////////////////////////////////////////////////////////
 	//
@@ -341,7 +349,7 @@ public class FKInfo implements Formatabl
 	{
 		if (SanityManager.DEBUG)
 		{
-			StringBuffer str = new StringBuffer();
+            StringBuilder str = new StringBuilder();
 			str.append("\nTableName:\t\t\t");
 			str.append(tableName);
 
@@ -401,7 +409,17 @@ public class FKInfo implements Formatabl
 			}
 			str.append(")\n");
 
-			return str.toString();
+            str.append("\nDeferrable array:\t\t\t(");
+            for (int i = 0; i < deferrable.length; i++)
+            {
+                if (i > 0)
+                    str.append(",");
+
+                str.append(colArray[i]);
+            }
+            str.append(")\n");
+
+            return str.toString();
 		}
 		else
 		{

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=1590849&r1=1590848&r2=1590849&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 Tue Apr 29 00:23:52 2014
@@ -21,15 +21,16 @@
 
 package org.apache.derby.impl.sql.execute;
 
-import org.apache.derby.shared.common.sanity.SanityManager;
+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.sql.Activation;
 import org.apache.derby.iapi.sql.StatementUtil;
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
 import org.apache.derby.iapi.sql.execute.ExecRow;
-import org.apache.derby.iapi.sql.execute.ExecIndexRow;
-import org.apache.derby.iapi.reference.SQLState;
 import org.apache.derby.iapi.store.access.ScanController;
 import org.apache.derby.iapi.store.access.TransactionController;
+import org.apache.derby.shared.common.sanity.SanityManager;
 
 /**
  * A Referential Integrity checker for a foreign
@@ -41,15 +42,18 @@ import org.apache.derby.iapi.store.acces
 public class ForeignKeyRIChecker extends GenericRIChecker
 {
 	/**
+     * @param lcc       the language connection context
 	 * @param tc		the xact controller
 	 * @param fkinfo	the foreign key information 
 	 *
 	 * @exception StandardException		Thrown on failure
 	 */
-	ForeignKeyRIChecker(TransactionController tc, FKInfo fkinfo)
-		throws StandardException
+    ForeignKeyRIChecker(
+        LanguageConnectionContext lcc,
+        TransactionController tc,
+        FKInfo fkinfo) throws StandardException
 	{
-		super(tc, fkinfo);
+        super(lcc, tc, fkinfo);
 
 		if (SanityManager.DEBUG)
 		{
@@ -68,12 +72,16 @@ public class ForeignKeyRIChecker extends
 	 * when this method returns.  The lock is held until
 	 * the next call to doCheck() or close().
 	 *
+     * @param a     the activation
 	 * @param row	the row to check
+     * @param restrictCheckOnly
 	 *
-	 * @exception StandardException on unexped error, or
+     * @exception StandardException on unexpected error, or
 	 *		on a foreign key violation
 	 */
-	void doCheck(ExecRow row, boolean restrictCheckOnly) throws StandardException
+    void doCheck(Activation a,
+                 ExecRow row,
+                 boolean restrictCheckOnly) throws StandardException
 	{
 
 		if(restrictCheckOnly) //RESTRICT rule checks are not valid here.
@@ -95,13 +103,32 @@ public class ForeignKeyRIChecker extends
 		ScanController scan = getScanController(fkInfo.refConglomNumber, refScoci, refDcoci, row);
 		if (!scan.next())
 		{
-			close();
-			StandardException se = StandardException.newException(SQLState.LANG_FK_VIOLATION, fkInfo.fkConstraintNames[0],
-										fkInfo.tableName,
-										StatementUtil.typeName(fkInfo.stmtType),
-										RowUtil.toString(row, fkInfo.colArray));
+            final UUID fkId = fkInfo.fkIds[0];
+            close();
+
+            if (fkInfo.deferrable[0] &&
+                lcc.isEffectivelyDeferred(lcc.getCurrentSQLSessionContext(a),
+                        fkId)) {
+                deferredRowsHashTable =
+                        DeferredConstraintsMemory.rememberFKViolation(
+                                lcc,
+                                deferredRowsHashTable,
+                                fkInfo.fkConglomNumbers[0],
+                                fkInfo.refConglomNumber,
+                                fkInfo.fkIds[0],
+                                indexQualifierRow.getRowArray(),
+                                fkInfo.schemaName,
+                                fkInfo.tableName);
+            } else {
+                StandardException se = StandardException.newException(
+                        SQLState.LANG_FK_VIOLATION,
+                        fkInfo.fkConstraintNames[0],
+                        fkInfo.tableName,
+                        StatementUtil.typeName(fkInfo.stmtType),
+                        RowUtil.toString(row, fkInfo.colArray));
+                throw se;
+            }
 
-			throw se;
 		}
 		
 		/*

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericRIChecker.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericRIChecker.java?rev=1590849&r1=1590848&r2=1590849&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericRIChecker.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericRIChecker.java Tue Apr 29 00:23:52 2014
@@ -21,18 +21,19 @@
 
 package org.apache.derby.impl.sql.execute;
 
+import java.util.Enumeration;
+import java.util.Hashtable;
 import org.apache.derby.iapi.error.StandardException;
-
-import org.apache.derby.iapi.types.DataValueDescriptor;
+import org.apache.derby.iapi.services.io.FormatableBitSet;
+import org.apache.derby.iapi.sql.Activation;
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
 import org.apache.derby.iapi.sql.execute.ExecRow;
+import org.apache.derby.iapi.store.access.BackingStoreHashtable;
 import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo;
 import org.apache.derby.iapi.store.access.ScanController;
 import org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo;
 import org.apache.derby.iapi.store.access.TransactionController;
-
-import org.apache.derby.iapi.services.io.FormatableBitSet;
-import java.util.Enumeration;
-import java.util.Hashtable;
+import org.apache.derby.iapi.types.DataValueDescriptor;
 
 /**
  * Generic implementation of a Referential Integrity
@@ -46,20 +47,30 @@ public abstract class GenericRIChecker
 	protected DynamicCompiledOpenConglomInfo refDcoci;
 	protected StaticCompiledOpenConglomInfo refScoci;
 	protected TransactionController		tc;
+    protected LanguageConnectionContext lcc;
+
+    /**
+     * Cached value (for efficiency) of the intermediate table of violations
+     * we use in the presence of deferred FK constraints.
+     */
+    protected BackingStoreHashtable deferredRowsHashTable;
 
-	private Hashtable<Long,ScanController> 		scanControllers;
-	private int				numColumns;
-	private	IndexRow		indexQualifierRow;
+    private final Hashtable<Long,ScanController> scanControllers;
+    private final int numColumns;
+    final IndexRow indexQualifierRow;
 
 	/**
+     * @param lcc       the language connection context
 	 * @param tc		the xact controller
 	 * @param fkinfo	the foreign key information 
 	 *
 	 * @exception StandardException		Thrown on failure
 	 */
-	GenericRIChecker(TransactionController tc, FKInfo fkinfo)
-		throws StandardException
+    GenericRIChecker(LanguageConnectionContext lcc,
+                     TransactionController tc,
+                     FKInfo fkinfo) throws StandardException
 	{
+        this.lcc = lcc;
 		this.fkInfo = fkinfo;
 		this.tc = tc;
 		scanControllers = new Hashtable<Long,ScanController>();
@@ -80,15 +91,20 @@ public abstract class GenericRIChecker
 	/**
 	 * Check the validity of this row
 	 *
+     * @param a     the activation
 	 * @param row	the row to check
+     * @param restrictCheckOnly If {@code true}, only perform check if the
+     *              constraint action is RESTRICT.
 	 *
 	 * @exception StandardException on error
 	 */
-	abstract void doCheck(ExecRow row, boolean restrictCheckOnly) throws StandardException;
+    abstract void doCheck(Activation a,
+                          ExecRow row,
+                          boolean restrictCheckOnly) throws StandardException;
 
-	public void doCheck(ExecRow row) throws StandardException
+    public void doCheck(Activation a, ExecRow row) throws StandardException
 	{
-		doCheck(row, false); //Check all the referential Actions
+        doCheck(a, row, false); //Check all the referential Actions
 	}
 
 	/**
@@ -125,7 +141,7 @@ public abstract class GenericRIChecker
 	{
 		int				isoLevel = getRICheckIsolationLevel();
 		ScanController 	scan;
-		Long			hashKey = new Long(conglomNumber);
+        Long            hashKey = Long.valueOf(conglomNumber);
 
 		/*
 		** If we haven't already opened this scan controller,

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=1590849&r1=1590848&r2=1590849&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 Tue Apr 29 00:23:52 2014
@@ -469,8 +469,8 @@ class IndexChanger
             // waiting for any locks; we will just presume any lock conflicts
             // constitute duplicates (not always the case), and check those keys
             // again at commit time.
-            final boolean deferred =
-                    lcc.isEffectivelyDeferred(activation, indexCID);
+            final boolean deferred = lcc.isEffectivelyDeferred(
+                    lcc.getCurrentSQLSessionContext(activation), indexCID);
 
             ScanController idxScan = tc.openScan(
                     indexCID,
@@ -524,7 +524,9 @@ class IndexChanger
             }
 
             if (duplicate) {
-                if (lcc.isEffectivelyDeferred(activation, indexCID)) {
+                if (lcc.isEffectivelyDeferred(
+                        lcc.getCurrentSQLSessionContext(activation),
+                        indexCID)) {
                     // Save duplicate row so we can check at commit time there is
                     // no longer any duplicate.
 

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=1590849&r1=1590848&r2=1590849&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 Tue Apr 29 00:23:52 2014
@@ -77,6 +77,7 @@ import org.apache.derby.iapi.types.Numbe
 import org.apache.derby.iapi.types.RowLocation;
 import org.apache.derby.iapi.types.SQLBoolean;
 import org.apache.derby.iapi.util.StringUtil;
+import org.apache.derby.impl.sql.execute.DeferredConstraintsMemory.CheckInfo;
 import org.apache.derby.shared.common.sanity.SanityManager;
 
 /**
@@ -298,7 +299,8 @@ class InsertResultSet extends DMLWriteRe
                             tableName,
                             deferredChecks,
                             violatingCheckConstraints,
-                            rl);
+                            rl,
+                            new CheckInfo[1] /* dummy */);
             violatingCheckConstraints.clear();
         }
     }
@@ -942,7 +944,7 @@ class InsertResultSet extends DMLWriteRe
 		{
 			if (fkChecker == null)
 			{
-				fkChecker = new RISetChecker(tc, fkInfoArray);
+                fkChecker = new RISetChecker(lcc, tc, fkInfoArray);
 			}
 			else
 			{
@@ -1025,7 +1027,7 @@ class InsertResultSet extends DMLWriteRe
 
 				if (fkChecker != null)
 				{
-					fkChecker.doFKCheck(row);
+                    fkChecker.doFKCheck(activation, row);
 				}
 
 				// Objectify any streaming columns that are indexed.
@@ -1058,7 +1060,8 @@ class InsertResultSet extends DMLWriteRe
                             tableName,
                             deferredChecks,
                             violatingCheckConstraints,
-                            offendingRow);
+                            offendingRow,
+                            new CheckInfo[1] /* dummy */);
                 }
 			}
 
@@ -1179,7 +1182,8 @@ class InsertResultSet extends DMLWriteRe
                                 tableName,
                                 deferredChecks,
                                 violatingCheckConstraints,
-                                offendingRow);
+                                offendingRow,
+                                new CheckInfo[1]);
                     }
 				}
 			} finally
@@ -1202,7 +1206,7 @@ class InsertResultSet extends DMLWriteRe
 					rs.open();
 					while ((deferredRowBuffer = rs.getNextRow()) != null)
 					{
-						fkChecker.doFKCheck(deferredRowBuffer);
+                        fkChecker.doFKCheck(activation, deferredRowBuffer);
 					}
 				} finally
 				{
@@ -1713,12 +1717,19 @@ class InsertResultSet extends DMLWriteRe
 				** magic.  It will do a merge on the two indexes. 
 				*/	
 				ExecRow firstFailedRow = template.getClone();
-				RIBulkChecker riChecker = new RIBulkChecker(refScan, 
+                RIBulkChecker riChecker = new RIBulkChecker(activation,
+                                            refScan,
 											fkScan, 
 											template, 	
 											true, 				// fail on 1st failure
 											(ConglomerateController)null,
-											firstFailedRow);
+                                            firstFailedRow,
+                                            fkInfo.schemaName,
+                                            fkInfo.tableName,
+                                            fkInfo.fkIds[0],
+                                            fkInfo.deferrable[0],
+                                            fkConglom,
+                                            pkConglom);
 	
 				int numFailures = riChecker.doCheck();
 				if (numFailures > 0)
@@ -1850,7 +1861,8 @@ class InsertResultSet extends DMLWriteRe
 
                 indexOrConstraintName = conDesc.getConstraintName();
                 deferred = lcc.isEffectivelyDeferred(
-                        activation, cd.getConglomerateNumber());
+                        lcc.getCurrentSQLSessionContext(activation),
+                        cd.getConglomerateNumber());
                 deferrable = conDesc.deferrable();
             }
 
@@ -2414,7 +2426,8 @@ class InsertResultSet extends DMLWriteRe
 					ConstraintDescriptor conDesc = 
                         dd.getConstraintDescriptor(td, cd.getUUID());
 					indexOrConstraintName = conDesc.getConstraintName();
-                    deferred = lcc.isEffectivelyDeferred(activation,
+                    deferred = lcc.isEffectivelyDeferred(
+                            lcc.getCurrentSQLSessionContext(activation),
                             cd.getConglomerateNumber());
                     uniqueDeferrable = conDesc.deferrable();
 				}

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=1590849&r1=1590848&r2=1590849&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 Tue Apr 29 00:23:52 2014
@@ -22,27 +22,19 @@
 package org.apache.derby.impl.sql.execute;
 
 import java.util.Enumeration;
-import org.apache.derby.shared.common.sanity.SanityManager;
-import org.apache.derby.iapi.services.io.StreamStorable;
-
+import org.apache.derby.catalog.types.ReferencedColumnsDescriptorImpl;
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.services.loader.GeneratedMethod;
+import org.apache.derby.iapi.sql.Activation;
 import org.apache.derby.iapi.sql.conn.StatementContext;
-
 import org.apache.derby.iapi.sql.execute.CursorResultSet;
 import org.apache.derby.iapi.sql.execute.ExecRow;
 import org.apache.derby.iapi.sql.execute.NoPutResultSet;
-
+import org.apache.derby.iapi.sql.execute.RowChanger;
 import org.apache.derby.iapi.types.DataValueDescriptor;
-import org.apache.derby.iapi.sql.Activation;
-
-import org.apache.derby.iapi.services.loader.GeneratedMethod;
-
-import org.apache.derby.iapi.error.StandardException;
-
 import org.apache.derby.iapi.types.RowLocation;
-
-import org.apache.derby.catalog.types.ReferencedColumnsDescriptorImpl;
-import org.apache.derby.iapi.sql.execute.RowChanger;
 import org.apache.derby.iapi.types.SQLRef;
+import org.apache.derby.shared.common.sanity.SanityManager;
 
 
 /**
@@ -79,10 +71,9 @@ class ProjectRestrictResultSet extends N
 	private boolean shortCircuitOpen;
 
 	private ExecRow projRow;
-    private boolean validatingCheckConstraint;
-    private long validatingBaseTableCID;
-    DeferredConstraintsMemory.CheckInfo ci;
-    Enumeration rowLocations;
+    private final boolean validatingCheckConstraint;
+    private final long validatingBaseTableCID;
+    Enumeration<Object> rowLocations;
 
     // class interface
     //
@@ -179,11 +170,9 @@ class ProjectRestrictResultSet extends N
 		}
 
         if (validatingCheckConstraint) {
-            ci = (DeferredConstraintsMemory.CheckInfo)activation.
-                getLanguageConnectionContext().
-                getDeferredHashTables().get(
-                    Long.valueOf(validatingBaseTableCID));
-            rowLocations = ci.infoRows.elements();
+            rowLocations = DeferredConstraintsMemory.
+                getDeferredCheckConstraintLocations(
+                        activation, validatingBaseTableCID);
         }
 
 

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=1590849&r1=1590848&r2=1590849&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 Tue Apr 29 00:23:52 2014
@@ -21,25 +21,17 @@
 
 package org.apache.derby.impl.sql.execute;
 
-import org.apache.derby.shared.common.sanity.SanityManager;
-
+import org.apache.derby.catalog.UUID;
 import org.apache.derby.iapi.error.StandardException;
-import org.apache.derby.iapi.sql.ResultSet;
-
-import org.apache.derby.iapi.types.BooleanDataValue;
-import org.apache.derby.iapi.types.DataValueDescriptor;
-import org.apache.derby.iapi.types.RowLocation;
-import org.apache.derby.iapi.sql.execute.ExecRow;
+import org.apache.derby.iapi.sql.Activation;
 import org.apache.derby.iapi.sql.LanguageProperties;
-
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
+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.GenericScanController;
 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.services.io.FormatableBitSet;
+import org.apache.derby.iapi.types.RowLocation;
 
 /**
  * Do a merge run comparing all the foreign keys from the
@@ -66,8 +58,16 @@ public class RIBulkChecker 
 	private static final int GREATER_THAN = 1;
 	private static final int LESS_THAN = -1;
 
-	private FKInfo			fkInfo;
-	private GroupFetchScanController	referencedKeyScan;
+    private final long            fkCID;
+    private final long            pkCID;
+    private final String          schemaName;
+    private final String          tableName;
+    private final UUID            constraintId;
+    private BackingStoreHashtable deferredRowsHashTable; // cached value
+    private final LanguageConnectionContext lcc;
+    private final boolean deferred; // constraint is deferred
+
+    private GroupFetchScanController    referencedKeyScan;
 	private DataValueDescriptor[][]		referencedKeyRowArray;
 	private GroupFetchScanController	foreignKeyScan;
 	private DataValueDescriptor[][]		foreignKeyRowArray;
@@ -80,10 +80,10 @@ public class RIBulkChecker 
 	private int				lastRefRowIndex;
 	private int				lastFKRowIndex;
 	private ExecRow			firstRowToFail;
-
     /**
      * Create a RIBulkChecker
 	 * 
+     * @param a                     the activation
 	 * @param referencedKeyScan		scan of the referenced key's
 	 *								backing index.  must be unique
 	 * @param foreignKeyScan		scan of the foreign key's
@@ -95,23 +95,44 @@ public class RIBulkChecker 
 	 * @param unreferencedCC	put unreferenced keys here
 	 * @param firstRowToFail		the first row that fails the constraint
 	 *								is copied to this, if non-null
+     * @param schemaName            schema name of the table we insert into
+     * @param tableName             table name of the table we insert into
+     * @param constraintId          constraint id of the foreign constraint
+     * @param deferrable            {@code true} if the constraint is deferrable
+     * @param fkCID                 conglomerate id of the foreign key
+     *                              supporting index
+     * @param pkCID                 conglomerate id of the referenced primary
+     *                              key or unique index.
+     * @throws org.apache.derby.iapi.error.StandardException
+     *
      */
     public RIBulkChecker
 	(
+            Activation                  a,
 			GroupFetchScanController    referencedKeyScan,
 			GroupFetchScanController	foreignKeyScan,
 			ExecRow					    templateRow,
 			boolean					    quitOnFirstFailure,
 			ConglomerateController	    unreferencedCC,
-			ExecRow					    firstRowToFail
-	)
+            ExecRow                     firstRowToFail,
+            String                      schemaName,
+            String                      tableName,
+            UUID                        constraintId,
+            boolean                     deferrable,
+            long                        fkCID,
+            long                        pkCID
+    ) throws StandardException
 	{
-		this.referencedKeyScan = referencedKeyScan;
+        this.referencedKeyScan = referencedKeyScan;
 		this.foreignKeyScan = foreignKeyScan;
 		this.quitOnFirstFailure = quitOnFirstFailure;
 		this.unreferencedCC = unreferencedCC;
 		this.firstRowToFail = firstRowToFail;
-
+        this.constraintId = constraintId;
+        this.fkCID = fkCID;
+        this.pkCID = pkCID;
+        this.schemaName = schemaName;
+        this.tableName = tableName;
 		foreignKeyRowArray		= new DataValueDescriptor[LanguageProperties.BULK_FETCH_DEFAULT_INT][];
 		foreignKeyRowArray[0]	= templateRow.getRowArrayClone();
 		referencedKeyRowArray	= new DataValueDescriptor[LanguageProperties.BULK_FETCH_DEFAULT_INT][];
@@ -120,10 +141,16 @@ public class RIBulkChecker 
 		numColumns = templateRow.getRowArray().length - 1;
 		currFKRowIndex = -1; 
 		currRefRowIndex = -1; 
+
+        this.lcc = a.getLanguageConnectionContext();
+        this.deferred = deferrable && lcc.isEffectivelyDeferred(
+                lcc.getCurrentSQLSessionContext(a), constraintId);
 	}
 
 	/**
-	 * Perform the check.
+     * Perform the check. If deferred constraint mode, the numbers of failed
+     * rows returned will be always be 0 (but any violating keys will have been
+     * saved for later checking).
 	 *
 	 * @return the number of failed rows
 	 *
@@ -168,7 +195,7 @@ public class RIBulkChecker 
 					failure(foreignKey);
 					if (quitOnFirstFailure)
 					{
-							return 1;
+                            return failedCounter;
 					}
 				} while ((foreignKey = getNextFK()) != null);
 				return failedCounter;
@@ -183,7 +210,7 @@ public class RIBulkChecker 
 						failure(foreignKey);
 						if (quitOnFirstFailure)
 						{
-							return 1;
+                            return failedCounter;
 						}
 					} while ((foreignKey = getNextFK()) != null);
 					return failedCounter;
@@ -195,7 +222,7 @@ public class RIBulkChecker 
 				failure(foreignKey);
 				if (quitOnFirstFailure)
 				{
-					return 1;
+                    return failedCounter;
 				}
 			}	
 		}
@@ -258,21 +285,36 @@ public class RIBulkChecker 
 	private void failure(DataValueDescriptor[] foreignKeyRow)
 		throws StandardException
 	{
-		if (failedCounter == 0)
-		{
-			if (firstRowToFail != null)
-			{
-				firstRowToFail.setRowArray(foreignKeyRow);
-				// clone it
-				firstRowToFail.setRowArray(firstRowToFail.getRowArrayClone());
-			}
-		}
-			
-		failedCounter++;
-		if (unreferencedCC != null)
-		{
-            unreferencedCC.insert(foreignKeyRow);
-		}
+        if (deferred) {
+            deferredRowsHashTable =
+                    DeferredConstraintsMemory.rememberFKViolation(
+                            lcc,
+                            deferredRowsHashTable,
+                            fkCID,
+                            pkCID,
+                            constraintId,
+                            foreignKeyRow,
+                            schemaName,
+                            tableName);
+
+        } else {
+            if (failedCounter == 0)
+            {
+                if (firstRowToFail != null)
+                {
+                    firstRowToFail.setRowArray(foreignKeyRow);
+                    // clone it
+                    firstRowToFail.setRowArray(
+                        firstRowToFail.getRowArrayClone());
+                }
+            }
+
+            failedCounter++;
+            if (unreferencedCC != null)
+            {
+                unreferencedCC.insert(foreignKeyRow);
+            }
+        }
 	}	
 	/*
 	** Returns true if any of the foreign keys are null

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RISetChecker.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RISetChecker.java?rev=1590849&r1=1590848&r2=1590849&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RISetChecker.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RISetChecker.java Tue Apr 29 00:23:52 2014
@@ -21,12 +21,12 @@
 
 package org.apache.derby.impl.sql.execute;
 
-import org.apache.derby.shared.common.sanity.SanityManager;
 import org.apache.derby.iapi.error.StandardException;
-
+import org.apache.derby.iapi.sql.Activation;
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
 import org.apache.derby.iapi.sql.execute.ExecRow;
-import org.apache.derby.iapi.sql.execute.ExecIndexRow;
 import org.apache.derby.iapi.store.access.TransactionController;
+import org.apache.derby.shared.common.sanity.SanityManager;
 
 /**
  * Checks a set or referential integrity constraints.  Used
@@ -36,15 +36,18 @@ import org.apache.derby.iapi.store.acces
 public class RISetChecker
 {
 	private GenericRIChecker[] 	checkers;
+    LanguageConnectionContext lcc;
 
 	/**
+     * @param lcc       the language connection context
 	 * @param tc		the xact controller
 	 * @param fkInfo	the foreign key information 
 	 *
 	 * @exception StandardException		Thrown on failure
 	 */
-	public RISetChecker(TransactionController tc, FKInfo fkInfo[])
-		throws StandardException
+    public RISetChecker(LanguageConnectionContext lcc,
+                        TransactionController tc,
+                        FKInfo fkInfo[]) throws StandardException
 	{
 		if (fkInfo == null)
 		{
@@ -52,12 +55,15 @@ public class RISetChecker
 		}
 
 		checkers = new GenericRIChecker[fkInfo.length];
+        this.lcc = lcc;
 
 		for (int i = 0; i < fkInfo.length; i++)
 		{
 			checkers[i] = (fkInfo[i].type == FKInfo.FOREIGN_KEY) ?
-				(GenericRIChecker)new ForeignKeyRIChecker(tc, fkInfo[i]) :
-				(GenericRIChecker)new ReferencedKeyRIChecker(tc, fkInfo[i]);
+                (GenericRIChecker)new ForeignKeyRIChecker(
+                    lcc, tc, fkInfo[i]) :
+                (GenericRIChecker)new ReferencedKeyRIChecker(
+                    lcc, tc, fkInfo[i]);
 		}
 	}
 
@@ -85,7 +91,9 @@ public class RISetChecker
 	 * @exception StandardException on unexpected error, or
 	 *		on a primary/unique key violation
 	 */
-	public void doPKCheck(ExecRow row, boolean restrictCheckOnly) throws StandardException
+    public void doPKCheck(Activation a,
+                          ExecRow row,
+                          boolean restrictCheckOnly) throws StandardException
 	{
 		if (checkers == null)
 			return;
@@ -94,7 +102,7 @@ public class RISetChecker
 		{
 			if (checkers[i] instanceof ReferencedKeyRIChecker)
 			{
-				checkers[i].doCheck(row,restrictCheckOnly);
+                checkers[i].doCheck(a, row,restrictCheckOnly);
 			}
 		}
 	}
@@ -104,12 +112,13 @@ public class RISetChecker
 	 * that there are no foreign keys in the passed
 	 * in row that have invalid values.
 	 *
+     * @param a     the activation
 	 * @param row	the row to check
 	 *
 	 * @exception StandardException on unexpected error, or
 	 *		on a primary/unique key violation
 	 */
-	public void doFKCheck(ExecRow row) throws StandardException
+    public void doFKCheck(Activation a, ExecRow row) throws StandardException
 	{
 		if (checkers == null)
 			return;
@@ -118,7 +127,7 @@ public class RISetChecker
 		{
 			if (checkers[i] instanceof ForeignKeyRIChecker)
 			{
-				checkers[i].doCheck(row);
+                checkers[i].doCheck(a, row);
 			}
 		}
 	}
@@ -126,13 +135,17 @@ public class RISetChecker
 	/**
 	 * Execute the specific RI check on the passed in row.
 	 *
+     * @param a     the activation
 	 * @param index	index into fkInfo
 	 * @param row		the row to check
 	 *
 	 * @exception StandardException on unexpected error, or
 	 *		on a primary/unique key violation
 	 */
-	public void doRICheck(int index, ExecRow row, boolean restrictCheckOnly) throws StandardException
+    public void doRICheck(Activation a,
+                          int index,
+                          ExecRow row,
+                          boolean restrictCheckOnly) throws StandardException
 	{
 		if (SanityManager.DEBUG)
 		{
@@ -148,7 +161,7 @@ public class RISetChecker
 			}
 		}
 
-		checkers[index].doCheck(row, restrictCheckOnly);
+        checkers[index].doCheck(a, row, restrictCheckOnly);
 	}
 
 	/**

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ReferencedKeyRIChecker.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ReferencedKeyRIChecker.java?rev=1590849&r1=1590848&r2=1590849&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ReferencedKeyRIChecker.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ReferencedKeyRIChecker.java Tue Apr 29 00:23:52 2014
@@ -21,16 +21,18 @@
 
 package org.apache.derby.impl.sql.execute;
 
-import org.apache.derby.shared.common.sanity.SanityManager;
+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.sql.Activation;
+import org.apache.derby.iapi.sql.StatementType;
 import org.apache.derby.iapi.sql.StatementUtil;
-import org.apache.derby.iapi.sql.execute.ExecRow;
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
 import org.apache.derby.iapi.sql.execute.ExecIndexRow;
-import org.apache.derby.iapi.reference.SQLState;
+import org.apache.derby.iapi.sql.execute.ExecRow;
 import org.apache.derby.iapi.store.access.ScanController;
 import org.apache.derby.iapi.store.access.TransactionController;
-import org.apache.derby.iapi.sql.StatementType;
+import org.apache.derby.shared.common.sanity.SanityManager;
 
 /**
  * A Referential Integrity checker for a change
@@ -43,15 +45,17 @@ import org.apache.derby.iapi.sql.Stateme
 public class ReferencedKeyRIChecker extends GenericRIChecker
 {
 	/**
+     * @param lcc       the language connection context
 	 * @param tc		the xact controller
 	 * @param fkinfo	the foreign key information 
 	 *
 	 * @exception StandardException		Thrown on failure
 	 */
-	ReferencedKeyRIChecker(TransactionController tc, FKInfo fkinfo)
-		throws StandardException
+    ReferencedKeyRIChecker(LanguageConnectionContext lcc,
+                           TransactionController tc,
+                           FKInfo fkinfo) throws StandardException
 	{
-		super(tc, fkinfo);
+        super(lcc, tc, fkinfo);
 
 		if (SanityManager.DEBUG)
 		{
@@ -70,12 +74,16 @@ public class ReferencedKeyRIChecker exte
 	 * If a foreign key is found, an exception is thrown.
 	 * If not, the scan is closed.
 	 *
+     * @para, a     the activation
 	 * @param row	the row to check
+     * @param restrictCheckOnly
 	 *
 	 * @exception StandardException on unexpected error, or
 	 *		on a primary/unique key violation
 	 */
-	void doCheck(ExecRow row, boolean restrictCheckOnly) throws StandardException
+    void doCheck(Activation a,
+                 ExecRow row,
+                 boolean restrictCheckOnly) throws StandardException
 	{
 		/*
 		** If any of the columns are null, then the
@@ -105,12 +113,36 @@ public class ReferencedKeyRIChecker exte
 			if (scan.next())
 			{
 				close();
-				StandardException se = StandardException.newException(SQLState.LANG_FK_VIOLATION, fkInfo.fkConstraintNames[i],
-										fkInfo.tableName,
-										StatementUtil.typeName(fkInfo.stmtType),
-										RowUtil.toString(row, fkInfo.colArray));
 
-				throw se;
+                final UUID fkId = fkInfo.fkIds[i];
+
+                // Only considering deferring if we don't have RESTRICT, i.e.
+                // NO ACTION. CASCADE and SET NULL handled elsewhere.
+                if (fkInfo.deferrable[i] &&
+                    fkInfo.raRules[i] != StatementType.RA_RESTRICT &&
+                        lcc.isEffectivelyDeferred(
+                                lcc.getCurrentSQLSessionContext(a), fkId)) {
+                    deferredRowsHashTable =
+                            DeferredConstraintsMemory.rememberFKViolation(
+                                    lcc,
+                                    deferredRowsHashTable,
+                                    fkInfo.fkConglomNumbers[i],
+                                    fkInfo.refConglomNumber,
+                                    fkInfo.fkIds[i],
+                                    indexQualifierRow.getRowArray(),
+                                    fkInfo.schemaName,
+                                    fkInfo.tableName);
+                } else {
+
+                    StandardException se = StandardException.newException(
+                            SQLState.LANG_FK_VIOLATION,
+                            fkInfo.fkConstraintNames[i],
+                            fkInfo.tableName,
+                            StatementUtil.typeName(fkInfo.stmtType),
+                            RowUtil.toString(row, fkInfo.colArray));
+
+                    throw se;
+                }
 			}
 			/*
 			** Move off of the current row to release any locks.

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/SetConstraintsConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/SetConstraintsConstantAction.java?rev=1590849&r1=1590848&r2=1590849&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/SetConstraintsConstantAction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/SetConstraintsConstantAction.java Tue Apr 29 00:23:52 2014
@@ -27,8 +27,10 @@ import org.apache.derby.iapi.error.Stand
 import org.apache.derby.iapi.reference.SQLState;
 import org.apache.derby.iapi.sql.Activation;
 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
+import org.apache.derby.iapi.sql.dictionary.CheckConstraintDescriptor;
 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.SchemaDescriptor;
 import org.apache.derby.iapi.sql.execute.ConstantAction;
@@ -127,20 +129,28 @@ class SetConstraintsConstantAction exten
                             cd.getConstraintName());
                 }
 
-                if (cd instanceof KeyConstraintDescriptor) {
-                    // Set unique, primary key and foreign key constraints
+                if (cd instanceof ForeignKeyConstraintDescriptor ||
+                    cd instanceof CheckConstraintDescriptor) {
+
+                    // Set check constraints and FKs
+                    lcc.setConstraintDeferred(
+                        activation,
+                        ( cd instanceof CheckConstraintDescriptor ?
+                          cd.getTableDescriptor().getHeapConglomerateId() :
+                          ((KeyConstraintDescriptor)cd).
+                          getIndexConglomerateDescriptor(dd).
+                          getConglomerateNumber() ),
+                        cd.getUUID(),
+                        deferred);
 
-                    lcc.setConstraintDeferred(activation,
-                                    ((KeyConstraintDescriptor)cd).
-                                        getIndexConglomerateDescriptor(dd).
-                                        getConglomerateNumber(),
-                                    deferred);
                 } else {
-                    // Set check constraints
+                    // Set unique, primary key
+
                     lcc.setConstraintDeferred(
                             activation,
-                            cd.getTableDescriptor().getHeapConglomerateId(),
-                            cd.getUUID(),
+                            ((KeyConstraintDescriptor)cd).
+                                    getIndexConglomerateDescriptor(dd).
+                                    getConglomerateNumber(),
                             deferred);
                 }
             }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateResultSet.java?rev=1590849&r1=1590848&r2=1590849&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/UpdateResultSet.java Tue Apr 29 00:23:52 2014
@@ -48,6 +48,7 @@ import org.apache.derby.iapi.types.DataV
 import org.apache.derby.iapi.types.RowLocation;
 import org.apache.derby.iapi.types.SQLBoolean;
 import org.apache.derby.iapi.types.SQLRef;
+import org.apache.derby.impl.sql.execute.DeferredConstraintsMemory.CheckInfo;
 import org.apache.derby.shared.common.sanity.SanityManager;
 
 /**
@@ -358,7 +359,7 @@ class UpdateResultSet extends DMLWriteRe
 		{
 			if (riChecker == null)
 			{
-				riChecker = new RISetChecker(tc, fkInfoArray);
+                riChecker = new RISetChecker(lcc, tc, fkInfoArray);
 			}
 			else
 			{
@@ -517,7 +518,8 @@ class UpdateResultSet extends DMLWriteRe
                                 constants.getTableName(),
                                 deferredChecks,
                                 violatingCheckConstraints,
-                                baseRowLocation);
+                                baseRowLocation,
+                                new CheckInfo[1]);
                     }
 				}
 
@@ -593,7 +595,8 @@ class UpdateResultSet extends DMLWriteRe
                             constants.getTableName(),
                             deferredChecks,
                             violatingCheckConstraints,
-                            baseRowLocation);
+                            baseRowLocation,
+                            new CheckInfo[1]);
                 }
 
 				RowUtil.copyRefColumns(newBaseRow,
@@ -611,7 +614,7 @@ class UpdateResultSet extends DMLWriteRe
 					** a referenced key, we'll be updating in deferred
 					** mode, so we wont get here.
 					*/
-					riChecker.doFKCheck(newBaseRow);
+                    riChecker.doFKCheck(activation, newBaseRow);
 				}
 
 				source.updateRow(newBaseRow, rowChanger);
@@ -885,7 +888,8 @@ class UpdateResultSet extends DMLWriteRe
                                 constants.getTableName(),
                                 deferredChecks,
                                 violatingCheckConstraints,
-                                baseRowLocation);
+                                baseRowLocation,
+                                new CheckInfo[1]);
                     }
 
 					/* Get the base row at the given RowLocation */
@@ -958,7 +962,8 @@ class UpdateResultSet extends DMLWriteRe
 										fkInfoArray[i].colArray, 
 										insertedRowHolder))
 						{
-							riChecker.doRICheck(i, deletedRow, restrictCheckOnly);
+                            riChecker.doRICheck(
+                                activation, i, deletedRow, restrictCheckOnly);
 						}
 					}	
 				}
@@ -1002,7 +1007,8 @@ class UpdateResultSet extends DMLWriteRe
 										fkInfoArray[i].colArray, 
 										deletedRowHolder))
 						{
-							riChecker.doRICheck(i, insertedRow, restrictCheckOnly);
+                            riChecker.doRICheck(
+                                activation, i, insertedRow, restrictCheckOnly);
 						}
 					}	
 				}

Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?rev=1590849&r1=1590848&r2=1590849&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Tue Apr 29 00:23:52 2014
@@ -900,7 +900,7 @@ Guide.
 
             <msg>
                 <name>23514.T.1</name>
-                <text>The transaction was aborted because of a deferred constraint violation: Check constraint identified by '{0}' defined on '{1}' as '{2}'.</text>
+                <text>The transaction was aborted because of a deferred constraint violation: Check constraint identified by '{0}' defined on {1} as '{2}'.</text>
                 <arg>indexOrConstraintName</arg>
                 <arg>tableName</arg>
                 <arg>constraintText</arg>
@@ -908,12 +908,32 @@ Guide.
 
             <msg>
                 <name>23515.S.1</name>
-                <text>Deferred constraint violation: Check constraint identified by '{0}' defined on '{1}' as '{2}'.</text>
+                <text>Deferred constraint violation: Check constraint identified by '{0}' defined on {1} as '{2}'.</text>
                 <arg>indexOrConstraintName</arg>
                 <arg>tableName</arg>
                 <arg>constraintText</arg>
             </msg>
 
+            <msg>
+                <name>23516.T.1</name>
+                <text>The transaction was aborted because of a deferred constraint violation: Foreign key '{0}' defined on {1} referencing referencing constraint '{2}' defined on {3}, key '{4}'.</text>
+                <arg>indexOrConstraintName</arg>
+                <arg>tableName</arg>
+                <arg>indexOrConstraintName</arg>
+                <arg>tableName</arg>
+                <arg>keyName</arg>
+            </msg>
+
+            <msg>
+                <name>23517.S.1</name>
+                <text>Deferred constraint violation: Foreign key constraint '{0}' defined on {1} referencing constraint '{2}' defined on {3}, key '{4}'.</text>
+                <arg>indexOrConstraintName</arg>
+                <arg>tableName</arg>
+                <arg>indexOrConstraintName</arg>
+                <arg>tableName</arg>
+                <arg>keyName</arg>
+            </msg>
+
         </family>
 
 

Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=1590849&r1=1590848&r2=1590849&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java Tue Apr 29 00:23:52 2014
@@ -747,6 +747,8 @@ public interface SQLState {
     String LANG_DEFERRED_CHECK_CONSTRAINT_T                            = "23514.T.1";
     String LANG_DEFERRED_CHECK_CONSTRAINT_S                            = "23515.S.1";
 
+    String LANG_DEFERRED_FK_CONSTRAINT_T                               = "23516.T.1";
+    String LANG_DEFERRED_FK_CONSTRAINT_S                               = "23517.S.1";
 	// From SQL/XML[2006] spec; there are others, but
 	// these are the ones we actually use with our
 	// current XML support.