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 ka...@apache.org on 2014/02/06 14:30:13 UTC

svn commit: r1565233 - in /db/derby/code/branches/10.9: ./ java/engine/org/apache/derby/iapi/sql/dictionary/ java/engine/org/apache/derby/impl/sql/compile/ java/engine/org/apache/derby/impl/sql/execute/ java/testing/org/apache/derbyTesting/functionTest...

Author: kahatlen
Date: Thu Feb  6 13:30:12 2014
New Revision: 1565233

URL: http://svn.apache.org/r1565233
Log:
DERBY-5866: Triggers fire out of order

Merged revision 1560616 from 10.10.

Added:
    db/derby/code/branches/10.9/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Derby5866TriggerOrderTest.java
      - copied unchanged from r1560616, db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Derby5866TriggerOrderTest.java
Modified:
    db/derby/code/branches/10.9/   (props changed)
    db/derby/code/branches/10.9/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java
    db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/sql/compile/CreateTriggerNode.java
    db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/sql/execute/CreateTriggerConstantAction.java
    db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/sql/execute/GenericConstantActionFactory.java
    db/derby/code/branches/10.9/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java
    db/derby/code/branches/10.9/java/testing/org/apache/derbyTesting/junit/TimeZoneTestSetup.java

Propchange: db/derby/code/branches/10.9/
------------------------------------------------------------------------------
  Merged /db/derby/code/trunk:r1555702
  Merged /db/derby/code/branches/10.10:r1560616

Modified: db/derby/code/branches/10.9/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.9/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java?rev=1565233&r1=1565232&r2=1565233&view=diff
==============================================================================
--- db/derby/code/branches/10.9/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java (original)
+++ db/derby/code/branches/10.9/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java Thu Feb  6 13:30:12 2014
@@ -1324,8 +1324,9 @@ public interface DataDictionary
 	/**
 	 * Load up the trigger descriptor list for this table
 	 * descriptor and return it.  If the descriptor list
-	 * is already loaded up, it is retuned without further
-	 * ado.
+     * is already loaded up, it is returned without further
+     * ado. The descriptors are returned in the order in
+     * which the triggers were created, with the oldest first.
 	 *
 	 * @param td			The table descriptor.
 	 *

Modified: db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/sql/compile/CreateTriggerNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/sql/compile/CreateTriggerNode.java?rev=1565233&r1=1565232&r2=1565233&view=diff
==============================================================================
--- db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/sql/compile/CreateTriggerNode.java (original)
+++ db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/sql/compile/CreateTriggerNode.java Thu Feb  6 13:30:12 2014
@@ -873,7 +873,6 @@ public class CreateTriggerNode extends D
 											(actionCompSchemaId == null) ?
 												compSchemaDescriptor.getUUID() :
 												actionCompSchemaId,
-											(Timestamp)null,	// creation time
 											referencedColInts,
 											referencedColsInTriggerAction,
 											originalActionText,

Modified: db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/sql/execute/CreateTriggerConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/sql/execute/CreateTriggerConstantAction.java?rev=1565233&r1=1565232&r2=1565233&view=diff
==============================================================================
--- db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/sql/execute/CreateTriggerConstantAction.java (original)
+++ db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/sql/execute/CreateTriggerConstantAction.java Thu Feb  6 13:30:12 2014
@@ -21,6 +21,7 @@
 
 package org.apache.derby.impl.sql.execute;
 
+import org.apache.derby.iapi.services.property.PropertyUtil;
 import org.apache.derby.iapi.store.access.TransactionController;
 
 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
@@ -29,6 +30,7 @@ import org.apache.derby.iapi.sql.execute
 
 import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
+import org.apache.derby.iapi.sql.dictionary.GenericDescriptorList;
 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
 import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;
 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
@@ -79,7 +81,6 @@ class CreateTriggerConstantAction extend
 	private String					oldReferencingName;
 	private String					newReferencingName;
 	private UUID					spsCompSchemaId;
-	private Timestamp				creationTimestamp;
 	private int[]					referencedCols;
 	private int[]					referencedColsInTriggerAction;
 
@@ -102,8 +103,6 @@ class CreateTriggerConstantAction extend
 	 * @param spsCompSchemaId	the compilation schema for the action and when
 	 *							spses.   If null, will be set to the current default
 	 *							schema
-	 * @param creationTimestamp	when was this trigger created?  if null, will be
-	 *						set to the time that executeConstantAction() is invoked
 	 * @param referencedCols	what columns does this trigger reference (may be null)
 	 * @param referencedColsInTriggerAction	what columns does the trigger 
 	 *						action reference through old/new transition variables
@@ -128,7 +127,6 @@ class CreateTriggerConstantAction extend
 		UUID				actionSPSId,
 		String				actionText,
 		UUID				spsCompSchemaId,
-		Timestamp			creationTimestamp,
 		int[]				referencedCols,
 		int[]				referencedColsInTriggerAction,
 		String				originalActionText,
@@ -151,7 +149,6 @@ class CreateTriggerConstantAction extend
 		this.actionSPSId = actionSPSId;
 		this.actionText = actionText;
 		this.spsCompSchemaId = spsCompSchemaId;
-		this.creationTimestamp = creationTimestamp;
 		this.referencedCols = referencedCols;
 		this.referencedColsInTriggerAction = referencedColsInTriggerAction;
 		this.originalActionText = originalActionText;
@@ -308,7 +305,7 @@ class CreateTriggerConstantAction extend
 									triggerTable,
 									whenspsd == null ? null : whenspsd.getUUID(),
 									actionSPSId,
-									creationTimestamp == null ? new Timestamp(System.currentTimeMillis()) : creationTimestamp,
+                                    makeCreationTimestamp(dd),
 									referencedCols,
 									referencedColsInTriggerAction,
 									originalActionText,
@@ -414,6 +411,54 @@ class CreateTriggerConstantAction extend
 	{
 		return constructToString("CREATE TRIGGER ", triggerName);		
 	}
-}
 
+    /**
+     * Construct the creation timestamp for the trigger. DERBY-5866: Also make
+     * sure the creation timestamp is higher than any timestamp on an existing
+     * trigger on the same table. Otherwise, the triggers may not fire in the
+     * correct order.
+     */
+    private Timestamp makeCreationTimestamp(DataDictionary dd)
+            throws StandardException {
+        Timestamp now = new Timestamp(System.currentTimeMillis());
+
+        // Allow overriding the timestamp in debug mode for testing of
+        // specific scenarios.
+        if (SanityManager.DEBUG) {
+            String val = PropertyUtil.getSystemProperty(
+                    "derby.debug.overrideTriggerCreationTimestamp");
+            if (val != null) {
+                now.setTime(Long.parseLong(val));
+            }
+        }
+
+        GenericDescriptorList tdl = dd.getTriggerDescriptors(triggerTable);
+        int numTriggers = tdl.size();
+
+        if (numTriggers == 0) {
+            // This is the first trigger on the table, so no need to check
+            // if there are any higher timestamps.
+            return now;
+        }
+
+        // Get the timestamp of the most recent existing trigger on the table.
+        Timestamp highest = ((TriggerDescriptor) tdl.get(numTriggers - 1))
+                                                     .getCreationTimestamp();
+
+        if (now.after(highest)) {
+            // The current timestamp is higher than the most recent existing
+            // trigger on the table, so it is OK.
+            return now;
+        }
+
+        // Otherwise, there is an existing trigger on the table with a
+        // timestamp that is at least as high as the current timestamp. Adjust
+        // the current timestamp so that it is one millisecond higher than the
+        // timestamp of the existing trigger. This ensures that the triggers
+        // will fire in the same order as they were created.
+
+        now.setTime(highest.getTime() + 1);
 
+        return now;
+    }
+}

