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 rh...@apache.org on 2006/08/23 15:48:55 UTC

svn commit: r434046 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/sql/depend/ engine/org/apache/derby/iapi/sql/dictionary/ engine/org/apache/derby/iapi/sql/execute/ engine/org/apache/derby/impl/sql/catalog/ engine/org/apache/derby/impl/s...

Author: rhillegas
Date: Wed Aug 23 06:48:54 2006
New Revision: 434046

URL: http://svn.apache.org/viewvc?rev=434046&view=rev
Log:
DERBY-1621: Commit derby1621trunkdiff04.txt, causing recompilation of trigger actions after ddl.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/depend/DependencyManager.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SPSDescriptor.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TabInfo.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TriggerDescriptor.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/RowChanger.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/TabInfoImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/depend/BasicDependencyManager.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RowChangerImpl.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/triggerGeneral.out
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/triggerGeneral.sql

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/depend/DependencyManager.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/depend/DependencyManager.java?rev=434046&r1=434045&r2=434046&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/depend/DependencyManager.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/depend/DependencyManager.java Wed Aug 23 06:48:54 2006
@@ -27,6 +27,7 @@
 
 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
 
+import org.apache.derby.iapi.store.access.TransactionController;
 
 /**
 	Dependency Manager Interface
@@ -491,4 +492,54 @@
 		@exception java.sql.SQLException thrown if something goes wrong
 	 */
 	public String dumpDependencies() throws StandardException, java.sql.SQLException;
+	
+	/**
+	 	Erases all of the dependencies the dependent has, be they
+	 	valid or invalid, of any dependency type.  This action is
+	 	usually performed as the first step in revalidating a
+	 	dependent; it first erases all the old dependencies, then
+	 	revalidates itself generating a list of new dependencies,
+	 	and then marks itself valid if all its new dependencies are
+	 	valid.
+	 	<p>
+	 	There might be a future want to clear all dependencies for
+	 	a particular provider, e.g. when destroying the provider.
+	 	However, at present, they are assumed to stick around and
+	 	it is the responsibility of the dependent to erase them when
+	 	revalidating against the new version of the provider.
+	 	<p>
+	 	clearDependencies will delete dependencies if they are
+	 	stored; the delete is finalized at the next commit.
+
+		@param lcc	Compiler state
+		@param d the dependent
+		@param tc transaction controller
+	
+		@exception StandardException		Thrown on failure
+	*/
+	public void clearDependencies(LanguageConnectionContext lcc, 
+									Dependent d, 
+									TransactionController tc) 
+		throws StandardException;
+
+
+	/**
+ 	 * Copy dependencies from one dependent to another.
+	 *
+	 * @param copy_From the dependent to copy from	
+	 * @param copyTo the dependent to copy to
+	 * @param persistentOnly only copy persistent dependencies
+	 * @param cm			Current ContextManager
+	 * @param tc            Transaction Controller
+	 *
+	 * @exception StandardException		Thrown on error.
+	 */
+	public void copyDependencies(
+									Dependent	copy_From, 
+									Dependent	copyTo,
+									boolean		persistentOnly,
+									ContextManager cm, 
+									TransactionController tc)
+			throws StandardException;
+	
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java?rev=434046&r1=434045&r2=434046&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java Wed Aug 23 06:48:54 2006
@@ -1687,4 +1687,52 @@
 	public String getVTIClass(TableDescriptor td)
 		throws StandardException;
 
