db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kahat...@apache.org
Subject svn commit: r1526831 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/services/io/ engine/org/apache/derby/iapi/sql/compile/ engine/org/apache/derby/iapi/sql/dictionary/ engine/org/apache/derby/impl/sql/catalog/ engine/org/apache/derby/impl...
Date Fri, 27 Sep 2013 08:41:48 GMT
Author: kahatlen
Date: Fri Sep 27 08:41:47 2013
New Revision: 1526831

URL: http://svn.apache.org/r1526831
Log:
DERBY-534: Support use of the WHEN clause in CREATE TRIGGER statements

Allow references to transition variables and transition tables in the
WHEN clause. To support this, a new column WHENCLAUSETEXT is added to
the SYS.SYSTRIGGERS table, and a corresponding field is added to the
TriggerDescriptor class.

The logic that transforms triggered SQL statements to internal syntax
for accessing the transition variables and transition tables (via Java
method calls and VTIs) is reused on the WHEN clause text so that the
same transformation happens there.

Upgrade logic is added so that the new column in SYS.SYSTRIGGERS will
be created when a database is upgraded from an older version. The WHEN
clause is now disabled in the parser when running in soft upgrade
mode. An upgrade test case checks that the WHEN clause can only be
used in a hard-upgraded database, and that a reasonable error is
raised otherwise.