Modified: db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/sql/execute/GenericConstantActionFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/sql/execute/GenericConstantActionFactory.java?rev=1565233&r1=1565232&r2=1565233&view=diff
==============================================================================
--- db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/sql/execute/GenericConstantActionFactory.java (original)
+++ db/derby/code/branches/10.9/java/engine/org/apache/derby/impl/sql/execute/GenericConstantActionFactory.java Thu Feb  6 13:30:12 2014
@@ -959,8 +959,6 @@ public class GenericConstantActionFactor
 	 * @param spsCompSchemaId	the compilation schema for the action and when
 	 *							spses.   If null, will be set to the current default
 	 *							schema
-	 * @param creationTimestamp	when was this trigger created?  if null, will be
-	 *						set to the time that executeConstantAction() is invoked
 	 * @param referencedCols	what columns does this trigger reference (may be null)
 	 * @param referencedColsInTriggerAction	what columns does the trigger 
 	 *						action reference through old/new transition variables
@@ -985,7 +983,6 @@ public class GenericConstantActionFactor
 		UUID				actionSPSId,
 		String				actionText,
 		UUID				spsCompSchemaId,
-		Timestamp			creationTimestamp,
 		int[]				referencedCols,
 		int[]				referencedColsInTriggerAction,
 		String				originalActionText,
@@ -997,7 +994,7 @@ public class GenericConstantActionFactor
 	{
 		return new CreateTriggerConstantAction(triggerSchemaName, triggerName, 
 				eventMask, isBefore, isRow, isEnabled, triggerTable, whenSPSId,
-				whenText, actionSPSId, actionText, spsCompSchemaId, creationTimestamp,
+                whenText, actionSPSId, actionText, spsCompSchemaId,
 				referencedCols, referencedColsInTriggerAction, originalActionText,
 				referencingOld, referencingNew, oldReferencingName, newReferencingName);
 	}

Modified: db/derby/code/branches/10.9/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.9/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java?rev=1565233&r1=1565232&r2=1565233&view=diff
==============================================================================
--- db/derby/code/branches/10.9/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java (original)
+++ db/derby/code/branches/10.9/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java Thu Feb  6 13:30:12 2014
@@ -225,6 +225,7 @@ public class _Suite extends BaseTestCase
         suite.addTest(Derby5652.suite());
         suite.addTest(QueryPlanTest.suite());
         suite.addTest(Derby6131.suite());
+        suite.addTest(Derby5866TriggerOrderTest.suite());
         return suite;
 	}
 }

Modified: db/derby/code/branches/10.9/java/testing/org/apache/derbyTesting/junit/TimeZoneTestSetup.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.9/java/testing/org/apache/derbyTesting/junit/TimeZoneTestSetup.java?rev=1565233&r1=1565232&r2=1565233&view=diff
==============================================================================
--- db/derby/code/branches/10.9/java/testing/org/apache/derbyTesting/junit/TimeZoneTestSetup.java (original)
+++ db/derby/code/branches/10.9/java/testing/org/apache/derbyTesting/junit/TimeZoneTestSetup.java Thu Feb  6 13:30:12 2014
@@ -70,7 +70,7 @@ public class TimeZoneTestSetup extends B
         requestedDefault = null;
     }
     
-    private void setDefault(final TimeZone tz) throws SecurityException{
+    public static void setDefault(final TimeZone tz) {
         if (tz== null) {
             throw new IllegalArgumentException("tz cannot be <null>");
         }