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/01/23 10:26:59 UTC
svn commit: r1560616 - in /db/derby/code/branches/10.10: ./
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/functionTes...
Author: kahatlen
Date: Thu Jan 23 09:26:59 2014
New Revision: 1560616
URL: http://svn.apache.org/r1560616
Log:
DERBY-5866: Triggers fire out of order
Merged revision 1555702 from trunk.
Added:
db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Derby5866TriggerOrderTest.java
- copied, changed from r1555702, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Derby5866TriggerOrderTest.java
Modified:
db/derby/code/branches/10.10/ (props changed)
db/derby/code/branches/10.10/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java
db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/compile/CreateTriggerNode.java
db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/execute/CreateTriggerConstantAction.java
db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/execute/GenericConstantActionFactory.java
db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java
db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/junit/TimeZoneTestSetup.java
Propchange: db/derby/code/branches/10.10/
------------------------------------------------------------------------------
Merged /db/derby/code/trunk:r1555702
Modified: db/derby/code/branches/10.10/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java?rev=1560616&r1=1560615&r2=1560616&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java (original)
+++ db/derby/code/branches/10.10/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java Thu Jan 23 09:26:59 2014
@@ -1334,8 +1334,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.10/java/engine/org/apache/derby/impl/sql/compile/CreateTriggerNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/compile/CreateTriggerNode.java?rev=1560616&r1=1560615&r2=1560616&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/compile/CreateTriggerNode.java (original)
+++ db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/compile/CreateTriggerNode.java Thu Jan 23 09:26:59 2014
@@ -871,7 +871,6 @@ public class CreateTriggerNode extends D
(actionCompSchemaId == null) ?
compSchemaDescriptor.getUUID() :
actionCompSchemaId,
- (Timestamp)null, // creation time
referencedColInts,
referencedColsInTriggerAction,
originalActionText,
Modified: db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/execute/CreateTriggerConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/execute/CreateTriggerConstantAction.java?rev=1560616&r1=1560615&r2=1560616&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/execute/CreateTriggerConstantAction.java (original)
+++ db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/execute/CreateTriggerConstantAction.java Thu Jan 23 09:26:59 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.10/java/engine/org/apache/derby/impl/sql/execute/GenericConstantActionFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/execute/GenericConstantActionFactory.java?rev=1560616&r1=1560615&r2=1560616&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/execute/GenericConstantActionFactory.java (original)
+++ db/derby/code/branches/10.10/java/engine/org/apache/derby/impl/sql/execute/GenericConstantActionFactory.java Thu Jan 23 09:26:59 2014
@@ -947,8 +947,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
@@ -973,7 +971,6 @@ public class GenericConstantActionFactor
UUID actionSPSId,
String actionText,
UUID spsCompSchemaId,
- Timestamp creationTimestamp,
int[] referencedCols,
int[] referencedColsInTriggerAction,
String originalActionText,
@@ -985,7 +982,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);
}
Copied: db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Derby5866TriggerOrderTest.java (from r1555702, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Derby5866TriggerOrderTest.java)
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Derby5866TriggerOrderTest.java?p2=db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Derby5866TriggerOrderTest.java&p1=db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Derby5866TriggerOrderTest.java&r1=1555702&r2=1560616&rev=1560616&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Derby5866TriggerOrderTest.java (original)
+++ db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/Derby5866TriggerOrderTest.java Thu Jan 23 09:26:59 2014
@@ -61,7 +61,6 @@ public class Derby5866TriggerOrderTest e
return new TimeZoneTestSetup(test, TIMEZONE);
}
- @Override
protected void tearDown() throws Exception {
// Reset the time zone after each test case, since the test case
// may have altered it.
@@ -117,7 +116,7 @@ public class Derby5866TriggerOrderTest e
*/
public void testEqualTimestamps() throws SQLException {
Timestamp now = new Timestamp(System.currentTimeMillis());
- testSpecificTimestamps(now, now, now);
+ testSpecificTimestamps(new Timestamp[]{ now, now, now });
}
/**
@@ -126,8 +125,11 @@ public class Derby5866TriggerOrderTest e
*/
public void testReversedTimestamps() throws SQLException {
long now = System.currentTimeMillis();
- testSpecificTimestamps(new Timestamp(now), new Timestamp(now - 1),
- new Timestamp(now - 2), new Timestamp(now - 3));
+ Timestamp[] args = {
+ new Timestamp(now), new Timestamp(now - 1),
+ new Timestamp(now - 2), new Timestamp(now - 3)
+ };
+ testSpecificTimestamps(args);
}
/**
@@ -145,8 +147,9 @@ public class Derby5866TriggerOrderTest e
// Test that triggers are ordered correctly if they are created
// 15 min before switch and 15 min after switch.
- testSpecificTimestamps(new Timestamp(cal.getTimeInMillis()),
- new Timestamp(cal.getTimeInMillis() + 1800000));
+ Timestamp[] args = { new Timestamp(cal.getTimeInMillis()),
+ new Timestamp(cal.getTimeInMillis() + 1800000) };
+ testSpecificTimestamps(args);
// 15 min before Central European Time switches from DST.
cal.clear();
@@ -154,22 +157,23 @@ public class Derby5866TriggerOrderTest e
// Test that triggers are ordered correctly if they are created
// 15 min before switch and 15 min after switch.
- testSpecificTimestamps(new Timestamp(cal.getTimeInMillis()),
- new Timestamp(cal.getTimeInMillis() + 1800000));
+ args = new Timestamp[] { new Timestamp(cal.getTimeInMillis()),
+ new Timestamp(cal.getTimeInMillis() + 1800000) };
+ testSpecificTimestamps(args);
// Last millisecond before switch to DST.
cal.clear();
cal.set(2014, Calendar.MARCH, 30, 0, 59, 59);
cal.set(Calendar.MILLISECOND, 999);
Timestamp ts = new Timestamp(cal.getTimeInMillis());
- testSpecificTimestamps(ts, ts, ts);
+ testSpecificTimestamps(new Timestamp[] { ts, ts, ts });
// Last millisecond before switch from DST.
cal.clear();
cal.set(2014, Calendar.OCTOBER, 26, 0, 59, 59);
cal.set(Calendar.MILLISECOND, 999);
ts = new Timestamp(cal.getTimeInMillis());
- testSpecificTimestamps(ts, ts, ts);
+ testSpecificTimestamps(new Timestamp[] { ts, ts, ts });
}
/**
@@ -179,18 +183,18 @@ public class Derby5866TriggerOrderTest e
public void testPreEpoch() throws SQLException {
// 24 hours before the epoch
Timestamp ts = new Timestamp(-3600L * 24 * 1000);
- testSpecificTimestamps(ts, ts, ts);
+ testSpecificTimestamps(new Timestamp[] { ts, ts, ts });
// Test with some non-zero fractions as well.
ts.setNanos(123000000);
- testSpecificTimestamps(ts, ts, ts);
+ testSpecificTimestamps(new Timestamp[] { ts, ts, ts });
ts.setNanos(567000000);
- testSpecificTimestamps(ts, ts, ts);
+ testSpecificTimestamps(new Timestamp[] { ts, ts, ts });
ts.setNanos(999000000);
- testSpecificTimestamps(ts, ts, ts);
+ testSpecificTimestamps(new Timestamp[] { ts, ts, ts });
}
/**
@@ -201,7 +205,7 @@ public class Derby5866TriggerOrderTest e
* overriding the creation timestamps, and verify that they fire in the
* expected order.
*/
- private void testSpecificTimestamps(Timestamp... timestamps)
+ private void testSpecificTimestamps(Timestamp[] timestamps)
throws SQLException {
setAutoCommit(false);
Modified: db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java?rev=1560616&r1=1560615&r2=1560616&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java (original)
+++ db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java Thu Jan 23 09:26:59 2014
@@ -237,6 +237,7 @@ public class _Suite extends BaseTestCase
suite.addTest(TruncateTableAndOnlineBackupTest.suite());
suite.addTest(QueryPlanTest.suite());
suite.addTest(Derby6131.suite());
+ suite.addTest(Derby5866TriggerOrderTest.suite());
return suite;
}
}
Modified: db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/junit/TimeZoneTestSetup.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/junit/TimeZoneTestSetup.java?rev=1560616&r1=1560615&r2=1560616&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/junit/TimeZoneTestSetup.java (original)
+++ db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/junit/TimeZoneTestSetup.java Thu Jan 23 09:26:59 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>");
}