Added:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TriggerDescriptor_v10_10.java   (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_11.java   (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/Parser.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/CatalogRowFactory.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDescriptorGenerator.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TriggerDescriptor.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SYSTRIGGERSRowFactory.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CreateTriggerNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ParserImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateTriggerConstantAction.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericConstantActionFactory.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/dblook_test_net.out
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/dblook_test_net_territory.out
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/dblook_test.out
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/dblook_test_territory.out
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SystemCatalogTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/TriggerWhenClauseTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/UpgradeRun.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/RegisteredFormatIds.java Fri Sep 27 08:41:47 2013
@@ -364,8 +364,8 @@ private static final    String[] TwoByte
         /* 312 */       "org.apache.derby.catalog.types.MethodAliasInfo",
         /* 313 */       "org.apache.derby.iapi.services.io.FormatableHashtable",
         /* 314 */       null,
-        /* 315 */       null,
-        /* 316 */       "org.apache.derby.iapi.sql.dictionary.TriggerDescriptor",
+        /* 315 */       "org.apache.derby.iapi.sql.dictionary.TriggerDescriptor",
+        /* 316 */       "org.apache.derby.iapi.sql.dictionary.TriggerDescriptor_v10_10",
         /* 317 */       "org.apache.derby.impl.sql.execute.TriggerInfo",
         /* 318 */       null,
         /* 319 */       null,

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/StoredFormatIds.java Fri Sep 27 08:41:47 2013
@@ -374,7 +374,15 @@ public interface StoredFormatIds {
             (MIN_ID_2 + 320);
 
     /**
-    class org.apache.derby.impl.sql.catalog.TriggerDescriptorFinder
+     * Class org.apache.derby.impl.sql.catalog.TriggerDescriptor, used for
+     * trigger descriptors if the dictionary version is 10.11 or higher.
+     */
+    static public final int TRIGGER_DESCRIPTOR_V02_ID =
+            (MIN_ID_2 + 315);
+
+    /**
+     * Class org.apache.derby.impl.sql.catalog.TriggerDescriptor_v10_10, used
+     * for trigger descriptors if the dictionary version is 10.10 or lower.
      */
     static public final int TRIGGER_DESCRIPTOR_V01_ID =
             (MIN_ID_2 + 316);
@@ -1111,18 +1119,6 @@ public interface StoredFormatIds {
             (MIN_ID_2 + 289);
     
     /**
-    class org.apache.derby.impl.sql.execute.CreateTriggerConstantAction
-     */
-    static public final int CREATE_TRIGGER_CONSTANT_ACTION_V01_ID   =
-            (MIN_ID_2 + 314);
-    
-    /**
-    class org.apache.derby.impl.sql.execute.DropTriggerConstantAction
-     */
-    static public final int DROP_TRIGGER_CONSTANT_ACTION_V01_ID     =
-            (MIN_ID_2 + 315);
-
-    /**
     class org.apache.derby.impl.sql.execute.TriggerInfo
      */
     static public final int TRIGGER_INFO_V01_ID     =

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/Parser.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/Parser.java?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/Parser.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/Parser.java Fri Sep 27 08:41:47 2013
@@ -58,6 +58,16 @@ public interface Parser
 	public Visitable parseStatement(String statementSQLText)
 		throws StandardException;
 
+    /**
+     * Parse an SQL fragment that represents a {@code <search condition>}.
+     *
+     * @param sqlFragment the SQL fragment to parse
+     * @return a parse tree representing the search condition
+     * @throws StandardException if the SQL fragment could not be parsed
+     */
+    public Visitable parseSearchCondition(String sqlFragment)
+        throws StandardException;
+
 	/**
 	 * Returns the current SQL text string that is being parsed.
 	 *

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/CatalogRowFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/CatalogRowFactory.java?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/CatalogRowFactory.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/CatalogRowFactory.java Fri Sep 27 08:41:47 2013
@@ -33,7 +33,6 @@ import org.apache.derby.iapi.sql.execute
 import org.apache.derby.iapi.sql.execute.ExecutionFactory;
 import org.apache.derby.iapi.store.raw.RawStoreFactory;
 import org.apache.derby.iapi.types.DataValueFactory;
-import org.apache.derby.iapi.util.StringUtil;
 
 /**
  * Superclass of all row factories.
@@ -294,7 +293,7 @@ public abstract	class CatalogRowFactory
 	 *
 	 * @return The number of columns in the heap.
 	 */
-	public final int getHeapColumnCount()
+    public int getHeapColumnCount() throws StandardException
 	{
 		return columnCount;
 	}
@@ -307,6 +306,28 @@ public abstract	class CatalogRowFactory
  		return	this.makeRow(null, null);
 	}
 
+    /**
+     * <p>
+     * Create an empty row for this conglomerate, in the format that would
+     * be used in a database that was created with, or hard upgraded to,
+     * the currently running version. That is, even if the database is only
+     * soft-upgraded, this method should return a row in the new format.
+     * </p>
+     *
+     * <p>
+     * This method is for use in code that creates the catalogs, or that
+     * upgrades the format of the catalogs to the newest version. Other code
+     * should call {@link #makeEmptyRow()}, which returns a row in the format
+     * used in the old database version if the database is soft-upgraded.
+     * </p>
+     *
+     * @return an empty row
+     * @throws StandardException if an error happens when creating the row
+     */
+    public ExecRow makeEmptyRowForCurrentVersion() throws StandardException {
+        return makeEmptyRow();
+    }
+
 	/**
 	 * most subclasses should provide this method. One or two oddball cases in
 	 * Replication and SysSTATEMENTSRowFactory don't. For those we call makeRow

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDescriptorGenerator.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDescriptorGenerator.java?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDescriptorGenerator.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDescriptorGenerator.java Fri Sep 27 08:41:47 2013
@@ -350,6 +350,8 @@ public class DataDescriptorGenerator 
 	 * @param referencingNew whether or not NEW appears in REFERENCING clause
 	 * @param oldReferencingName old referencing table name, if any, that appears in REFERCING clause
 	 * @param newReferencingName new referencing table name, if any, that appears in REFERCING clause
+     * @param whenClauseText the SQL text of the WHEN clause (may be null)
+     * @return a trigger descriptor
 	 *
 	 * @exception StandardException on error
 	 */
@@ -372,10 +374,16 @@ public class DataDescriptorGenerator 
 		boolean				referencingOld,
 		boolean				referencingNew,
 		String				oldReferencingName,
-		String				newReferencingName
+        String              newReferencingName,
+        String              whenClauseText
 	) throws StandardException
 	{
-		return new TriggerDescriptor(
+        if (dataDictionary.checkVersion(
+                DataDictionary.DD_VERSION_DERBY_10_11, null)) {
+            // The dictionary version is recent enough to support the WHEN
+            // clause (DERBY-534). Create a descriptor that uses the new
+            // format.
+            return new TriggerDescriptor(
 					dataDictionary,
 					sd,
 					uuid,
@@ -394,8 +402,34 @@ public class DataDescriptorGenerator 
 					referencingOld,
 					referencingNew,
 					oldReferencingName,
-					newReferencingName
+                    newReferencingName,
+                    whenClauseText
 					);
+        }
+
+        // This is a soft-upgraded database whose dictionary version is 10.10
+        // or lower. Create a descriptor that uses the legacy format so that
+        // it can be read by older database versions.
+        return new TriggerDescriptor_v10_10(
+                dataDictionary,
+                sd,
+                uuid,
+                name,
+                eventMask,
+                isBefore,
+                isRow,
+                isEnabled,
+                td,
+                whenSPSId,
+                actionSPSId,
+                creationTimestamp,
+                referencedCols,
+                referencedColsInTriggerAction,
+                triggerDefinition,
+                referencingOld,
+                referencingNew,
+                oldReferencingName,
+                newReferencingName);
 	}
 		
 	/*

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TriggerDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TriggerDescriptor.java?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TriggerDescriptor.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TriggerDescriptor.java Fri Sep 27 08:41:47 2013
@@ -75,6 +75,7 @@ import java.io.IOException;
  * <li> public SPSDescriptor getActionSPS();
  * <li>	public UUID getWhenClauseId();
  * <li>	public SPSDescriptor getWhenClauseSPS()
+ * <li> public String getWhenClauseText();
  * <li>	public TableDescriptor getTableDescriptor()
  * <li> public ReferencedColumns getReferencedColumnsDescriptor()
  * <li> public int[] getReferencedCols();
@@ -123,6 +124,7 @@ public class TriggerDescriptor extends U
 	private	Timestamp			creationTimestamp;
 	private UUID				triggerSchemaId;
 	private UUID				triggerTableId;
+    private String              whenClauseText;
 
 
 	/**
@@ -154,6 +156,8 @@ public class TriggerDescriptor extends U
 	 * @param referencingNew whether or not NEW appears in REFERENCING clause
 	 * @param oldReferencingName old referencing table name, if any, that appears in REFERCING clause
 	 * @param newReferencingName new referencing table name, if any, that appears in REFERCING clause
+     * @param whenClauseText the SQL text of the WHEN clause, or {@code null}
+     *                       if there is no WHEN clause
 	 */
     TriggerDescriptor
 	(
@@ -175,7 +179,8 @@ public class TriggerDescriptor extends U
 		boolean				referencingOld,
 		boolean				referencingNew,
 		String				oldReferencingName,
-		String				newReferencingName
+        String              newReferencingName,
+        String              whenClauseText
 	)
 	{
 		super(dataDictionary);
@@ -197,6 +202,7 @@ public class TriggerDescriptor extends U
 		this.referencingNew = referencingNew;
 		this.oldReferencingName = oldReferencingName;
 		this.newReferencingName = newReferencingName;
+        this.whenClauseText = whenClauseText;
 		triggerSchemaId = sd.getUUID();
 		triggerTableId = td.getUUID();
 	}	
@@ -403,6 +409,15 @@ public class TriggerDescriptor extends U
 		return whenSPSId;
 	}
 
+    /**
+     * Get the SQL text of the WHEN clause.
+     * @return SQL text for the WHEN clause, or {@code null} if there is
+     *   no WHEN clause
+     */
+    public String getWhenClauseText() {
+        return whenClauseText;
+    }
+
 	/**
 	 * Get the trigger when clause sps 
 	 *
@@ -859,6 +874,16 @@ public class TriggerDescriptor extends U
 	public void readExternal(ObjectInput in)
 		 throws IOException, ClassNotFoundException
 	{
+        readExternal_v10_10(in);
+        whenClauseText = (String) in.readObject();
+    }
+
+    /**
+     * {@code readExternal()} method to be used if the data dictionary
+     * version is 10.10 or lower.
+     */
+    void readExternal_v10_10(ObjectInput in)
+            throws IOException, ClassNotFoundException {
 		id = (UUID)in.readObject();
 		name = (String)in.readObject();
 		triggerSchemaId = (UUID)in.readObject();
@@ -923,6 +948,15 @@ public class TriggerDescriptor extends U
 	public void writeExternal( ObjectOutput out )
 		 throws IOException
 	{
+        writeExternal_v10_10(out);
+        out.writeObject(whenClauseText);
+    }
+
+    /**
+     * {@code writeExternal()} method to be used if the data dictionary
+     * version is 10.10 or lower.
+     */
+    void writeExternal_v10_10(ObjectOutput out) throws IOException {
 		if (SanityManager.DEBUG)
 		{
 			SanityManager.ASSERT(triggerSchemaId != null,
@@ -976,7 +1010,9 @@ public class TriggerDescriptor extends U
 	 *
 	 *	@return	the formatID of this class
 	 */
-	public	int	getTypeFormatId()	{ return StoredFormatIds.TRIGGER_DESCRIPTOR_V01_ID; }
+    public int getTypeFormatId() {
+        return StoredFormatIds.TRIGGER_DESCRIPTOR_V02_ID;
+    }
 
 	/** @see TupleDescriptor#getDescriptorType */
 	public String getDescriptorType()

Added: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TriggerDescriptor_v10_10.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TriggerDescriptor_v10_10.java?rev=1526831&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TriggerDescriptor_v10_10.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TriggerDescriptor_v10_10.java Fri Sep 27 08:41:47 2013
@@ -0,0 +1,94 @@
+/*
+
+   Derby - Class org.apache.derby.iapi.sql.dictionary.TriggerDescriptor_v10_10
+
+   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.iapi.sql.dictionary;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.sql.Timestamp;
+import org.apache.derby.catalog.UUID;
+import org.apache.derby.iapi.services.io.StoredFormatIds;
+
+/**
+ * <p>
+ * Representation of a {@code TriggerDescriptor} in the format used in version
+ * 10.10 and earlier. To be used when reading descriptors written by an older
+ * Derby version, or when writing a descriptor to a database that has been
+ * soft-upgraded from an older Derby version.
+ * </p>
+ *
+ * <p>
+ * The format of trigger descriptors changed in version 10.11 when support for
+ * the WHEN clause was added (DERBY-534).
+ * </p>
+ */
+public class TriggerDescriptor_v10_10 extends TriggerDescriptor {
+
+    /**
+     * Niladic constructor, for formatable.
+     */
+    public TriggerDescriptor_v10_10() {
+    }
+
+    TriggerDescriptor_v10_10(
+            DataDictionary dataDictionary,
+            SchemaDescriptor sd,
+            UUID id,
+            String name,
+            int eventMask,
+            boolean isBefore,
+            boolean isRow,
+            boolean isEnabled,
+            TableDescriptor td,
+            UUID whenSPSId,
+            UUID actionSPSId,
+            Timestamp creationTimestamp,
+            int[] referencedCols,
+            int[] referencedColsInTriggerAction,
+            String triggerDefinition,
+            boolean referencingOld,
+            boolean referencingNew,
+            String oldReferencingName,
+            String newReferencingName) {
+        super(dataDictionary, sd, id, name, eventMask, isBefore, isRow,
+              isEnabled, td, whenSPSId, actionSPSId, creationTimestamp,
+              referencedCols, referencedColsInTriggerAction, triggerDefinition,
+              referencingOld, referencingNew, oldReferencingName,
+              newReferencingName, null);
+    }
+
+    @Override
+    public int getTypeFormatId() {
+        return StoredFormatIds.TRIGGER_DESCRIPTOR_V01_ID;
+    }
+
+    @Override
+    public void readExternal(ObjectInput in)
+            throws IOException, ClassNotFoundException {
+        readExternal_v10_10(in);
+    }
+
+    @Override
+    public void writeExternal(ObjectOutput out) throws IOException {
+        writeExternal_v10_10(out);
+    }
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TriggerDescriptor_v10_10.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java Fri Sep 27 08:41:47 2013
@@ -508,6 +508,16 @@ public	class DD_Version implements	Forma
             bootingDictionary.create_10_10_system_procedures( tc, newlyCreatedRoutines );
         }
 
+        if (fromMajorVersionNumber <= DataDictionary.DD_VERSION_DERBY_10_10)
+        {
+            // On upgrade from versions before 10.11, add a column to the
+            // SYSTRIGGERS table in order to support the WHEN clause.
+            bootingDictionary.upgrade_addColumns(
+              bootingDictionary.getNonCoreTIByNumber(
+                DataDictionary.SYSTRIGGERS_CATALOG_NUM).getCatalogRowFactory(),
+                new int[] { 18 }, tc);
+        }
+
         // Grant PUBLIC access to some system routines
         bootingDictionary.grantPublicAccessToSystemRoutines(newlyCreatedRoutines, tc, aid);
 	}

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java Fri Sep 27 08:41:47 2013
@@ -121,7 +121,6 @@ import org.apache.derby.iapi.sql.diction
 import org.apache.derby.iapi.sql.dictionary.TablePermsDescriptor;
 import org.apache.derby.iapi.sql.dictionary.TriggerDescriptor;
 import org.apache.derby.iapi.sql.dictionary.TupleDescriptor;
-import org.apache.derby.iapi.sql.dictionary.UniqueTupleDescriptor;
 import org.apache.derby.iapi.sql.dictionary.UserDescriptor;
 import org.apache.derby.iapi.sql.dictionary.ViewDescriptor;
 import org.apache.derby.iapi.sql.execute.ExecIndexRow;
@@ -4747,34 +4746,6 @@ public final class	DataDictionaryImpl
 		return list;
 	}
 
-	/**
-	 * Get every trigger in this database.
-	 * Note that this list of TriggerDescriptors is
-	 * not going to be the same objects that are typically
-	 * cached off of the table descriptors, so this will
-	 * most likely instantiate some duplicate objects.
-	 *
-	 * @return the list of descriptors
-	 *
-	 * @exception StandardException		Thrown on failure
-	 */
-    private TriggerDescriptorList getAllTriggerDescriptors()
-		throws StandardException
-	{
-		TabInfoImpl					ti = getNonCoreTI(SYSTRIGGERS_CATALOG_NUM);
-
-        TriggerDescriptorList list = new TriggerDescriptorList();
-
-		getDescriptorViaHeap(
-                        null,
-						(ScanQualifier[][]) null,
-						ti,
-						(TupleDescriptor) null,
-                        list,
-                        TriggerDescriptor.class);
-		return list;
-	}
-
     /**
      * Comparator that can be used for sorting lists of column references
      * on the position they have in the SQL query string.
@@ -5457,11 +5428,6 @@ public final class	DataDictionaryImpl
 	{
         TriggerDescriptorList   gdl;
 
-		if (td == null)
-		{
-			return getAllTriggerDescriptors();
-		}
-
 		/* Build the TableDescriptor's TDL if it is currently empty */
 		gdl = td.getTriggerDescriptorList();
 
@@ -8396,7 +8362,7 @@ public final class	DataDictionaryImpl
 			createConglomerate(
 				ti.getTableName(),
 				tc,
-				ti.getCatalogRowFactory().makeEmptyRow(),
+                ti.getCatalogRowFactory().makeEmptyRowForCurrentVersion(),
 				heapProperties
 				)
 			);
@@ -8464,7 +8430,7 @@ public final class	DataDictionaryImpl
 		SystemColumn		currentColumn;
 
 		SystemColumn[]		columns = rowFactory.buildColumnList();
-		ExecRow				templateRow = rowFactory.makeEmptyRow();
+        ExecRow templateRow = rowFactory.makeEmptyRowForCurrentVersion();
 		int					columnCount = newColumnIDs.length;
 		SchemaDescriptor	sd = getSystemSchemaDescriptor();
 		TableDescriptor		td;
@@ -8508,7 +8474,7 @@ public final class	DataDictionaryImpl
 			columnID = newColumnIDs[ix];
 			currentColumn = columns[ columnID - 1 ];	// from 1 to 0 based
 
-			cdArray[ix] = makeColumnDescriptor( currentColumn, ix + 1, td );
+            cdArray[ix] = makeColumnDescriptor(currentColumn, columnID, td);
 		}
 		addDescriptorArray(cdArray, td, SYSCOLUMNS_CATALOG_NUM, false, tc);
 
@@ -8531,7 +8497,7 @@ public final class	DataDictionaryImpl
     )
 		throws StandardException
 	{
-		ExecRow				templateRow = rowFactory.makeEmptyRow();
+        ExecRow templateRow = rowFactory.makeEmptyRowForCurrentVersion();
 		SchemaDescriptor	sd = getSystemSchemaDescriptor( );
 		long				conglomID = getTableDescriptor( rowFactory.getCatalogName(), sd, tc ).getHeapConglomerateId();
 
@@ -8926,7 +8892,7 @@ public final class	DataDictionaryImpl
 		// create an index row template
 		indexableRow = irg.getIndexRowTemplate();
 
-		baseRow = rf.makeEmptyRow();
+        baseRow = rf.makeEmptyRowForCurrentVersion();
 
 		// Get a RowLocation template
 		cc = tc.openConglomerate(
@@ -9848,7 +9814,7 @@ public final class	DataDictionaryImpl
 
 			  case SYSTRIGGERS_CATALOG_NUM:
 				retval = new TabInfoImpl(new SYSTRIGGERSRowFactory(
-												luuidFactory, exFactory, dvf));
+                                          this, luuidFactory, exFactory, dvf));
 				break;
 
 			  case SYSSTATISTICS_CATALOG_NUM:

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SYSTRIGGERSRowFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SYSTRIGGERSRowFactory.java?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SYSTRIGGERSRowFactory.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SYSTRIGGERSRowFactory.java Fri Sep 27 08:41:47 2013
@@ -21,7 +21,6 @@
 
 package org.apache.derby.impl.sql.catalog;
 
-import org.apache.derby.iapi.types.DataTypeDescriptor;
 import org.apache.derby.iapi.types.DataValueDescriptor;
 import org.apache.derby.iapi.types.SQLBoolean;
 import org.apache.derby.iapi.types.SQLChar;
@@ -81,8 +80,9 @@ public class SYSTRIGGERSRowFactory exten
 	public	static	final	int		SYSTRIGGERS_REFERENCINGNEW = 15;
 	public	static	final	int		SYSTRIGGERS_OLDREFERENCINGNAME = 16;
 	public	static	final	int		SYSTRIGGERS_NEWREFERENCINGNAME = 17;
+    public  static  final   int     SYSTRIGGERS_WHENCLAUSETEXT = 18;
 
-	public	static	final	int		SYSTRIGGERS_COLUMN_COUNT = SYSTRIGGERS_NEWREFERENCINGNAME;
+    public  static  final   int     SYSTRIGGERS_COLUMN_COUNT = SYSTRIGGERS_WHENCLAUSETEXT;
 
 	public  static final int		SYSTRIGGERS_INDEX1_ID = 0;
 	public  static final int		SYSTRIGGERS_INDEX2_ID = 1;
@@ -110,14 +110,22 @@ public class SYSTRIGGERSRowFactory exten
 		,"c013800d-00d7-c025-480d-000a0a411200"	// SYSTRIGGERS_INDEX3
 	};
 