+	
+	/**
+	 * Adds a descriptor to a system catalog identified by the catalogNumber. 
+	 *
+	 * @param tuple			   descriptor to insert.
+	 * @param parent           parent descriptor; e.g for a column parent is the
+	 * tabledescriptor to which the descriptor is beign inserted. for most other
+	 * objects it is the schema descriptor.
+	 * @param catalogNumber	   a value which identifies the catalog into which
+	 * the descriptor should be inserted. It is the users responsibility to
+	 * ensure that the catalogNumber is consistent with the tuple being
+	 * inserted. 
+	 * @see DataDictionary#SYSCONGLOMERATES_CATALOG_NUM
+	 * @param allowsDuplicates whether an exception should be thrown if the
+	 * insert results in a duplicate; if this parameter is FALSE then one
+	 * of the following exception will be thrown; LANG_OBJECT_ALREADY_EXISTS (if
+	 * parent is null) or LANG_OBJECT_ALREADY_EXISTS_IN_OBJECT (if parent is not
+	 * null). The error message is created by getting the name and type of the
+	 * tuple and parent.
+	 * @see org.apache.derby.impl.sql.catalog.DataDictionaryImpl#duplicateDescriptorException
+	 * @param 	tc	the transaction controller to use to do all of this.
+	 * @param wait  If true, then the caller wants to wait for locks. False will
+	 *	            be when we using a nested user xaction - we want to timeout 
+	 *              right away if the parent holds the lock. 
+	 * @see #addDescriptorArray
+	 */
+	public void addDescriptor(TupleDescriptor tuple, TupleDescriptor parent,
+							  int catalogNumber, boolean allowsDuplicates,
+							  TransactionController tc, boolean wait) 
+		throws StandardException;
+	
+	/** 
+	 * Remove all of the stored dependencies for a given dependent's ID 
+	 * from the data dictionary.
+	 * 
+	 * @param dependentsUUID	Dependent's uuid
+	 * @param tc				TransactionController for the transaction
+	 * @param wait  If true, then the caller wants to wait for locks. False will
+	 *	            be when we using a nested user xaction - we want to timeout 
+	 *              right away if the parent holds the lock. 
+	 *
+	 * @exception StandardException		Thrown on failure
+	 */
+	public void dropDependentsStoredDependencies(UUID dependentsUUID,
+									   TransactionController tc,
+									   boolean wait) 
+				throws StandardException;	
+
 }	

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SPSDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SPSDescriptor.java?rev=434046&r1=434045&r2=434046&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SPSDescriptor.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/SPSDescriptor.java Wed Aug 23 06:48:54 2006
@@ -260,13 +260,15 @@
 	 * @param lcc the language connection context
 	 * @param triggerTable the table descriptor to bind against.  Had
 	 * 	better be null if this isn't a trigger sps.
+	 * @param tc the transaction controller
 	 *
 	 * @exception StandardException on error
 	 */
 	public final synchronized void prepareAndRelease
 	(
 		LanguageConnectionContext	lcc, 
-		TableDescriptor				triggerTable
+		TableDescriptor				triggerTable,
+		TransactionController       tc
 	) throws StandardException
 	{
 		if (SanityManager.DEBUG)
@@ -277,10 +279,36 @@
 			}
 		}
 		
-		compileStatement(lcc, triggerTable);
+		compileStatement(lcc, triggerTable, tc);
 	
 		preparedStatement.makeInvalid(DependencyManager.PREPARED_STATEMENT_RELEASE, lcc);
 	}