+    private final DataDictionary dataDictionary;
+
 	/////////////////////////////////////////////////////////////////////////////
 	//
 	//	CONSTRUCTORS
 	//
 	/////////////////////////////////////////////////////////////////////////////
-	SYSTRIGGERSRowFactory(UUIDFactory uuidf, ExecutionFactory ef, DataValueFactory dvf)
+    SYSTRIGGERSRowFactory(
+            DataDictionary dd,
+            UUIDFactory uuidf,
+            ExecutionFactory ef,
+            DataValueFactory dvf)
+        throws StandardException
 	{
 		super(uuidf,ef,dvf);
+        this.dataDictionary = dd;
 		initInfo(SYSTRIGGERS_COLUMN_COUNT, TABLENAME_STRING, 
 				 indexColumnPositions,  uniqueness, uuids);
 	}
@@ -134,13 +142,33 @@ public class SYSTRIGGERSRowFactory exten
 	 *
 	 * @exception   StandardException thrown on failure
 	 */
-
+    @Override
 	public ExecRow makeRow(TupleDescriptor td, TupleDescriptor parent)
 		throws StandardException
 	{
-		DataTypeDescriptor		dtd;
-		ExecRow    				row;
-		DataValueDescriptor		col;
+        return makeRow(td, getHeapColumnCount());
+    }
+
+    @Override
+    public ExecRow makeEmptyRowForCurrentVersion() throws StandardException {
+        return makeRow(null, SYSTRIGGERS_COLUMN_COUNT);
+    }
+
+    /**
+     * Helper method that contains common logic for {@code makeRow()} and
+     * {@code makeEmptyRowForCurrentVersion()}. Creates a row for the
+     * SYSTRIGGERS conglomerate.
+     *
+     * @param td the {@code TriggerDescriptor} to create a row from (can be
+     *   {@code null} if the returned row should be empty)
+     * @param columnCount the number of columns in the returned row (used for
+     *   trimming off columns in soft upgrade mode to match the format in
+     *   the old dictionary version)
+     * @return a row for the SYSTRIGGERS conglomerate
+     * @throws StandardException if an error happens when creating the row
+     */
+    private ExecRow makeRow(TupleDescriptor td, int columnCount)
+            throws StandardException {
 		String					name = null;
 		UUID					uuid = null;	
 		UUID					suuid = null;			// schema	
@@ -158,6 +186,7 @@ public class SYSTRIGGERSRowFactory exten
 		ReferencedColumns rcd = null;
 		boolean					referencingOld = false;
 		boolean					referencingNew = false;
+        String                  whenClauseText = null;
 
 		if (td != null)
 		{
@@ -185,10 +214,11 @@ public class SYSTRIGGERSRowFactory exten
 			referencingNew = triggerDescriptor.getReferencingNew();
 			oldReferencingName = triggerDescriptor.getOldReferencingName();
 			newReferencingName = triggerDescriptor.getNewReferencingName();
+            whenClauseText = triggerDescriptor.getWhenClauseText();
 		}
 
 		/* Build the row to insert */
-		row = getExecutionFactory().getValueRow(SYSTRIGGERS_COLUMN_COUNT);
+        ExecRow row = getExecutionFactory().getValueRow(columnCount);
 
 		/* 1st column is TRIGGERID */
 		row.setColumn(1, new SQLChar((uuid == null) ? null : uuid.toString()));
@@ -243,6 +273,13 @@ public class SYSTRIGGERSRowFactory exten
 		/* 17th column is NEWREFERENCINGNAME */
 		row.setColumn(17, new SQLVarchar(newReferencingName));
 
+        /* 18th column is WHENCLAUSETEXT */
+        if (row.nColumns() >= 18) {
+            // This column is present only if the data dictionary version is
+            // 10.11 or higher.
+            row.setColumn(18, dvf.getLongvarcharDataValue(whenClauseText));
+        }
+
 		return row;
 	}
 