+	
+	/**
+	 * FOR TRIGGERS ONLY
+	 * <p>
+	 * Generate the class for this SPS and immediately
+	 * release it.  This is useful for cases where we
+	 * don't want to immediately execute the statement 
+	 * corresponding to this sps (e.g. CREATE STATEMENT).
+ 	 * <p>
+	 * <I>SIDE EFFECTS</I>: will update and SYSDEPENDS 
+	 * with the prepared statement dependency info.
+ 	 * 
+	 * @param lcc the language connection context
+	 * @param triggerTable the table descriptor to bind against.  Had
+	 * 	better be null if this isn't a trigger sps.
+	 *
+	 * @exception StandardException on error
+	 */
+	public final synchronized void prepareAndRelease
+	(
+		LanguageConnectionContext	lcc, 
+		TableDescriptor				triggerTable
+	) throws StandardException
+	{
+		prepareAndRelease(lcc, triggerTable, (TransactionController)null);
+	}
 
 	/**
 	 * Generate the class for this SPS and immediately
@@ -297,13 +325,14 @@
 	 */
 	public final synchronized void prepareAndRelease(LanguageConnectionContext lcc) throws StandardException
 	{
-		prepareAndRelease(lcc, (TableDescriptor)null);
+		prepareAndRelease(lcc, (TableDescriptor)null, (TransactionController)null);
 	}
 
 	private void compileStatement
 	(
 		LanguageConnectionContext	lcc,
-		TableDescriptor				triggerTable
+		TableDescriptor				triggerTable,
+		TransactionController       tc
 	)
 		throws StandardException
 	{
@@ -388,7 +417,7 @@
 			** before we recreate them so we don't grow
 			** SYS.SYSDEPENDS forever.
 			*/
-			dm.clearDependencies(lcc, this);
+			dm.clearDependencies(lcc, this, tc);
 
 			/*
 			** Copy over all the dependencies to me
@@ -396,7 +425,8 @@
 			dm.copyDependencies(preparedStatement, 	// from
 											this, 	// to
 											false,	// persistent only
-											cm);
+											cm,
+											tc);
 		}
 
 		// mark it as valid
@@ -673,7 +703,7 @@
 			*/
 			LanguageConnectionContext lcc = (LanguageConnectionContext)
 					cm.getContext(LanguageConnectionContext.CONTEXT_ID);
-			prepareAndRelease(lcc);
+			
 
 
 			if (!((org.apache.derby.impl.sql.catalog.DataDictionaryImpl) (lcc.getDataDictionary())).readOnlyUpgrade) {
@@ -697,6 +727,7 @@
 
 				try
 				{
+					prepareAndRelease(lcc, null, nestedTC);
 					updateSYSSTATEMENTS(lcc, RECOMPILE, nestedTC);
 				}
 				catch (StandardException se)
@@ -711,6 +742,7 @@
 						}
 						// if we couldn't do this with a nested xaction, retry with
 						// parent-- we need to wait this time!
+						prepareAndRelease(lcc, null, null);
 						updateSYSSTATEMENTS(lcc, RECOMPILE, null);
 					}
 					else throw se;

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TabInfo.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TabInfo.java?rev=434046&r1=434045&r2=434046&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TabInfo.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/TabInfo.java Wed Aug 23 06:48:54 2006
@@ -444,4 +444,64 @@
 	 * @return The Properties associated with creating the specified index.
 	 */
 	public Properties getCreateIndexProperties(int indexNumber);
+	
+	/**
+	  *	Given a key row, delete all matching heap rows and their index
+	  *	rows.
+	  * <p>
+	  * LOCKING: row locking if there is a key; otherwise, 
+	  * table locking.
+	  *
+	  *	@param	tc			transaction controller
+	  *	@param	key			key to delete by.
+	  *	@param	indexNumber	Key is appropriate for this index.
+	  * @param  wait        If true, then the caller wants to wait for locks. 
+	  *						False will be when we using a nested user xaction 
+	  *						- we want to timeout right away if the parent holds 
+	  *                     the lock.
+	  * @return the number of rows deleted. If key is not unique,
+	  *         this may be more than one.
+	  * @exception StandardException		Thrown on failure
+	  */
+	public int deleteRow( TransactionController tc,
+						  ExecIndexRow key,
+						  int indexNumber,
+						  boolean wait)
+		throws StandardException;
+	
+	/**
+	  *	Delete the set of rows defined by a scan on an index
+	  * from the table. Most of the parameters are simply passed
+	  * to TransactionController.openScan. Please refer to the
+	  * TransactionController documentation for details.
+	  * <p>
+	  * LOCKING: row locking if there is a start and a stop
+	  * key; otherwise, table locking
+	  *
+	  *	@param	tc			transaction controller
+	  *	@param	startKey	key to start the scan.
+	  * @param  startOp     operation to start the scan.
+	  *	@param	stopKey	    key to start the scan.
+	  * @param  qualifier   a qualifier for the scan.
+	  * @param  filter		filter on base rows
+	  * @param  stopOp      operation to start the scan.
+	  *	@param	indexNumber	Key is appropriate for this index.
+	  * @param  wait        If true, then the caller wants to wait for locks. 
+	  *						False will be when we using a nested user xaction 
+	  *						- we want to timeout right away if the parent holds 
+	  *                     the lock.
+	  * @return the number of rows deleted.
+	  * @exception StandardException		Thrown on failure
+	  * @see TransactionController#openScan
+	  */
+	public int deleteRows(TransactionController tc,
+						  ExecIndexRow startKey,
+						  int startOp,
+						  Qualifier[][] qualifier,
+						  TupleFilter filter,
+						  ExecIndexRow stopKey,
+						  int stopOp,
+						  int indexNumber,
+						  boolean wait)
+		 throws StandardException;
 }

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=434046&r1=434045&r2=434046&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 Wed Aug 23 06:48:54 2006
@@ -689,17 +689,29 @@
 		// the trigger table, so there is a very large number of actions
 		// that we would have to check against. This is hard to maintain,
 		// so don't bother.