@@ -296,7 +333,15 @@ public class SYSTRIGGERSRowFactory exten
 
 		if (SanityManager.DEBUG)
 		{
-			SanityManager.ASSERT(row.nColumns() == SYSTRIGGERS_COLUMN_COUNT, 
+            // The expected number of columns depends on the version of the
+            // data dictionary. The WHENCLAUSETEXT column was added in version
+            // 10.11 (DERBY-534).
+            int expectedCols =
+                dd.checkVersion(DataDictionary.DD_VERSION_DERBY_10_11, null)
+                    ? SYSTRIGGERS_COLUMN_COUNT
+                    : (SYSTRIGGERS_COLUMN_COUNT - 1);
+
+            SanityManager.ASSERT(row.nColumns() == expectedCols,
 								 "Wrong number of columns for a SYSTRIGGERS row");
 		}
 
@@ -372,7 +417,7 @@ public class SYSTRIGGERSRowFactory exten
 		col = row.getColumn(12);
 		rcd = (ReferencedColumns) col.getObject();
 		
-		// 13th column is TRIGGERDEFINITION (longvarhar)
+        // 13th column is TRIGGERDEFINITION (longvarchar)
 		col = row.getColumn(13);
 		triggerDefinition = col.getString();
 
@@ -392,6 +437,15 @@ public class SYSTRIGGERSRowFactory exten
 		col = row.getColumn(17);
 		newReferencingName = col.getString();
 
+        // 18th column is WHENCLAUSETEXT (longvarchar)
+        String whenClauseText = null;
+        if (row.nColumns() >= 18) {
+            // This column is present only if the data dictionary version is
+            // 10.11 or higher.
+            col = row.getColumn(18);
+            whenClauseText = col.getString();
+        }
+
         descriptor = ddg.newTriggerDescriptor(
 									dd.getSchemaDescriptor(suuid, null),
 									uuid, 
@@ -410,7 +464,8 @@ public class SYSTRIGGERSRowFactory exten
 									referencingOld,
 									referencingNew,
 									oldReferencingName,
-									newReferencingName
+                                    newReferencingName,
+                                    whenClauseText
 									);
 
 		return descriptor;
@@ -450,7 +505,8 @@ public class SYSTRIGGERSRowFactory exten
             SystemColumnImpl.getColumn("REFERENCINGNEW", Types.BOOLEAN, true),
             SystemColumnImpl.getIdentifierColumn("OLDREFERENCINGNAME", true),
             SystemColumnImpl.getIdentifierColumn("NEWREFERENCINGNAME", true),
-            
+            SystemColumnImpl.getColumn("WHENCLAUSETEXT",
+                    Types.LONGVARCHAR, true, Integer.MAX_VALUE),
            };
 	}
 
@@ -474,4 +530,16 @@ public class SYSTRIGGERSRowFactory exten
 			return true;
 		}
 	}
+
+    @Override
+    public int getHeapColumnCount() throws StandardException {
+        // The WHEN clause (DERBY-534) is only supported if the dictionary
+        // version is 10.11 or higher. Older versions of the dictionary don't
+        // include the WHENCLAUSETEXT column, so adjust the column count
+        // accordingly.
+        boolean supportsWhenClause = dataDictionary
+                .checkVersion(DataDictionary.DD_VERSION_DERBY_10_11, null);
+        int heapCols = super.getHeapColumnCount();
+        return supportsWhenClause ? heapCols : (heapCols - 1);
+    }
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CreateTriggerNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CreateTriggerNode.java?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CreateTriggerNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/CreateTriggerNode.java Fri Sep 27 08:41:47 2013
@@ -22,6 +22,7 @@
 package	org.apache.derby.impl.sql.compile;
 
 import java.sql.Timestamp;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashSet;
@@ -32,6 +33,7 @@ import org.apache.derby.iapi.reference.S
 import org.apache.derby.iapi.services.context.ContextManager;
 import org.apache.derby.shared.common.sanity.SanityManager;
 import org.apache.derby.iapi.sql.compile.CompilerContext;
+import org.apache.derby.iapi.sql.compile.Visitable;
 import org.apache.derby.iapi.sql.conn.Authorizer;
 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
@@ -63,8 +65,10 @@ class CreateTriggerNode extends DDLState
 	private	String				whenText;
 	private	StatementNode		actionNode;
 	private	String				actionText;
-	private	String				originalActionText; // text w/o trim of spaces
-	private	int					actionOffset;
+    private final String        originalWhenText;
+    private final String        originalActionText;
+    private final int           whenOffset;
+    private final int           actionOffset;
 
 	private SchemaDescriptor	triggerSchemaDescriptor;
 	private SchemaDescriptor	compSchemaDescriptor;
@@ -227,6 +231,7 @@ class CreateTriggerNode extends DDLState
 	 * @param refClause				the referencing clause
 	 * @param whenClause			the WHEN clause tree
 	 * @param whenText				the text of the WHEN clause
+     * @param whenOffset            offset of start of WHEN clause
 	 * @param actionNode			the trigger action tree
 	 * @param actionText			the text of the trigger action
 	 * @param actionOffset			offset of start of action clause
@@ -246,6 +251,7 @@ class CreateTriggerNode extends DDLState
         List<TriggerReferencingStruct> refClause,
         ValueNode       whenClause,
         String          whenText,
+        int             whenOffset,
         StatementNode   actionNode,
         String          actionText,
         int             actionOffset,
@@ -263,10 +269,12 @@ class CreateTriggerNode extends DDLState
         this.isEnabled = isEnabled;
         this.refClause = refClause;
         this.whenClause = whenClause;
-        this.whenText = (whenText == null) ? null : ("VALUES " + whenText);
+        this.originalWhenText = whenText;
+        this.whenText = (whenText == null) ? null : whenText.trim();
+        this.whenOffset = whenOffset;
         this.actionNode = actionNode;
         this.originalActionText = actionText;
-        this.actionText = (actionText == null) ? null : actionText;
+        this.actionText = (actionText == null) ? null : actionText.trim();
         this.actionOffset = actionOffset;
         this.implicitCreateSchema = true;
 	}
@@ -384,12 +392,13 @@ class CreateTriggerNode extends DDLState
 					
 			actionNode.bindStatement();
 
-			/* when clause is always null
 			if (whenClause != null)
 			{
-				whenClause.bind();
+                ContextManager cm = getContextManager();
+                whenClause = whenClause.bindExpression(
+                        new FromList(cm), new SubqueryList(cm),
+                        new ArrayList<AggregateNode>(0));
 			}
-			*/
 		}
 		finally
 		{
@@ -470,7 +479,7 @@ class CreateTriggerNode extends DDLState
 	**
 	** 1) validate the referencing clause (if any)
 	**
-	** 2) convert trigger action text.  e.g. 
+    ** 2) convert trigger action text and WHEN clause text.  e.g.
 	**	DELETE FROM t WHERE c = old.c
 	** turns into
 	**	DELETE FROM t WHERE c = org.apache.derby.iapi.db.Factory::
@@ -515,7 +524,7 @@ class CreateTriggerNode extends DDLState
         if ( isBefore ) { forbidActionsOnGenCols(); }
 
 		String transformedActionText;
-		int start = 0;
+        String transformedWhenText = null;
 		if (triggerCols != null && triggerCols.size() != 0) {
 			//If the trigger is defined on speific columns, then collect
 			//their column positions and ensure that those columns do
@@ -576,6 +585,17 @@ class CreateTriggerNode extends DDLState
 					triggerEventMask,
 					true
 					);			