-		// When REVOKE_PRIVILEGE gets sent (this happens for privilege 
-		// types SELECT, UPDATE, DELETE, INSERT, REFERENCES, TRIGGER), we  
-		// make the TriggerDescriptor drop itself. 
-		if (action ==  DependencyManager.REVOKE_PRIVILEGE)
+
+		switch (action)
 		{
-		    DropTriggerConstantAction.dropTriggerDescriptor(
-				lcc,getDataDictionary().getDependencyManager(), 
-				getDataDictionary(), lcc.getTransactionExecute(), this,
-				null);
-		    return;
+			// invalidate this trigger descriptor
+			case DependencyManager.USER_RECOMPILE_REQUEST:
+				DependencyManager dm = getDataDictionary().getDependencyManager();
+				dm.invalidateFor(this, DependencyManager.PREPARED_STATEMENT_RELEASE, lcc);
+				break;
+
+			// When REVOKE_PRIVILEGE gets sent (this happens for privilege 
+			// types SELECT, UPDATE, DELETE, INSERT, REFERENCES, TRIGGER), we  
+			// make the TriggerDescriptor drop itself. 
+			case DependencyManager.REVOKE_PRIVILEGE:
+				DropTriggerConstantAction.dropTriggerDescriptor(
+					lcc, getDataDictionary().getDependencyManager(),
+					getDataDictionary(), lcc.getTransactionExecute(), this,
+					null);
+				break;
+
+			default:
+				break;
 		}
+		
 	}
 
 	/**

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/RowChanger.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/RowChanger.java?rev=434046&r1=434045&r2=434046&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/RowChanger.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/RowChanger.java Wed Aug 23 06:48:54 2006
@@ -146,4 +146,19 @@
 	 */
 	public ConglomerateController getHeapConglomerateController();
 
+	/**
+	  Open this RowChanger.
+
+	  <P>Note to avoid the cost of fixing indexes that do not
+	  change during update operations use openForUpdate(). 
+	  @param lockMode	The lock mode to use
+							(row or table, see TransactionController)
+	  @param wait		If true, then the caller wants to wait for locks. False will be
+							when we using a nested user xaction - we want to timeout right away
+							if the parent holds the lock.  
+
+	  @exception StandardException thrown on failure to convert
+	  */
+	public void open(int lockMode, boolean wait)
+		 throws StandardException;
 }

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=434046&r1=434045&r2=434046&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 Wed Aug 23 06:48:54 2006
@@ -1636,10 +1636,13 @@
 							  TransactionController tc)
 		throws StandardException
 	{
-		addDescriptorNow(td, parent, catalogNumber, duplicatesAllowed, tc, true);
+		addDescriptor(td, parent, catalogNumber, duplicatesAllowed, tc, true);
 	}
 
-	private void addDescriptorNow(TupleDescriptor td, TupleDescriptor parent,
+	/**
+	 * @inheritDoc
+	 */
+	public void addDescriptor(TupleDescriptor td, TupleDescriptor parent,
 							  int catalogNumber, boolean duplicatesAllowed,
 							  TransactionController tc, boolean wait)
 		throws StandardException
@@ -3242,7 +3245,7 @@
                     uuid,
                     (UUID) null, 0, 0);
 										
-			addDescriptorNow(cd, null, SYSCOLUMNS_CATALOG_NUM, 
+			addDescriptor(cd, null, SYSCOLUMNS_CATALOG_NUM, 
 						  false, // no chance of duplicates here
 						  tc, wait);
 		}