+
+            // If there is a WHEN clause, we need to transform its text too.
+            if (whenClause != null) {
+                transformedWhenText =
+                    getDataDictionary().getTriggerActionString(
+                            whenClause, oldTableName, newTableName,
+                            originalWhenText, referencedColInts,
+                            referencedColsInTriggerAction, whenOffset,
+                            triggerTableDescriptor, triggerEventMask, true);
+            }
+
 			//Now that we know what columns we need for REFERENCEd columns in
 			//trigger action, we can get rid of -1 entries for the remaining 
 			//columns from trigger table. This information will be saved in
@@ -587,63 +607,12 @@ class CreateTriggerNode extends DDLState
 		else
 		{
 			//This is a table level trigger	        
-			//Total Number of columns in the trigger table
-			int numberOfColsInTriggerTable = triggerTableDescriptor.getNumberOfColumns();
-            StringBuilder newText = new StringBuilder();
-			/*
-			** For a statement trigger, we find all FromBaseTable nodes.  If
-			** the from table is NEW or OLD (or user designated alternates
-			** REFERENCING), we turn them into a trigger table VTI.
-			*/
-			CollectNodesVisitor<FromBaseTable> visitor = new CollectNodesVisitor<FromBaseTable>(FromBaseTable.class);
-			actionNode.accept(visitor);
-			List<FromBaseTable> tabs = visitor.getList();
-			Collections.sort(tabs, OFFSET_COMPARATOR);
-			for (int i = 0; i < tabs.size(); i++)
-			{
-				FromBaseTable fromTable = tabs.get(i);
-				String baseTableName = fromTable.getBaseTableName();
-				if ((baseTableName == null) ||
-					((oldTableName == null || !oldTableName.equals(baseTableName)) &&
-					(newTableName == null || !newTableName.equals(baseTableName))))
-				{
-					continue;
-				}
-				int tokBeginOffset = fromTable.getTableNameField().getBeginOffset();
-				int tokEndOffset = fromTable.getTableNameField().getEndOffset();
-				if (tokBeginOffset == -1)
-				{
-					continue;
-				}
-
-				checkInvalidTriggerReference(baseTableName);
-
-				newText.append(originalActionText.substring(start, tokBeginOffset-actionOffset));
-				newText.append(baseTableName.equals(oldTableName) ?
-								"new org.apache.derby.catalog.TriggerOldTransitionRows() " :
-								"new org.apache.derby.catalog.TriggerNewTransitionRows() ");
-				/*
-				** If the user supplied a correlation, then just
-				** pick it up automatically; otherwise, supply
-				** the default.
-				*/
-                if (fromTable.getCorrelationName() == null)
-				{
-					newText.append(baseTableName).append(" ");
-				}
-				start=tokEndOffset-actionOffset+1;
-				//If we are dealing with statement trigger, then we will read 
-				//all the columns from the trigger table since trigger will be
-				//fired for any of the columns in the trigger table.
-				referencedColInts= new int[numberOfColsInTriggerTable];
-				for (int j=0; j < numberOfColsInTriggerTable; j++)
-					referencedColInts[j]=j+1;
-			}
-			if (start < originalActionText.length())
-			{
-				newText.append(originalActionText.substring(start));
-			}
-			transformedActionText = newText.toString();
+            transformedActionText = transformStatementTriggerText(
+                    actionNode, originalActionText, actionOffset);
+            if (whenClause != null) {
+                transformedWhenText = transformStatementTriggerText(
+                        whenClause, originalWhenText, whenOffset);
+            }
 		}
 
 		if (referencedColsInTriggerAction != null)
@@ -662,6 +631,12 @@ class CreateTriggerNode extends DDLState
 			actionNode = parseStatement(actionText, true);
 		}
 
+        if (whenClause != null && !transformedWhenText.equals(whenText)) {
+            regenNode = true;
+            whenText = transformedWhenText;
+            whenClause = parseSearchCondition(whenText, true);
+        }
+
 		return regenNode;
 	}
 
@@ -693,6 +668,89 @@ class CreateTriggerNode extends DDLState
 			return null;
 	}
 
+    /**
+     * Transform the WHEN clause or the triggered SQL statement of a
+     * statement trigger from its original shape to internal syntax where
+     * references to transition tables are replaced with VTIs that return
+     * the before or after image of the changed rows.
+     *
+     * @param node the syntax tree of the WHEN clause or the triggered
+     *   SQL statement
+     * @param originalText the original text of the WHEN clause or the
+     *   triggered SQL statement
+     * @param offset the offset of the WHEN clause or the triggered SQL
+     *   statement within the CREATE TRIGGER statement
+     * @return internal syntax for accessing before or after image of
+     *   the changed rows
+     * @throws StandardException if an error happens while performing the
+     *   transformation
+     */
+    private String transformStatementTriggerText(
+            Visitable node, String originalText, int offset)
+        throws StandardException
+    {
+        int start = 0;
+        StringBuilder newText = new StringBuilder();
+
+        // For a statement trigger, we find all FromBaseTable nodes. If
+        // the from table is NEW or OLD (or user designated alternates
+        // REFERENCING), we turn them into a trigger table VTI.
+        CollectNodesVisitor<FromBaseTable> visitor =
+                new CollectNodesVisitor<FromBaseTable>(FromBaseTable.class);
+        node.accept(visitor);
+        List<FromBaseTable> tabs = visitor.getList();
+        Collections.sort(tabs, OFFSET_COMPARATOR);
+        for (FromBaseTable fromTable : tabs) {
+            String baseTableName = fromTable.getBaseTableName();
+            if (baseTableName == null
+                    || (!baseTableName.equals(oldTableName)
+                            && !baseTableName.equals(newTableName))) {
+                // baseTableName is not the NEW or OLD table, so no need
+                // to do anything. Skip this table.
+                continue;
+            }
+
+            int tokBeginOffset = fromTable.getTableNameField().getBeginOffset();
+            int tokEndOffset = fromTable.getTableNameField().getEndOffset();
+            if (tokBeginOffset == -1) {
+                // Unknown offset. Skip this table.
+                continue;
+            }
+
+            // Check if this transition table is allowed in this trigger type.
+            checkInvalidTriggerReference(baseTableName);
+
+            // Replace the transition table name with a VTI.
+            newText.append(originalText, start, tokBeginOffset - offset);
+            newText.append(baseTableName.equals(oldTableName)
+                ? "new org.apache.derby.catalog.TriggerOldTransitionRows() "
+                : "new org.apache.derby.catalog.TriggerNewTransitionRows() ");
+
+            // If the user supplied a correlation, then just
+            // pick it up automatically; otherwise, supply
+            // the default.
+            if (fromTable.getCorrelationName() == null) {
+                newText.append(baseTableName).append(' ');
+            }
+
+            start = tokEndOffset - offset + 1;
+
+            // If we are dealing with statement trigger, then we will read
+            // all the columns from the trigger table since trigger will be
+            // fired for any of the columns in the trigger table.
+            int numberOfColsInTriggerTable =
+                    triggerTableDescriptor.getNumberOfColumns();
+            referencedColInts = new int[numberOfColsInTriggerTable];
+            for (int j = 0; j < numberOfColsInTriggerTable; j++) {
+                referencedColInts[j] = j + 1;
+            }
+        }
+
+        newText.append(originalText, start, originalText.length());
+
+        return newText.toString();
+    }
+
     /*
      * Forbid references to generated columns in the actions of BEFORE triggers.
      * This is DERBY-3948, enforcing the following section of the SQL standard:
@@ -872,6 +930,7 @@ class CreateTriggerNode extends DDLState
 											(Timestamp)null,	// creation time
 											referencedColInts,
 											referencedColsInTriggerAction,
+                                            originalWhenText,
 											originalActionText,
 											oldTableInReferencingClause,
 											newTableInReferencingClause,

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ParserImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ParserImpl.java?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ParserImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ParserImpl.java Fri Sep 27 08:41:47 2013
@@ -21,6 +21,7 @@
 
 package org.apache.derby.impl.sql.compile;
 
+import java.io.StringReader;
 import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.reference.SQLState;
 import org.apache.derby.iapi.sql.compile.CompilerContext;
@@ -126,8 +127,27 @@ public class ParserImpl implements Parse
 	public Visitable parseStatement(String statementSQLText, Object[] paramDefaults)
 		throws StandardException
 	{
-
-		java.io.Reader sqlText = new java.io.StringReader(statementSQLText);
+        return parseStatementOrSearchCondition(
+                statementSQLText, paramDefaults, true);
+    }
+
+    /**
+     * Parse a full SQL statement or a fragment that represents a
+     * {@code <search condition>}.
+     *
+     * @param sql the SQL statement or fragment to parse
+     * @param paramDefaults parameter defaults to pass on to the parser
+     *   in the case where {@code sql} is a full SQL statement
+     * @param isStatement {@code true} if {@code sql} is a full SQL statement,
+     *   {@code false} if it is a fragment
+     * @return parse tree for the SQL
+     * @throws StandardException if an error happens during parsing
+     */
+    private Visitable parseStatementOrSearchCondition(
+            String sql, Object[] paramDefaults, boolean isStatement)
+        throws StandardException
+    {
+        StringReader sqlText = new StringReader(sql);
 
 		/* Get a char stream if we don't have one already */
 		if (charStream == null)
@@ -140,12 +160,15 @@ public class ParserImpl implements Parse
 		}
 
 		/* remember the string that we're parsing */
-		SQLtext = statementSQLText;
+        SQLtext = sql;
 
 		/* Parse the statement, and return the QueryTree */
 		try
 		{
-		    return getParser().Statement(statementSQLText, paramDefaults);
+            SQLParser p = getParser();
+            return isStatement
+                    ? p.Statement(sql, paramDefaults)
+                    : p.SearchCondition(sql);
 		}
 		catch (ParseException e)
 		{
@@ -166,6 +189,12 @@ public class ParserImpl implements Parse
 		}
 	}
 
+    @Override
+    public Visitable parseSearchCondition(String sqlFragment)
+            throws StandardException {
+        return parseStatementOrSearchCondition(sqlFragment, null, false);
+    }
+
 	/**
 	 * Returns the current SQL text string that is being parsed.
 	 *

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/QueryTreeNode.java Fri Sep 27 08:41:47 2013
@@ -737,6 +737,44 @@ public abstract class QueryTreeNode impl
 	*/
 	StatementNode parseStatement(String sql, boolean internalSQL) throws StandardException
 	{
+        return (StatementNode)
+                parseStatementOrSearchCondition(sql, internalSQL, true);
+    }
+
+    /**
+     * Parse an SQL fragment that represents a {@code <search condition>}.
+     *
+     * @param sql a fragment of an SQL statement
+     * @param internalSQL {@code true} if the SQL fragment is allowed to
+     *   contain internal syntax, {@code false} otherwise
+     * @return a {@code ValueNode} representing the parse tree of the
+     *   SQL fragment
+     * @throws StandardException if an error happens while parsing
+     */
+    ValueNode parseSearchCondition(String sql, boolean internalSQL)
+        throws StandardException
+    {
+        return (ValueNode)
+                parseStatementOrSearchCondition(sql, internalSQL, false);
+    }
+
+    /**
+     * Parse a full SQL statement or a fragment representing a {@code <search
+     * condition>}. This is a worker method that contains common logic for
+     * {@link #parseStatement} and {@link #parseSearchCondition}.
+     *
+     * @param sql the SQL statement or fragment to parse
+     * @param internalSQL {@code true} if it is allowed to contain internal
+     *   syntax, {@code false} otherwise
+     * @param isStatement {@code true} if {@code sql} is a full SQL statement,
+     *   {@code false} if it is a fragment
+     * @return a parse tree
+     * @throws StandardException if an error happens while parsing
+     */
+    private Visitable parseStatementOrSearchCondition(
+            String sql, boolean internalSQL, boolean isStatement)
+        throws StandardException
+    {
 		/*
 		** Get a new compiler context, so the parsing of the text
 		** doesn't mess up anything in the current context 
@@ -749,7 +787,9 @@ public abstract class QueryTreeNode impl
 		try
 		{
 			Parser p = newCC.getParser();
-			return (StatementNode) p.parseStatement(sql);
+            return isStatement
+                    ? p.parseStatement(sql)
+                    : p.parseSearchCondition(sql);
 		}
 
 		finally

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=1526831&r1=1526830&r2=1526831&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 Fri Sep 27 08:41:47 2013
@@ -2873,6 +2873,26 @@ Statement( String statementSQLText, Obje
 	}
 }
 
+/**
+ * Parse a search condition.
+ *
+ * @param sqlFragment a fragment of an SQL statement, representing a
+ *                    search condition
+ * @return a {@code ValueNode} representing the search condition
+ */
+ValueNode
+SearchCondition(String sqlFragment) throws StandardException :
+{
+    ValueNode valueNode;
+    initStatement(sqlFragment, null);
+}
+{
+    valueNode = valueExpression() <EOF>
+    {
+        return valueNode;
+    }
+}
+
 StatementNode 
 proceduralStatement(Token[] tokenHolder) throws StandardException : 
 {
@@ -11149,10 +11169,19 @@ triggerDefinition() throws StandardExcep
 			throw StandardException.newException(SQLState.LANG_NO_PARAMS_IN_TRIGGER_ACTION);
 		}
 
-        String whenText = (whenClause == null)
-            ? null
-            : StringUtil.slice(statementSQLText, whenOpen.endOffset + 1,
-                               whenClose.beginOffset - 1, true);
+        String actionText = StringUtil.slice(
+                statementSQLText, actionBegin, actionEnd, false);
+
+        String whenText = null;
+        int whenOffset = 0;
+        if (whenClause != null) {
+            // The WHEN clause is only supported if the dictionary version is
+            // 10.11 or higher.
+            checkVersion(DataDictionary.DD_VERSION_DERBY_10_11, "WHEN");
+            whenOffset = whenOpen.endOffset + 1;
+            whenText = StringUtil.slice(statementSQLText,
+                    whenOffset, whenClose.beginOffset - 1, false);
+        }
 
         return new CreateTriggerNode(
 								triggerName, 
@@ -11165,10 +11194,9 @@ triggerDefinition() throws StandardExcep
                                 refClause,   // referencing clause
                                 whenClause,  // when clause node
                                 whenText,    // when clause text
+                                whenOffset,
 								actionNode,
-								StringUtil.slice(statementSQLText,
-									actionBegin,
-									actionEnd, true),
+                                actionText,
                                 actionBegin,
 								getContextManager());
 	}

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateTriggerConstantAction.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateTriggerConstantAction.java?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateTriggerConstantAction.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CreateTriggerConstantAction.java Fri Sep 27 08:41:47 2013
@@ -75,6 +75,7 @@ class CreateTriggerConstantAction extend
 	private String					whenText;
 	private UUID					actionSPSId;
 	private String					actionText;
+    private final String            originalWhenText;
 	private String					originalActionText;
 	private String					oldReferencingName;
 	private String					newReferencingName;
@@ -108,6 +109,7 @@ class CreateTriggerConstantAction extend
 	 * @param referencedColsInTriggerAction	what columns does the trigger 
 	 *						action reference through old/new transition variables
 	 *						(may be null)
+     * @param originalWhenText The original user text of the WHEN clause (may be null)
 	 * @param originalActionText The original user text of the trigger action
 	 * @param referencingOld whether or not OLD appears in REFERENCING clause
 	 * @param referencingNew whether or not NEW appears in REFERENCING clause
@@ -131,6 +133,7 @@ class CreateTriggerConstantAction extend
 		Timestamp			creationTimestamp,
 		int[]				referencedCols,
 		int[]				referencedColsInTriggerAction,
+        String              originalWhenText,
 		String				originalActionText,
 		boolean				referencingOld,
 		boolean				referencingNew,
@@ -155,6 +158,7 @@ class CreateTriggerConstantAction extend
 		this.referencedCols = referencedCols;
 		this.referencedColsInTriggerAction = referencedColsInTriggerAction;
 		this.originalActionText = originalActionText;
+        this.originalWhenText = originalWhenText;
 		this.referencingOld = referencingOld;
 		this.referencingNew = referencingNew;
 		this.oldReferencingName = oldReferencingName;
@@ -319,7 +323,8 @@ class CreateTriggerConstantAction extend
 									referencingOld,
 									referencingNew,
 									oldReferencingName,