@@ -5873,6 +5876,17 @@
 									   TransactionController tc) 
 				throws StandardException	
 	{
+		 dropDependentsStoredDependencies(dependentsUUID, tc, true);
+	}
+				
+	/** 
+	 * @inheritDoc
+	 */
+	public void dropDependentsStoredDependencies(UUID dependentsUUID,
+									   TransactionController tc,
+									   boolean wait) 
+				throws StandardException	
+	{
 		ExecIndexRow			keyRow1 = null;
 		DataValueDescriptor		dependentIDOrderable;
 		TabInfoImpl					ti = getNonCoreTI(SYSDEPENDS_CATALOG_NUM);
@@ -5886,7 +5900,8 @@
 		keyRow1 = (ExecIndexRow) exFactory.getIndexableRow(1);
 		keyRow1.setColumn(1, dependentIDOrderable);
 
-		ti.deleteRow( tc, keyRow1, SYSDEPENDSRowFactory.SYSDEPENDS_INDEX1_ID );
+		ti.deleteRow( tc, keyRow1, SYSDEPENDSRowFactory.SYSDEPENDS_INDEX1_ID, 
+				wait );
 
 	}
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/TabInfoImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/TabInfoImpl.java?rev=434046&r1=434045&r2=434046&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/TabInfoImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/TabInfoImpl.java Wed Aug 23 06:48:54 2006
@@ -616,9 +616,26 @@
 						   null,
 						   key,
 						   ScanController.GT,
-						   indexNumber);
+						   indexNumber,
+						   true);
 	}
 
+	public int deleteRow( TransactionController tc, ExecIndexRow key,
+							int indexNumber, boolean wait)
+		throws StandardException
+	{
+		//  Always row locking
+		return  deleteRows(tc,
+						   key,
+						   ScanController.GE,
+						   null,
+						   null,
+						   key,
+						   ScanController.GT,
+						   indexNumber,
+						   wait);
+	}
+	
 	/**
 	 * LOCKING: row locking if there is both a start and
 	 * stop key; otherwise table locking
@@ -627,13 +644,37 @@
 	 * @see TabInfo#deleteRows
 	 */
 	public int deleteRows(TransactionController tc,
+							ExecIndexRow startKey,
+							int startOp,
+							Qualifier[][] qualifier,
+							TupleFilter filter,
+							ExecIndexRow stopKey,
+							int stopOp,
+							int indexNumber) throws StandardException
+    {
+		return  deleteRows(tc,
+				   startKey,
+				   startOp,
+				   qualifier,
+				   filter,
+				   stopKey,
+				   stopOp,
+				   indexNumber,
+				   true);
+    }
+
+	/**
+	 * @inheritDoc
+	 */
+	public int deleteRows(TransactionController tc,
 						  ExecIndexRow startKey,
 						  int startOp,
 						  Qualifier[][] qualifier,
 						  TupleFilter filter,
 						  ExecIndexRow stopKey,
 						  int stopOp,
-						  int indexNumber)
+						  int indexNumber,
+						  boolean wait)
 		 throws StandardException
 	{
 		ConglomerateController		heapCC;
@@ -644,7 +685,7 @@
 		ExecRow						baseRow = crf.makeEmptyRow();
 		int                         rowsDeleted = 0;
 		boolean						passedFilter = true;
-
+		
 		rc = getRowChanger( tc, (int[])null,baseRow );
 
 		/*
@@ -666,7 +707,7 @@
 				TransactionController.ISOLATION_SERIALIZABLE;
 
 		// Row level locking
-		rc.open(lockMode);
+		rc.open(lockMode, wait);
 
 		DataValueDescriptor[] startKeyRow = 
             startKey == null ? null : startKey.getRowArray();
@@ -678,14 +719,16 @@
 		heapCC = tc.openConglomerate(
                     getHeapConglomerate(),
                     false,
-                    TransactionController.OPENMODE_FORUPDATE,
+                    (TransactionController.OPENMODE_FORUPDATE |
+                            ((wait) ? 0 : TransactionController.OPENMODE_LOCK_NOWAIT)),
                     lockMode,
                     TransactionController.ISOLATION_REPEATABLE_READ);
 
 		drivingScan = tc.openScan(
 			getIndexConglomerate(indexNumber),  // conglomerate to open
 			false, // don't hold open across commit
-            TransactionController.OPENMODE_FORUPDATE, // for update
+			(TransactionController.OPENMODE_FORUPDATE | 
+				((wait) ? 0 : TransactionController.OPENMODE_LOCK_NOWAIT)),
             lockMode,
 			isolation,
 			(FormatableBitSet) null, // all fields as objects
@@ -729,6 +772,7 @@
 		heapCC.close();
 		drivingScan.close();
 		rc.close();
+		
 		return rowsDeleted;
 	}
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/depend/BasicDependencyManager.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/depend/BasicDependencyManager.java?rev=434046&r1=434045&r2=434046&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/depend/BasicDependencyManager.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/depend/BasicDependencyManager.java Wed Aug 23 06:48:54 2006
@@ -94,7 +94,13 @@
 
 		@exception StandardException thrown if something goes wrong
 	 */
-	public void addDependency(Dependent d, Provider p, ContextManager cm) throws StandardException {
+	public void addDependency(Dependent d, Provider p, ContextManager cm) 
+		throws StandardException {
+		addDependency(d, p, cm, null);
+	}
+	
+	private void addDependency(Dependent d, Provider p, ContextManager cm, 
+			TransactionController tc) throws StandardException {
 
 		synchronized(this)
 		{
@@ -145,13 +151,14 @@
 				LanguageConnectionContext	lcc = getLanguageConnectionContext(cm);
 				DataDictionary				dd = getDataDictionary();
 				DependencyDescriptor		dependencyDescriptor;
+				boolean wait = (tc == null);
 			
 				dependencyDescriptor = new DependencyDescriptor(d, p);
 
 				/* We can finally call the DataDictionary to store the dependency */
 				dd.addDescriptor(dependencyDescriptor, null,
 								 DataDictionary.SYSDEPENDS_CATALOG_NUM, true,
-								 lcc.getTransactionExecute());
+								 ((wait)?lcc.getTransactionExecute():tc), wait);
 			}
 		}
 	}
@@ -422,6 +429,14 @@
 	 * @exception StandardException		Thrown on failure
 	 */
 	public void clearDependencies(LanguageConnectionContext lcc, Dependent d) throws StandardException {
+		clearDependencies(lcc, d, null);
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	public void clearDependencies(LanguageConnectionContext lcc, 
+									Dependent d, TransactionController tc) throws StandardException {
 		List deps = (List) dependents.get(d.getObjectID());
 
 		synchronized(this)
@@ -430,9 +445,11 @@
 			if (d.isPersistent())
 			{
 				DataDictionary			  dd = getDataDictionary();
-
+				boolean wait = (tc == null);
+				
 				dd.dropDependentsStoredDependencies(d.getObjectID(),
-													lcc.getTransactionExecute());
+								((wait)?lcc.getTransactionExecute():tc),
+								wait);
 			}
 
 			/* Now remove the in-memory dependencies */
@@ -697,11 +714,23 @@
 	 *
 	 * @exception StandardException		Thrown on error.
 	 */
+	public void copyDependencies(Dependent	copy_From, 
+								Dependent	copyTo,
+								boolean		persistentOnly,
+								ContextManager cm) throws StandardException
+	{
+		copyDependencies(copy_From, copyTo, persistentOnly, cm, null);
+	}
+	
+	/**
+	 * @inheritDoc 
+	 */
 	public synchronized void copyDependencies(
 									Dependent	copy_From, 
 									Dependent	copyTo,
 									boolean		persistentOnly,
-									ContextManager cm)
+									ContextManager cm,
+									TransactionController tc)
 		throws StandardException
 	{
 
@@ -715,7 +744,7 @@
 				
 			if (!persistentOnly || provider.isPersistent())
 			{
-				this.addDependency(copyTo, provider, cm);
+				this.addDependency(copyTo, provider, cm, tc);
 			}
 		}
 	}

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RowChangerImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RowChangerImpl.java?rev=434046&r1=434045&r2=434046&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RowChangerImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/RowChangerImpl.java Wed Aug 23 06:48:54 2006
@@ -247,6 +247,15 @@
 	public void open(int lockMode)
 		 throws StandardException
 	{
+		open(lockMode, true);
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	public void open(int lockMode, boolean wait)
+		 throws StandardException
+	{
 		//
 		//We open for update but say to fix every index on
 		//updates.
@@ -256,9 +265,9 @@
 			for (int ix = 0; ix < irgs.length; ix++)
 				fixOnUpdate[ix] = true;
 		}
-		openForUpdate(fixOnUpdate, lockMode, true);
+		openForUpdate(fixOnUpdate, lockMode, wait);
 	}