-									newReferencingName);
+                                    newReferencingName,
+                                    originalWhenText);
 
 
 		dd.addDescriptor(triggerd, triggerSd,
@@ -332,8 +337,11 @@ class CreateTriggerConstantAction extend
 		*/
 		if (whenText != null)
 		{
+            // The WHEN clause is just a search condition and not a full
+            // SQL statement. Turn in into a VALUES statement.
+            String whenValuesStmt = "VALUES " + whenText;
 			whenspsd = createSPS(lcc, ddg, dd, tc, tmpTriggerId, triggerSd,
-						whenSPSId, spsCompSchemaId, whenText, true, triggerTable);
+                whenSPSId, spsCompSchemaId, whenValuesStmt, true, triggerTable);
 		}
 
 		/*

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=1526831&r1=1526830&r2=1526831&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 Fri Sep 27 08:41:47 2013
@@ -987,6 +987,7 @@ public class GenericConstantActionFactor
 	 * @param referencedColsInTriggerAction	what columns does the trigger 
 	 *						action reference through old/new transition variables
 	 *						(may be null)
+     * @param originalWhenText The original user text of the WHEN clause (may be null)
 	 * @param originalActionText The original user text of the trigger action
 	 * @param referencingOld whether or not OLD appears in REFERENCING clause
 	 * @param referencingNew whether or not NEW appears in REFERENCING clause
@@ -1010,6 +1011,7 @@ public class GenericConstantActionFactor
 		Timestamp			creationTimestamp,
 		int[]				referencedCols,
 		int[]				referencedColsInTriggerAction,
+        String              originalWhenText,
 		String				originalActionText,
 		boolean				referencingOld,
 		boolean				referencingNew,
@@ -1020,7 +1022,8 @@ public class GenericConstantActionFactor
 		return new CreateTriggerConstantAction(triggerSchemaName, triggerName, 
 				eventMask, isBefore, isRow, isEnabled, triggerTable, whenSPSId,
 				whenText, actionSPSId, actionText, spsCompSchemaId, creationTimestamp,
-				referencedCols, referencedColsInTriggerAction, originalActionText,
+                referencedCols, referencedColsInTriggerAction,
+                originalWhenText, originalActionText,
 				referencingOld, referencingNew, oldReferencingName, newReferencingName);
 	}
 

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/dblook_test_net.out
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/dblook_test_net.out?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/dblook_test_net.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/dblook_test_net.out Fri Sep 27 08:41:47 2013
@@ -2111,6 +2111,7 @@ false
 false
 null
 null
+null
 -----
 <systemid>
 REFTRIG
@@ -2129,6 +2130,7 @@ true
 false
 OLDTABLE
 null
+null
 -----
 <systemid>
 TRIG2
@@ -2147,6 +2149,7 @@ false
 false
 null
 null
+null
 -----
 <systemid>
 TRIGFOUR
@@ -2165,6 +2168,7 @@ true
 true
 OLD
 NEW
+null
 -----
 <systemid>
 TRIGONE
@@ -2183,6 +2187,7 @@ false
 false
 null
 null
+null
 -----
 <systemid>
 TrigThree
@@ -2201,6 +2206,7 @@ false
 false
 null
 null
+null
 -----
 ========== SYSVIEWS ==========
 V"3

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/dblook_test_net_territory.out
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/dblook_test_net_territory.out?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/dblook_test_net_territory.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/dblook_test_net_territory.out Fri Sep 27 08:41:47 2013
@@ -2111,6 +2111,7 @@ false
 false
 null
 null
+null
 -----
 <systemid>
 REFTRIG
@@ -2129,6 +2130,7 @@ true
 false
 OLDTABLE
 null
+null
 -----
 <systemid>
 TRIG2
@@ -2147,6 +2149,7 @@ false
 false
 null
 null
+null
 -----
 <systemid>
 TRIGFOUR
@@ -2165,6 +2168,7 @@ true
 true
 OLD
 NEW
+null
 -----
 <systemid>
 TRIGONE
@@ -2183,6 +2187,7 @@ false
 false
 null
 null
+null
 -----
 <systemid>
 TrigThree
@@ -2201,6 +2206,7 @@ false
 false
 null
 null
+null
 -----
 ========== SYSVIEWS ==========
 V"3

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/dblook_test.out
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/dblook_test.out?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/dblook_test.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/dblook_test.out Fri Sep 27 08:41:47 2013
@@ -2104,6 +2104,7 @@ false
 false
 null
 null
+null
 ----
 <systemid>
 REFTRIG
@@ -2122,6 +2123,7 @@ true
 false
 OLDTABLE
 null
+null
 ----
 <systemid>
 TRIG2
@@ -2140,6 +2142,7 @@ false
 false
 null
 null
+null
 ----
 <systemid>
 TRIGFOUR
@@ -2158,6 +2161,7 @@ true
 true
 OLD
 NEW
+null
 ----
 <systemid>
 TRIGONE
@@ -2176,6 +2180,7 @@ false
 false
 null
 null
+null
 ----
 <systemid>
 TrigThree
@@ -2194,6 +2199,7 @@ false
 false
 null
 null
+null
 ----
 ========== SYSVIEWS ==========
 V"3
@@ -4369,6 +4375,7 @@ false
 false
 null
 null
+null
 ----
 <systemid>
 REFTRIG
@@ -4387,6 +4394,7 @@ true
 false
 OLDTABLE
 null
+null
 ----
 <systemid>
 TRIG2
@@ -4405,6 +4413,7 @@ false
 false
 null
 null
+null
 ----
 <systemid>
 TRIGFOUR
@@ -4423,6 +4432,7 @@ true
 true
 OLD
 NEW
+null
 ----
 <systemid>
 TRIGONE
@@ -4441,6 +4451,7 @@ false
 false
 null
 null
+null
 ----
 <systemid>
 TrigThree
@@ -4459,6 +4470,7 @@ false
 false
 null
 null
+null
 ----
 ========== SYSVIEWS ==========
 V"3
@@ -5105,6 +5117,7 @@ true
 false
 OLDTABLE
 null
+null
 ----
 ========== SYSVIEWS ==========
 ========== SYSROLES ==========
@@ -5716,6 +5729,7 @@ false
 false
 null
 null
+null
 ----
 ========== SYSVIEWS ==========
 V2
@@ -5894,6 +5908,7 @@ false
 false
 null
 null
+null
 ----
 ========== SYSVIEWS ==========
 ========== SYSROLES ==========

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/dblook_test_territory.out
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/dblook_test_territory.out?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/dblook_test_territory.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/dblook_test_territory.out Fri Sep 27 08:41:47 2013
@@ -2104,6 +2104,7 @@ false
 false
 null
 null
+null
 ----
 <systemid>
 REFTRIG
@@ -2122,6 +2123,7 @@ true
 false
 OLDTABLE
 null
+null
 ----
 <systemid>
 TRIG2
@@ -2140,6 +2142,7 @@ false
 false
 null
 null
+null
 ----
 <systemid>
 TRIGFOUR
@@ -2158,6 +2161,7 @@ true
 true
 OLD
 NEW
+null
 ----
 <systemid>
 TRIGONE
@@ -2176,6 +2180,7 @@ false
 false
 null
 null
+null
 ----
 <systemid>
 TrigThree
@@ -2194,6 +2199,7 @@ false
 false
 null
 null
+null
 ----
 ========== SYSVIEWS ==========
 V"3
@@ -4369,6 +4375,7 @@ false
 false
 null
 null
+null
 ----
 <systemid>
 REFTRIG
@@ -4387,6 +4394,7 @@ true
 false
 OLDTABLE
 null
+null
 ----
 <systemid>
 TRIG2
@@ -4405,6 +4413,7 @@ false
 false
 null
 null
+null
 ----
 <systemid>
 TRIGFOUR
@@ -4423,6 +4432,7 @@ true
 true
 OLD
 NEW
+null
 ----
 <systemid>
 TRIGONE
@@ -4441,6 +4451,7 @@ false
 false
 null
 null
+null
 ----
 <systemid>
 TrigThree
@@ -4459,6 +4470,7 @@ false
 false
 null
 null
+null
 ----
 ========== SYSVIEWS ==========
 V"3
@@ -5105,6 +5117,7 @@ true
 false
 OLDTABLE
 null
+null
 ----
 ========== SYSVIEWS ==========
 ========== SYSROLES ==========
@@ -5716,6 +5729,7 @@ false
 false
 null
 null
+null
 ----
 ========== SYSVIEWS ==========
 V2
@@ -5894,6 +5908,7 @@ false
 false
 null
 null
+null
 ----
 ========== SYSVIEWS ==========
 ========== SYSROLES ==========

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SystemCatalogTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SystemCatalogTest.java?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SystemCatalogTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SystemCatalogTest.java Fri Sep 27 08:41:47 2013
@@ -322,6 +322,7 @@ public class SystemCatalogTest extends B
 				{"SYSTRIGGERS", "TRIGGERID", "1", "CHAR(36) NOT NULL"},
 				{"SYSTRIGGERS", "TRIGGERNAME", "2", "VARCHAR(128) NOT NULL"},
 				{"SYSTRIGGERS", "TYPE", "7", "CHAR(1) NOT NULL"},
+                {"SYSTRIGGERS", "WHENCLAUSETEXT", "18", "LONG VARCHAR"},
 				{"SYSTRIGGERS", "WHENSTMTID", "10", "CHAR(36)"},
 				{"SYSUSERS", "HASHINGSCHEME", "2", "VARCHAR(32672) NOT NULL"},
 				{"SYSUSERS", "LASTMODIFIED", "4", "TIMESTAMP NOT NULL"},

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/TriggerWhenClauseTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/TriggerWhenClauseTest.java?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/TriggerWhenClauseTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/TriggerWhenClauseTest.java Fri Sep 27 08:41:47 2013
@@ -56,46 +56,75 @@ public class TriggerWhenClauseTest exten
 
         // Create after triggers that should always be executed. Create row
         // trigger, statement trigger and implicit statement trigger.
-        s.execute("create trigger tr1 after insert on t1 for each row "
-                + "when (true) insert into t2 values 'Executed tr1'");
-        s.execute("create trigger tr2 after insert on t1 for each statement "
-                + "when (true) insert into t2 values 'Executed tr2'");
-        s.execute("create trigger tr3 after insert on t1 "
-                + "when (true) insert into t2 values 'Executed tr3'");
+        s.execute("create trigger tr01 after insert on t1 for each row "
+                + "when (true) insert into t2 values 'Executed tr01'");
+        s.execute("create trigger tr02 after insert on t1 for each statement "
+                + "when (true) insert into t2 values 'Executed tr02'");
+        s.execute("create trigger tr03 after insert on t1 "
+                + "when (true) insert into t2 values 'Executed tr03'");
 
         // Create corresponding triggers that should never fire (their WHEN
         // clause is false).
-        s.execute("create trigger tr4 after insert on t1 for each row "
-                + "when (false) insert into t2 values 'Executed tr4'");
-        s.execute("create trigger tr5 after insert on t1 for each statement "
-                + "when (false) insert into t2 values 'Executed tr5'");
-        s.execute("create trigger tr6 after insert on t1 "
-                + "when (false) insert into t2 values 'Executed tr6'");
+        s.execute("create trigger tr04 after insert on t1 for each row "
+                + "when (false) insert into t2 values 'Executed tr04'");
+        s.execute("create trigger tr05 after insert on t1 for each statement "
+                + "when (false) insert into t2 values 'Executed tr05'");
+        s.execute("create trigger tr06 after insert on t1 "
+                + "when (false) insert into t2 values 'Executed tr06'");
 
         // Create triggers with EXISTS subqueries in the WHEN clause. The
         // first returns TRUE and the second returns FALSE.
-        s.execute("create trigger tr7 after insert on t1 "
+        s.execute("create trigger tr07 after insert on t1 "
                 + "when (exists (select * from sysibm.sysdummy1)) "
-                + "insert into t2 values 'Executed tr7'");
-        s.execute("create trigger tr8 after insert on t1 "
+                + "insert into t2 values 'Executed tr07'");
+        s.execute("create trigger tr08 after insert on t1 "
                 + "when (exists "
                 + "(select * from sysibm.sysdummy1 where ibmreqd <> 'Y')) "
-                + "insert into t2 values 'Executed tr8'");
+                + "insert into t2 values 'Executed tr08'");
 
         // WHEN clause returns NULL, trigger should not be fired.
-        s.execute("create trigger tr9 after insert on t1 "
+        s.execute("create trigger tr09 after insert on t1 "
                 + "when (cast(null as boolean))"
-                + "insert into t2 values 'Executed tr9'");
+                + "insert into t2 values 'Executed tr09'");
+
+        // WHEN clause contains reference to a transition variable.
+        s.execute("create trigger tr10 after insert on t1 "
+                + "referencing new as new for each row "
+                + "when (new.x <> 2) insert into t2 values 'Executed tr10'");
+
+        // WHEN clause contains reference to a transition table.
+        s.execute("create trigger tr11 after insert on t1 "
+                + "referencing new table as new "
+                + "when (exists (select * from new where x > 5)) "
+                + "insert into t2 values 'Executed tr11'");
 
         // Now fire the triggers and verify the results.
         assertUpdateCount(s, 3, "insert into t1 values 1, 2, 3");
         JDBC.assertFullResultSet(
             s.executeQuery("select y, count(*) from t2 group by y order by y"),
             new String[][] {
-                { "Executed tr1", "3" },
-                { "Executed tr2", "1" },
-                { "Executed tr3", "1" },
-                { "Executed tr7", "1" },
+                { "Executed tr01", "3" },
+                { "Executed tr02", "1" },
+                { "Executed tr03", "1" },
+                { "Executed tr07", "1" },
+                { "Executed tr10", "2" },
+            });
+
+        // Empty t2 before firing the triggers again.
+        s.execute("delete from t2");
+
+        // Insert more rows with different values and see that a slightly
+        // different set of triggers get fired.
+        assertUpdateCount(s, 2, "insert into t1 values 2, 6");
+        JDBC.assertFullResultSet(
+            s.executeQuery("select y, count(*) from t2 group by y order by y"),
+            new String[][] {
+                { "Executed tr01", "2" },
+                { "Executed tr02", "1" },
+                { "Executed tr03", "1" },
+                { "Executed tr07", "1" },
+                { "Executed tr10", "1" },
+                { "Executed tr11", "1" },
             });
     }
 

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_11.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_11.java?rev=1526831&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_11.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_11.java Fri Sep 27 08:41:47 2013
@@ -0,0 +1,107 @@
+/*
+
+Derby - Class org.apache.derbyTesting.functionTests.tests.upgradeTests.Changes10_11
+
+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.derbyTesting.functionTests.tests.upgradeTests;
+
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.derbyTesting.junit.JDBC;
+
+
+/**
+ * Upgrade test cases for 10.11.
+ */
+public class Changes10_11 extends UpgradeChange
+{
+
+    //////////////////////////////////////////////////////////////////
+    //
+    // CONSTANTS
+    //
+    //////////////////////////////////////////////////////////////////
+
+    private static  final   String  SYNTAX_ERROR = "42X01";
+    private static  final   String  HARD_UPGRADE_REQUIRED = "XCL47";
+
+    //////////////////////////////////////////////////////////////////
+    //
+    // CONSTRUCTOR
+    //
+    //////////////////////////////////////////////////////////////////
+
+    public Changes10_11(String name) {
+        super(name);
+    }
+
+    //////////////////////////////////////////////////////////////////
+    //
+    // JUnit BEHAVIOR
+    //
+    //////////////////////////////////////////////////////////////////
+
+    /**
+     * Return the suite of tests to test the changes made in 10.11.
+     *
+     * @param phase an integer that indicates the current phase in
+     *              the upgrade test.
+     * @return the test suite created.
+     */
+    public static Test suite(int phase) {
+        return new TestSuite(Changes10_11.class, "Upgrade test for 10.11");
+    }
+
+    //////////////////////////////////////////////////////////////////
+    //
+    // TESTS
+    //
+    //////////////////////////////////////////////////////////////////
+
+    public void testTriggerWhenClause() throws SQLException {
+        String createTrigger =
+                "create trigger d534_tr1 after insert on d534_t1 "
+                + "referencing new as new for each row mode db2sql "
+                + "when (new.x <> 2) insert into d534_t2 values new.x";
+
+        Statement s = createStatement();
+        switch (getPhase()) {
+            case PH_CREATE:
+                s.execute("create table d534_t1(x int)");
+                s.execute("create table d534_t2(y int)");
+                assertCompileError(SYNTAX_ERROR, createTrigger);
+                break;
+            case PH_SOFT_UPGRADE:
+                assertCompileError(HARD_UPGRADE_REQUIRED, createTrigger);
+                break;
+            case PH_POST_SOFT_UPGRADE:
+                assertCompileError(SYNTAX_ERROR, createTrigger);
+                break;
+            case PH_HARD_UPGRADE:
+                s.execute(createTrigger);
+                s.execute("insert into d534_t1 values 1, 2, 3");
+                JDBC.assertFullResultSet(
+                        s.executeQuery("select * from d534_t2 order by y"),
+                        new String[][]{{"1"}, {"3"}});
+                break;
+        }
+    }
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_11.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/UpgradeRun.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/UpgradeRun.java?rev=1526831&r1=1526830&r2=1526831&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/UpgradeRun.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/UpgradeRun.java Fri Sep 27 08:41:47 2013
@@ -192,6 +192,8 @@ class UpgradeRun extends UpgradeClassLoa
                 	suite.addTest(Changes10_9.suite(phase));
                 if (oldMinor < 10)
                 	suite.addTest(Changes10_10.suite(phase));
+                if (oldMinor < 11)
+                    suite.addTest(Changes10_11.suite(phase));
             }
             
             // Add DatabaseMetaData tests. Since metadata



Mime
View raw message