-	
+
 	/**
 	  Open this RowChanger to avoid fixing indexes that do not change
 	  during update operations. 

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/triggerGeneral.out
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/triggerGeneral.out?rev=434046&r1=434045&r2=434046&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/triggerGeneral.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/triggerGeneral.out Wed Aug 23 06:48:54 2006
@@ -1136,4 +1136,131 @@
 3 rows inserted/updated/deleted
 ij> UPDATE TEST SET INFO = 1 WHERE TESTID = 2;
 ERROR 54038: Maximum depth of nested triggers was exceeded.
+ij> drop table test;
+0 rows inserted/updated/deleted
+ij> -- DERBY-1621
+-- creating and dropping index on the table in the trigger action
+create table t1 (i int);
+0 rows inserted/updated/deleted
+ij> create table t2 (i int);
+0 rows inserted/updated/deleted
+ij> create trigger tt after insert on t1 for each statement mode db2sql insert into t2 values 1;
+0 rows inserted/updated/deleted
+ij> insert into t1 values 1;
+1 row inserted/updated/deleted
+ij> create unique index tu on t2(i);
+0 rows inserted/updated/deleted
+ij> insert into t1 values 1;
+ERROR 23505: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'TU' defined on 'T2'.
+ij> select * from t2;
+I          
+-----------
+1          
+ij> insert into t1 values 1;
+ERROR 23505: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'TU' defined on 'T2'.
+ij> select * from t2;
+I          
+-----------
+1          
+ij> drop index tu;
+0 rows inserted/updated/deleted
+ij> select * from t2;
+I          
+-----------
+1          
+ij> insert into t1 values 1;
+1 row inserted/updated/deleted
+ij> select * from t2;
+I          
+-----------
+1          
+1          
+ij> drop trigger tt;
+0 rows inserted/updated/deleted
+ij> -- dropping and recreating a table which the trigger references
+create table t3 (i int);
+0 rows inserted/updated/deleted
+ij> create table t4 (i int);
+0 rows inserted/updated/deleted
+ij> create trigger tt2 after insert on t3 for each statement mode db2sql insert into t4 values 1;
+0 rows inserted/updated/deleted
+ij> insert into t3 values 1;
+1 row inserted/updated/deleted
+ij> select * from t4;
+I          
+-----------
+1          
+ij> drop table t4;
+0 rows inserted/updated/deleted
+ij> insert into t3 values 1;
+ERROR 42X05: Table/View 'T4' does not exist.
+ij> create table t4 (i int);
+0 rows inserted/updated/deleted
+ij> insert into t3 values 1;
+1 row inserted/updated/deleted
+ij> select * from t4;
+I          
+-----------
+1          
+ij> -- dropping a function which the trigger references
+create function max_value(x int, y int) returns int language java parameter style java external name 'java.lang.Math.max';
+0 rows inserted/updated/deleted
+ij> create table test(a integer);
+0 rows inserted/updated/deleted
+ij> create trigger test_trigger AFTER insert on test FOR EACH ROW MODE DB2SQL values max_value(2,4);
+0 rows inserted/updated/deleted
+ij> insert into test values(1);
+1 row inserted/updated/deleted
+ij> --- drop function and again do inserts. these should not work as the trigger would be invalid
+drop function max_value;
+0 rows inserted/updated/deleted
+ij> insert into test values(2);
+ERROR 42Y03: 'MAX_VALUE' is not recognized as a function or procedure.
+ij> insert into test values(1);
+ERROR 42Y03: 'MAX_VALUE' is not recognized as a function or procedure.
+ij> -- dropping a view which the trigger references
+create table t11TriggerTest (c111 int not null primary key, c112 int);
+0 rows inserted/updated/deleted
+ij> insert into t11TriggerTest values(1,1);
+1 row inserted/updated/deleted
+ij> insert into t11TriggerTest values(2,2);
+1 row inserted/updated/deleted
+ij> -- create a view based on table t11TriggerTest
+create view v21ViewTest as select * from t11TriggerTest;
+0 rows inserted/updated/deleted
+ij> -- get ready to create a trigger. Trigger is created on t31TriggerTest and it inserts into t32TriggerTest
+create table t31TriggerTest (c311 int);
+0 rows inserted/updated/deleted
+ij> create table t32TriggerTest (c321 int);
+0 rows inserted/updated/deleted
+ij> create trigger tr31t31TriggerTest after insert on t31TriggerTest for each statement mode db2sql
+   insert into t32TriggerTest values (select c111 from v21ViewTest where c112=1);
+0 rows inserted/updated/deleted
+ij> -- try an insert which will fire the trigger
+insert into t31TriggerTest values(1);
+1 row inserted/updated/deleted
+ij> select * from t31TriggerTest;
+C311       
+-----------
+1          
+ij> -- we know the trigger got fired if there is one row in t32TriggerTest
+select * from t32TriggerTest;
+C321       
+-----------
+1          
+ij> -- drop the view used by the trigger.
+drop view v21ViewTest;
+0 rows inserted/updated/deleted
+ij> -- try an insert which would cause insert trigger to fire. The insert trigger should have failed because view doesn't
+-- exist anymore.
+insert into t31TriggerTest values(1);
+ERROR 42X05: Table/View 'V21VIEWTEST' does not exist.
+ij> select * from t31TriggerTest;
+C311       
+-----------
+1          
+ij> select * from t32TriggerTest;
+C321       
+-----------
+1          
 ij> 

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/triggerGeneral.sql
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/triggerGeneral.sql?rev=434046&r1=434045&r2=434046&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/triggerGeneral.sql (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/triggerGeneral.sql Wed Aug 23 06:48:54 2006
@@ -624,7 +624,7 @@
 SELECT * FROM T10641;
 SELECT * FROM T10642;
 SELECT * FROM T10641_DELETIONS;
-SELECT * FROM T10642_DELETIONS;
+SELECT * FROM T10642_DELETIONS; 
 
 -- DERBY-1652
 create table test (testid integer not null 
@@ -637,3 +637,75 @@
     update test set ts=current_timestamp where testid=old.testid;
 insert into test(info) values (1),(2),(3);
 UPDATE TEST SET INFO = 1 WHERE TESTID = 2;
+drop table test;
+
+-- DERBY-1621
+-- creating and dropping index on the table in the trigger action
+create table t1 (i int);
+create table t2 (i int);
+create trigger tt after insert on t1 for each statement mode db2sql insert into t2 values 1;
+insert into t1 values 1;
+create unique index tu on t2(i);
+insert into t1 values 1;
+select * from t2;
+insert into t1 values 1;
+select * from t2;
+drop index tu;
+select * from t2;
+insert into t1 values 1;
+select * from t2;
+drop trigger tt;
+
+-- dropping and recreating a table which the trigger references
+create table t3 (i int);
+create table t4 (i int);
+create trigger tt2 after insert on t3 for each statement mode db2sql insert into t4 values 1;
+insert into t3 values 1;
+select * from t4;
+drop table t4;
+insert into t3 values 1;
+create table t4 (i int);
+insert into t3 values 1;
+select * from t4;
+
+-- dropping a function which the trigger references
+create function max_value(x int, y int) returns int language java parameter style java external name 'java.lang.Math.max';
+create table test(a integer);
+create trigger test_trigger AFTER insert on test FOR EACH ROW MODE DB2SQL values max_value(2,4);
+
+insert into test values(1);
+
+--- drop function and again do inserts. these should not work as the trigger would be invalid
+drop function max_value;
+insert into test values(2);
+insert into test values(1);
+
+
+-- dropping a view which the trigger references
+create table t11TriggerTest (c111 int not null primary key, c112 int);
+insert into t11TriggerTest values(1,1);
+insert into t11TriggerTest values(2,2);
+
+-- create a view based on table t11TriggerTest
+create view v21ViewTest as select * from t11TriggerTest;
+
+-- get ready to create a trigger. Trigger is created on t31TriggerTest and it inserts into t32TriggerTest
+create table t31TriggerTest (c311 int);
+create table t32TriggerTest (c321 int);
+create trigger tr31t31TriggerTest after insert on t31TriggerTest for each statement mode db2sql
+   insert into t32TriggerTest values (select c111 from v21ViewTest where c112=1);
+
+-- try an insert which will fire the trigger
+insert into t31TriggerTest values(1);
+select * from t31TriggerTest;
+-- we know the trigger got fired if there is one row in t32TriggerTest
+select * from t32TriggerTest;
+
+-- drop the view used by the trigger.
+drop view v21ViewTest;
+
+-- try an insert which would cause insert trigger to fire. The insert trigger should have failed because view doesn't
+-- exist anymore.
+insert into t31TriggerTest values(1);
+select * from t31TriggerTest;
+select * from t32TriggerTest;