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 dj...@apache.org on 2005/06/30 19:37:37 UTC

svn commit: r208650 [1/2] - in /incubator/derby/code/trunk/java: engine/org/apache/derby/ engine/org/apache/derby/iapi/reference/ engine/org/apache/derby/iapi/services/monitor/ engine/org/apache/derby/iapi/services/timer/ engine/org/apache/derby/iapi/s...

Author: djd
Date: Thu Jun 30 10:37:35 2005
New Revision: 208650

URL: http://svn.apache.org/viewcvs?rev=208650&view=rev
Log:
DERBY-31 - Implement Connection.setQueryTimeout for embedded driver.

Patch contributed by Øyvind Bakksjø - Oyvind.Bakksjo@Sun.COM

Added:
    incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/timer/
    incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/timer/TimerFactory.java   (with props)
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java   (with props)
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/SetQueryTimeoutTest.out   (with props)
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/SetQueryTimeoutTest.java   (with props)
Modified:
    incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/SQLState.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/monitor/ModuleFactory.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/monitor/Monitor.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/PreparedStatement.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/StatementContext.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/monitor/BaseMonitor.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericPreparedStatement.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericStatement.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericStatementContext.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BasicNoPutResultSetImpl.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BulkTableScanResultSet.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstraintConstantAction.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericTriggerExecutor.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/TableScanResultSet.java
    incubator/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties
    incubator/derby/code/trunk/java/engine/org/apache/derby/modules.properties
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNetClient.exclude
    incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/SQLState.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/SQLState.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/SQLState.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/SQLState.java Thu Jun 30 10:37:35 2005
@@ -1299,7 +1299,10 @@
 
     // Initial release of DB2 Cloudscape does not support upgrade
 	String LANG_CANT_UPGRADE_DATABASE                                 = "XCL50.S";
-	/*
+
+    String LANG_STATEMENT_CANCELLED_OR_TIMED_OUT                       = "XCL52.S";
+
+    /*
 	** Language errors that match DB2
 	*/
 
@@ -1382,6 +1385,7 @@
     String NULL_SQL_TEXT = "XJ067.S";
     String MIDDLE_OF_BATCH = "XJ068.S";
     String NO_SETXXX_FOR_EXEC_USING = "XJ069.S";
+    String INVALID_QUERYTIMEOUT_VALUE = "XJ074.S";
     String LANG_NUM_PARAMS_INCORRECT = "XJ080.S";
     String INVALID_API_PARAMETER = "XJ081.S";
     String INTERNAL_ERROR = "XJ999.S";

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/monitor/ModuleFactory.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/monitor/ModuleFactory.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/monitor/ModuleFactory.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/monitor/ModuleFactory.java Thu Jun 30 10:37:35 2005
@@ -282,4 +282,12 @@
 	 * methods to create and recreate database unique identifiers.
 	 */
 	public org.apache.derby.iapi.services.uuid.UUIDFactory getUUIDFactory();
+        
+	/**
+	 * Get the Timer factory for the system. The Timer factory provides
+     * access to Timer objects for various purposes.
+     *
+     * @return the system's Timer factory.
+	 */
+    public org.apache.derby.iapi.services.timer.TimerFactory getTimerFactory();
 }

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/monitor/Monitor.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/monitor/Monitor.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/monitor/Monitor.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/monitor/Monitor.java Thu Jun 30 10:37:35 2005
@@ -278,7 +278,7 @@
   <P> If MonitorBoot.start() is called more then once then subsequent calls
   have no effect.
 
-		@param properties The application properties
+		@param bootProperties The application properties
 		@param logging Where to place initial error output. This location will be used
 			until an InfoStreams module is successfully started.
 	*/

Added: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/timer/TimerFactory.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/timer/TimerFactory.java?rev=208650&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/timer/TimerFactory.java (added)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/timer/TimerFactory.java Thu Jun 30 10:37:35 2005
@@ -0,0 +1,38 @@
+/*
+
+   Derby - Class org.apache.derby.iapi.services.timer.TimerFactory
+
+   Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed 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.services.timer;
+
+import java.util.Timer;
+
+/**
+ * This class provides access to Timer objects for various purposes.
+ * The scheme for creation of Timer objects is implementation-defined.
+ */
+public interface TimerFactory
+{
+    /**
+     * Returns a Timer object that can be used for adding TimerTasks
+     * that cancel executing statements.
+     *
+     * @return a Timer object for cancelling statements.
+     */
+    public Timer getCancellationTimer();
+}

Propchange: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/services/timer/TimerFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/PreparedStatement.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/PreparedStatement.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/PreparedStatement.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/PreparedStatement.java Thu Jun 30 10:37:35 2005
@@ -124,6 +124,16 @@
 	ResultSet	execute(LanguageConnectionContext lcc, boolean rollbackParentContext)
 		throws StandardException;
 
+    /**
+     * Sets the timeout for execution of this statement.
+     * The timeout value will be set in the assigned StatementContext object.
+     *
+     * @param timeoutMillis timeout value in milliseconds.
+     *
+     * @see org.apache.derby.iapi.sql.conn.StatementContext
+     */
+    void setQueryTimeout(long timeoutMillis);
+
 	/**
 	 * Get the ResultDescription for the statement.  The ResultDescription
 	 * describes what the results look like: what are the rows and columns?

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java Thu Jun 30 10:37:35 2005
@@ -122,8 +122,6 @@
 	 * executing statement to error log.)
 	 *
 	 * @param logStatementText	Whether or not logStatementText property is set.
-	 *
-	 * @return Nothing.
 	 */
 	public void setLogStatementText(boolean logStatementText);
 
@@ -203,20 +201,20 @@
 	 * Mark the passed temporary table as modified in the current unit of work. That information will be used at rollback time
 	 * The compile phase will generate code to call this method if the DML is on a temporary table
 	 *
-	 * @param String tableName Mark the passed temporary table name as modified
+	 * @param tableName Mark the passed temporary table name as modified
 	 */
 	public void markTempTableAsModifiedInUnitOfWork(String tableName);
   
 	/**
 	 * Add the declared global temporary table to the list of temporary tables known by this connection.
-	 * @param TableDescriptor td Corresponding to the temporary table
+	 * @param td Corresponding to the temporary table
 	 *
 	 */
 	public void addDeclaredGlobalTempTable(TableDescriptor td) throws StandardException;
 
 	/**
 	 * Drop (mark the declared global temporary table for dropping) from the list of temporary tables known by this connection.
-	 * @param String tableName look for this table name in the saved list and drop it if found
+	 * @param tableName look for this table name in the saved list and drop it if found
 	 * @return true if dropped the temporary table. False if no such temporary table exists.
 	 *
 	 * @see org.apache.derby.impl.sql.conn.TempTableInfo
@@ -226,7 +224,7 @@
 	/**
 	 * Get table descriptor for the declared global temporary table from the list of temporary
 	 * tables known by this connection.
-	 * @param String tableName Get table descriptor for the passed table name
+	 * @param tableName Get table descriptor for the passed table name
 	 * @return TableDescriptor if found the temporary table. Else return null
 	 *
 	 */
@@ -247,8 +245,6 @@
 
 		@param	commitStore	true if we should commit the Store transaction
 
-		@return	the commit instant
-
 		@exception StandardException thrown if something goes wrong
 	 */
 	void internalCommit( boolean commitStore )
@@ -260,8 +256,6 @@
 		@param	commitflag	the flags to pass to commitNoSync in the store's
 							TransactionController
 
-		@return	the commit instant
-
 		@exception StandardException	thrown if something goes wrong
 	 */
 	void internalCommitNoSync(int commitflag) throws StandardException;
@@ -270,8 +264,6 @@
 		Do a commit, as issued directly by a user (e.g. via Connection.commit()
 		or the JSQL 'COMMIT' statement.
 
-		@return	the commit instant
-
 		@exception StandardException thrown if something goes wrong
 	 */
 	void userCommit() throws StandardException;
@@ -282,8 +274,6 @@
 		@param onePhase if true, allow it to commit without first going thru a
 		prepared state.
 
-		@return	the commit instant
-
 		@exception StandardException	thrown if something goes wrong
 	 */
 	void xaCommit(boolean onePhase) throws StandardException;
@@ -493,7 +483,7 @@
 	/**
 	 *	Set the current default schema
 	 *
-	 * @param SchemaDescriptor	the new default schema
+	 * @param sd the new default schema
 	 *
 	 * @exception StandardException thrown on failure
 	 */
@@ -517,7 +507,7 @@
 	/**
 	 * Set the field of most recently generated identity column value.
 	 *
-	 * @param the generated identity column value
+	 * @param val the generated identity column value
 	 */
 	public void setIdentityValue(long val);
 
@@ -576,8 +566,6 @@
 	 *
 	 * @param compilerContext  The compiler context.
 	 *
-	 * @return Nothing.
-	 *
 	 * @exception StandardException thrown on failure
 	 */
 	public void popCompilerContext(CompilerContext compilerContext);
@@ -598,21 +586,21 @@
 	 * @param rollbackParentContext True if 1) the statement context is
 	 * 	NOT a top-level context, AND 2) in the event of a statement-level
 	 *	exception, the parent context needs to be rolled back, too.
+     *
+     * @param timeoutMillis Timeout value for this statement, in milliseconds.
+     *  Zero means no timeout.
 	 *
 	 * @return StatementContext	The statement context.
 	 *
 	 */
 	StatementContext pushStatementContext(boolean isAtomic, String stmtText,
-		ParameterValueSet pvs, boolean rollbackParentContext);
+		ParameterValueSet pvs, boolean rollbackParentContext, long timeoutMillis);
 
 	/**
 	 * Pop a StatementContext of the context stack.
 	 *
 	 * @param statementContext  The statement context.
 	 * @param error				The error, if any  (Only relevant for DEBUG)
-	 *
-	 * @return Nothing.
-	 *
 	 */
 	public void popStatementContext(StatementContext statementContext,
 									Throwable error);
@@ -797,8 +785,6 @@
 	 * Set current isolation level.
 	 * 
 	 * @param isolationLevel	The new isolationLevel.
-	 *
-	 * @return Nothing.
 	 */
 	public void setIsolationLevel(int isolationLevel) throws StandardException;
 
@@ -956,7 +942,7 @@
      * Convert an identifier to the proper case for this connection. This method
      * is here to support the Plugin.
      *
-     * @param	an identifier string
+     * @param id an identifier string
      * @return  the string converted to upper or lower case, as appropriate
      *
      * @exception StandardException thrown if something goes wrong
@@ -1074,7 +1060,7 @@
 	/**
 	 * Set the DRDA ID of this LCC.
 	 *
-	 * @param	DRDA ID.
+	 * @param drdaID DRDA ID.
 	 */
 	public void setDrdaID(String drdaID);
 

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/StatementContext.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/StatementContext.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/StatementContext.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/StatementContext.java Thu Jun 30 10:37:35 2005
@@ -44,7 +44,7 @@
 	/**
 	 * Mark this context as being in use.
 	 *
-	 *	@param	parentInTrigger	true if the parent started in the context of a trigger
+	 *	@param inTrigger true if the parent started in the context of a trigger
 	 *	@param	isAtomic true if the statement must be executed
 	 *		atomically
 	 *  @param stmtText the text of the statement.  Needed for any language
@@ -52,8 +52,11 @@
 	 * 	to fire).  Please set this unless you are some funky jdbc setXXX
 	 *	method or something.
 	 *	@param	pvs	parameter value set, if it has one
+     *  @param timeoutMillis timeout value for the statement, in milliseconds.
+     *   Zero means no timeout.
 	 */
-	public void setInUse(boolean inTrigger, boolean isAtomic, String stmtText, ParameterValueSet pvs);
+    public void setInUse(boolean inTrigger, boolean isAtomic, String stmtText,
+                         ParameterValueSet pvs, long timeoutMillis);
 
 	/**
 	 * Mark this context as not in use.  This is important because we
@@ -96,7 +99,6 @@
 	 * @param subqueryTrackingArray	(Sparse) of tops of subquery ResultSet trees
 	 *
 	 * @exception StandardException Thrown on error
-	 * @return Nothing.
 	 */
 	public void setTopResultSet(ResultSet topResultSet,
 								NoPutResultSet[] subqueryTrackingArray)
@@ -111,7 +113,6 @@
 	 * @param subqueryResultSet	The NoPutResultSet at the top of the subquery
 	 * @param numSubqueries		The total # of subqueries in the entire query
 	 *
-	 * @return Nothing.
 	 * @exception StandardException Thrown on error
 	 */
 	public void setSubqueryResultSet(int subqueryNumber,
@@ -137,7 +138,6 @@
 	 *
 	 * @param dy	The dependency to track.
 	 *
-	 * @return Nothing.
 	 * @exception StandardException Thrown on error
 	 */
 	public void addDependency(Dependency dy)
@@ -174,6 +174,22 @@
 	 */
 	public boolean inUse();
 	
+    /**
+     * Checks if the statement which has allocated this statement context
+     * should cancel its execution.
+     *
+     * @return true if the statement execution should be cancelled.
+     **/
+    public boolean isCancelled();
+
+    /**
+     * Indicate that the statement which has allocated this statement
+     * context should cancel its execution.
+     * Usually called as a consequence of Statement.cancel() or a query timeout
+     * set with Statement.setQueryTimeout().
+     */
+    public void cancel();
+
 	/**
 	 * Return the text of the current statement.
 	 * Note that this may be null.  It is currently

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedPreparedStatement.java Thu Jun 30 10:37:35 2005
@@ -585,7 +585,7 @@
      * standard interface.
      *
      * @param parameterIndex the first parameter is 1, the second is 2, ...
-     * @param x the java reader which contains the UNICODE data
+     * @param reader the java reader which contains the UNICODE data
      * @param length the number of characters in the stream
      * @exception SQLException if a database-access error occurs.
      */

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java Thu Jun 30 10:37:35 2005
@@ -142,6 +142,7 @@
 	 */
 	protected final EmbedStatement stmt;
 	private EmbedStatement owningStmt;
+    private long timeoutMillis;
 
 	protected final boolean isAtomic;
 
@@ -171,6 +172,11 @@
 		theResults = resultsToWrap;
 		this.forMetaData = forMetaData;
 		this.stmt = owningStmt = stmt;
+
+        this.timeoutMillis = stmt == null
+            ? 0L
+            : (long)stmt.getQueryTimeout() * 1000L;
+
 		this.isAtomic = isAtomic;
 
 		//If the Statement object has CONCUR_READ_ONLY set on it then the concurrency on the ResultSet object will be CONCUR_READ_ONLY also.
@@ -329,8 +335,10 @@
 				 * on an error.
 				 * (Cache the LanguageConnectionContext)
 				 */
-				StatementContext statementContext = lcc.pushStatementContext(isAtomic, getSQLText(),
-														getParameterValueSet(), false);
+                StatementContext statementContext =
+                    lcc.pushStatementContext(isAtomic, getSQLText(),
+                                             getParameterValueSet(),
+                                             false, timeoutMillis);
 
 				switch (position)
 				{
@@ -3068,10 +3076,10 @@
 	 * 
 	 * @param columnName
 	 *            the name of the column
-	 * @param x
+	 * @param reader
 	 *            the new column value
 	 * @param length
-	 *            of the stream
+	 *            length of the stream
 	 * @exception SQLException
 	 *                if a database-access error occurs
 	 */
@@ -3180,7 +3188,9 @@
             //using quotes around the cursor name to preserve case sensitivity
             updateWhereCurrentOfSQL.append(" WHERE CURRENT OF \"" + getCursorName() + "\"");
             lcc = getEmbedConnection().getLanguageConnection();
-            statementContext = lcc.pushStatementContext(isAtomic, updateWhereCurrentOfSQL.toString(), null, false);
+
+            // Context used for preparing, don't set any timeout (use 0)
+            statementContext = lcc.pushStatementContext(isAtomic, updateWhereCurrentOfSQL.toString(), null, false, 0L);
             org.apache.derby.iapi.sql.PreparedStatement ps = lcc.prepareInternalStatement(updateWhereCurrentOfSQL.toString());
             Activation act = ps.getActivation(lcc, false);
 
@@ -3189,6 +3199,8 @@
                 if (columnGotUpdated[i-1])  //if the column got updated, do following
                     act.getParameterValueSet().getParameterForSet(paramPosition++).setValue(currentRow.getColumn(i));
             }
+            // Don't set any timeout when updating rows (use 0)
+            ps.setQueryTimeout(0L);
             org.apache.derby.iapi.sql.ResultSet rs = ps.execute(act, false, true, true); //execute the update where current of sql
             rs.close();
             rs.finish();
@@ -3229,8 +3241,12 @@
                 deleteWhereCurrentOfSQL.append(" WHERE CURRENT OF \"" + getCursorName() + "\"");
 
                 LanguageConnectionContext lcc = getEmbedConnection().getLanguageConnection();
-                StatementContext statementContext = lcc.pushStatementContext(isAtomic, deleteWhereCurrentOfSQL.toString(), null, false);
+
+                // Context used for preparing, don't set any timeout (use 0)
+                StatementContext statementContext = lcc.pushStatementContext(isAtomic, deleteWhereCurrentOfSQL.toString(), null, false, 0L);
                 org.apache.derby.iapi.sql.PreparedStatement ps = lcc.prepareInternalStatement(deleteWhereCurrentOfSQL.toString());
+                // Don't set any timeout when deleting rows (use 0)
+                ps.setQueryTimeout(0L);
                 org.apache.derby.iapi.sql.ResultSet rs = ps.execute(lcc, true); //execute delete where current of sql
                 rs.close();
                 rs.finish();
@@ -3349,8 +3365,7 @@
 	 * 
 	 * Get a BLOB column.
 	 * 
-	 * @param i
-	 *            the first column is 1, the second is 2, ...
+	 * @param columnIndex the first column is 1, the second is 2, ...
 	 * @return an object representing a BLOB
 	 */
 	public Blob getBlob(int columnIndex) throws SQLException {
@@ -3401,8 +3416,7 @@
 	 * 
 	 * Get a CLOB column.
 	 * 
-	 * @param i
-	 *            the first column is 1, the second is 2, ...
+	 * @param columnIndex the first column is 1, the second is 2, ...
 	 * @return an object representing a CLOB
 	 */
 	public final Clob getClob(int columnIndex) throws SQLException {
@@ -3454,8 +3468,7 @@
 	 * 
 	 * Get a BLOB column.
 	 * 
-	 * @param colName
-	 *            the column name
+	 * @param columnName the column name
 	 * @return an object representing a BLOB
 	 */
 	public final Blob getBlob(String columnName) throws SQLException {
@@ -3467,8 +3480,7 @@
 	 * 
 	 * Get a CLOB column.
 	 * 
-	 * @param colName
-	 *            the column name
+	 * @param columnName the column name
 	 * @return an object representing a CLOB
 	 * @exception SQLException
 	 *                Feature not implemented for now.
@@ -3580,9 +3592,6 @@
 	 * 
 	 * @param columnName
 	 *            the name of the column
-	 * @param operation
-	 *            the operation the caller is trying to do (for error
-	 *            reporting). Null means don't do error checking.
 	 * @return the column index
 	 * @exception SQLException
 	 *                thrown on failure.
@@ -3842,9 +3851,11 @@
 					 */
 					LanguageConnectionContext lcc = getEmbedConnection()
 							.getLanguageConnection();
-					StatementContext statementContext = lcc
-							.pushStatementContext(isAtomic, getSQLText(),
-									getParameterValueSet(), false);
+                    // No timeout for this operation (use 0)
+					StatementContext statementContext =
+                        lcc.pushStatementContext(isAtomic, getSQLText(),
+                                                 getParameterValueSet(),
+                                                 false, 0L);
 
 					boolean result = theResults.checkRowPosition(position);
 

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java Thu Jun 30 10:37:35 2005
@@ -81,6 +81,7 @@
     private int fetchSize = 1;
     private int fetchDirection = JDBC20Translation.FETCH_FORWARD;
     int MaxFieldSize;
+    private int timeoutSeconds;
 
 	//the state of this statement, set to false when close() is called
 	protected boolean active = true;
@@ -109,6 +110,10 @@
 
 		lcc = getEmbedConnection().getLanguageConnection();
 		applicationConnection = getEmbedConnection().getApplicationConnection();
+
+        // By default, no statements time out.
+        // Timeout is set explicitly with setQueryTimeout().
+        timeoutSeconds = 0;
 	}
 
 	//
@@ -364,10 +369,8 @@
      * @return the current query timeout limit in seconds; zero means unlimited
 	 * @exception SQLException thrown on failure.
      */
-	public int getQueryTimeout() throws SQLException {
-        // Currently Cloudscape does not support any sort of timeout, so always
-        // return 0, which means that timeout is unlimited.
-        return(0);
+	public final int getQueryTimeout() throws SQLException {
+        return timeoutSeconds;
 	}
 
     /**
@@ -378,9 +381,13 @@
      * @param seconds the new query timeout limit in seconds; zero means unlimited
 	 * @exception SQLException thrown on failure.
      */
-	public void setQueryTimeout(int seconds) throws SQLException {
-		if (seconds != 0)
-			throw Util.notImplemented("setQueryTimeout");
+	public final void setQueryTimeout(int seconds) throws SQLException {
+		checkStatus();
+        if (seconds < 0) {
+            throw newSQLException(SQLState.INVALID_QUERYTIMEOUT_VALUE,
+                                  new Integer(seconds));
+        }
+        timeoutSeconds = seconds;
 	}
 
     /**
@@ -460,8 +467,6 @@
      * move to any subsequent result(s).
      *
      * @param sql					any SQL statement
-	 * @param executeQuery			caller is executeQuery()
-	 * @param executeUpdate			caller is executeUpdate()
 	 *
      * @return true if the first result is a ResultSet; false if it is an integer
      * @see #getResultSet
@@ -475,6 +480,33 @@
 		return execute(sql, false, false, JDBC30Translation.NO_GENERATED_KEYS, null, null);
 	}
 	
+    /**
+     * Execute a SQL statement that may return multiple results.
+     * Under some (uncommon) situations a single SQL statement may return
+     * multiple result sets and/or update counts.  Normally you can ignore
+     * this, unless you're executing a stored procedure that you know may
+     * return multiple results, or unless you're dynamically executing an
+     * unknown SQL string.  The "execute", "getMoreResults", "getResultSet"
+     * and "getUpdateCount" methods let you navigate through multiple results.
+     *
+     * The "execute" method executes a SQL statement and indicates the
+     * form of the first result.  You can then use getResultSet or
+     * getUpdateCount to retrieve the result, and getMoreResults to
+     * move to any subsequent result(s).
+     *
+     * @param sql					any SQL statement
+	 * @param executeQuery			caller is executeQuery()
+	 * @param executeUpdate			caller is executeUpdate()
+     * @param autoGeneratedKeys
+     * @param columnIndexes
+     * @param columnNames
+	 *
+     * @return true if the first result is a ResultSet; false if it is an integer
+     * @see #getResultSet
+     * @see #getUpdateCount
+     * @see #getMoreResults
+	 * @exception SQLException thrown on failure
+     */
 	protected boolean execute(String sql, boolean executeQuery, boolean executeUpdate,
 		int autoGeneratedKeys, int[] columnIndexes, String[] columnNames) throws SQLException
 	{
@@ -1105,6 +1137,8 @@
 				//and clear existing result sets in case this has been cached
 				a.reset();
 				a.setMaxRows(maxRows);
+                long timeoutMillis = (long)timeoutSeconds * 1000L;
+                ps.setQueryTimeout(timeoutMillis);
 				ResultSet resultsToWrap = ps.execute(a, executeQuery, executeUpdate, false);
 				getWarnings(a.getWarnings());
 

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/monitor/BaseMonitor.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/monitor/BaseMonitor.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/monitor/BaseMonitor.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/monitor/BaseMonitor.java Thu Jun 30 10:37:35 2005
@@ -42,6 +42,7 @@
 import org.apache.derby.iapi.services.sanity.SanityManager;
 import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.services.uuid.UUIDFactory;
+import org.apache.derby.iapi.services.timer.TimerFactory;
 import org.apache.derby.iapi.reference.Property;
 import org.apache.derby.iapi.reference.SQLState;
 import org.apache.derby.iapi.reference.Attribute;
@@ -125,6 +126,7 @@
 	private InfoStreams systemStreams;
 	private ContextService contextService;
 	private UUIDFactory uuidFactory;
+    private TimerFactory timerFactory;
 
 	protected boolean reportOn;
 	private PrintStream logging;
@@ -365,6 +367,7 @@
 
 			uuidFactory = (UUIDFactory) Monitor.startSystemModule("org.apache.derby.iapi.services.uuid.UUIDFactory");
 
+            timerFactory = (TimerFactory)Monitor.startSystemModule("org.apache.derby.iapi.services.timer.TimerFactory");
 		} catch (StandardException se) {
 
 			// if we can't create an error log or a context then there's no point going on
@@ -580,8 +583,7 @@
 	/**
 		Obtain a class that supports the given identifier.
 
-		@param identifier	identifer to associate with class
-		@param length		number of bytes to use from identifier
+		@param fmtId identifer to associate with class
 
 		@return a reference InstanceGetter
 
@@ -1910,6 +1912,15 @@
 
 		return uuidFactory;
 	}
+        
+    /**
+     * Returns the Timer factory for this system.
+     *
+     * @return the system's Timer factory.
+     */
+    public TimerFactory getTimerFactory() {
+        return timerFactory;
+    }
 
 	/*
 	** Methods to deal with storing error messages until an InfoStreams is available.

Added: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java?rev=208650&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java (added)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java Thu Jun 30 10:37:35 2005
@@ -0,0 +1,107 @@
+/*
+
+   Derby - Class org.apache.derby.impl.services.timer.SingletonTimerFactory
+
+   Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+
+   Licensed 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.impl.services.timer;
+
+import org.apache.derby.iapi.services.timer.TimerFactory;
+import org.apache.derby.iapi.services.monitor.ModuleControl;
+
+import org.apache.derby.iapi.error.StandardException;
+
+import java.util.Timer;
+import java.util.Properties;
+
+
+/**
+ * This class implements the TimerFactory interface.
+ * It creates a singleton Timer instance.
+ *
+ * The class implements the ModuleControl interface,
+ * because it needs to cancel the Timer at system shutdown.
+ *
+ * @see TimerFactory
+ * @see ModuleControl
+ */
+public class SingletonTimerFactory
+    implements
+        TimerFactory,
+        ModuleControl
+{
+    /**
+     * Singleton Timer instance.
+     */
+    private Timer singletonTimer;
+
+    /**
+     * Initializes this TimerFactory with a singleton Timer instance.
+     */
+    public SingletonTimerFactory()
+    {
+        /**
+         * Even though we implement the ModuleControl interface,
+         * we initialize the object here rather than in boot, since
+         * a) We avoid synchronizing access to singletonTimer later
+         * b) We don't need any properties
+         */
+        singletonTimer = new Timer(true); // Run as daemon
+    }
+
+    /**
+     * Returns a Timer object that can be used for adding TimerTasks
+     * that cancel executing statements.
+     *
+     * Implements the TimerFactory interface.
+     *
+     * @return a Timer object for cancelling statements.
+     *
+     * @see TimerFactory
+     */
+    public Timer getCancellationTimer()
+    {
+        return singletonTimer;
+    }
+
+    /**
+     * Currently does nothing, singleton Timer instance is initialized
+     * in the constructor.
+     *
+     * Implements the ModuleControl interface.
+     *
+     * @see ModuleControl
+     */
+    public void boot(boolean create, Properties properties)
+        throws
+            StandardException
+    {
+        // Do nothing, instance already initialized in constructor
+    }
+
+    /**
+     * Cancels the singleton Timer instance.
+     * 
+     * Implements the ModuleControl interface.
+     *
+     * @see ModuleControl
+     */
+    public void stop()
+    {
+        singletonTimer.cancel();
+    }
+}

Propchange: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericPreparedStatement.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericPreparedStatement.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericPreparedStatement.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericPreparedStatement.java Thu Jun 30 10:37:35 2005
@@ -152,6 +152,7 @@
 	private String execSchemaName;
 	protected boolean isAtomic;
 	protected String sourceTxt;
+    private long timeoutMillis; // Timeout value, in milliseconds.
 
 	private int inUseCount;
 
@@ -194,6 +195,7 @@
 		UUIDValue = uuidFactory.createUUID();
 		UUIDString = UUIDValue.toString();
 		spsAction = false;
+        timeoutMillis = 0L; // 0 means no timeout; default.
 	}
 
 	/**
@@ -255,6 +257,18 @@
 		return ac;
 	}
 
+    /**
+     * Sets a timeout value for execution of this statement.
+     * Will also apply to each row fetch from the ResultSet
+     * produced by this statement.
+     *
+     * @param timeoutMillis Timeout value in milliseconds. 0 means no timeout.
+     */
+    public void setQueryTimeout(long timeoutMillis)
+    {
+        this.timeoutMillis = timeoutMillis;
+    }
+
 	public ResultSet execute(LanguageConnectionContext lcc, boolean rollbackParentContext)
 		throws StandardException
 	{
@@ -342,7 +356,7 @@
 			rePrepare(lccToUse);
 
 			StatementContext statementContext = lccToUse.pushStatementContext(
-				isAtomic, getSource(), pvs, rollbackParentContext);
+				isAtomic, getSource(), pvs, rollbackParentContext, timeoutMillis);
 
 			if (needsSavepoint())
 			{
@@ -529,8 +543,6 @@
 	 * Set the compile time for this prepared statement.
 	 *
 	 * @param compileTime	The compile time
-	 *
-	 * @return Nothing.
 	 */
 	protected void setCompileTimeMillis(long parseTime, long bindTime,
 										long optimizeTime, 
@@ -594,7 +606,7 @@
 	 *	Set the Execution constants. This routine is called as we Prepare the
 	 *	statement.
 	 *
-	 *	@param	ConstantAction	The big structure enclosing the Execution constants.
+	 *	@param constantAction The big structure enclosing the Execution constants.
 	 */
 	public	final void	setConstantAction( ConstantAction constantAction )
 	{
@@ -886,8 +898,6 @@
 		and associated information.
 
 		@param qt the query tree for this statement
-		@param dtd	The DataTypeDescriptors for the parameters, if any
-		@param ac the generated class for this statement
 
 		@return	true if there is a reference to SESSION schema tables, else false
 

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericStatement.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericStatement.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericStatement.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericStatement.java Thu Jun 30 10:37:35 2005
@@ -236,8 +236,9 @@
 			if (!preparedStmt.isStorable() || lcc.getStatementDepth() == 0)
 			{
 				// since this is for compilation only, set atomic
-				// param to true
-				statementContext = lcc.pushStatementContext(true, getSource(), null, false);
+				// param to true and timeout param to 0
+				statementContext = lcc.pushStatementContext(true, getSource(),
+                                                            null, false, 0L);
 			}
 
 

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java Thu Jun 30 10:37:35 2005
@@ -632,8 +632,8 @@
 	 * them by dropping the conglomerate and recreating the conglomerate. In order to store the new conglomerate
 	 * information for the temp table, we need to replace the existing table descriptor with the new table descriptor
 	 * which has the new conglomerate information
-	 * @param String tableName Temporary table name whose table descriptor is getting changed
-	 * @param TableDescriptor td New table descriptor for the temporary table
+	 * @param tableName Temporary table name whose table descriptor is getting changed
+	 * @param td New table descriptor for the temporary table
 	 */
 	private void replaceDeclaredGlobalTempTable(String tableName, TableDescriptor td) {
     TempTableInfo tempTableInfo = findDeclaredGlobalTempTable(tableName);
@@ -656,7 +656,7 @@
 
 	/**
 	 * Find the declared global temporary table in the list of temporary tables known by this connection.
-	 * @param String tableName look for this table name in the saved list
+	 * @param tableName look for this table name in the saved list
 	 * @return data structure defining the temporary table if found. Else, return null 
 	 *
 	 */
@@ -946,8 +946,6 @@
 		@param onePhase if true, allow it to commit without first going thru a
 		prepared state.
 
-		@return	the commit instant
-
 		@exception StandardException	thrown if something goes wrong
 	 */
 	public final void xaCommit(boolean onePhase) throws StandardException
@@ -1488,7 +1486,7 @@
 
 	/**
 	 * check if there are any activations that reference this temporary table
-	 * @param String tableName look for any activations referencing this table name
+	 * @param tableName look for any activations referencing this table name
 	 * @return boolean  false if found no activations
 	 */
 	private boolean checkIfAnyActivationHasHoldCursor(String tableName)
@@ -1719,7 +1717,7 @@
 	/**
 	 * Set the default schema -- used by SET SCHEMA.
 	 * 
-	 * @param SchemaDescriptor	the new default schema.
+	 * @param sd the new default schema.
 	 * If null, then the default schema descriptor is used.
 	 *
 	 * @exception StandardException thrown on failure
@@ -1748,7 +1746,7 @@
 	/**
 	 * Set the field of most recently generated identity column value.
 	 *
-	 * @param the generated identity column value
+	 * @param val the generated identity column value
 	 */
 	public void setIdentityValue(long val)
 	{
@@ -1839,9 +1837,6 @@
 	 * Pop a CompilerContext off the context stack.
 	 *
 	 * @param cc  The compiler context.
-	 *
-	 * @return Nothing.
-	 *
 	 */
 	public void popCompilerContext(CompilerContext cc)
 	{
@@ -1878,12 +1873,14 @@
 	 * @param rollbackParentContext True if 1) the statement context is
 	 * 	NOT a top-level context, AND 2) in the event of a statement-level
 	 *	exception, the parent context needs to be rolled back, too.
+     * @param timeoutMillis timeout value for this statement, in milliseconds.
+     *  The value 0 means that no timeout is set.
 	 *
 	 * @return StatementContext  The statement context.
 	 *
 	 */
 	public StatementContext pushStatementContext(boolean isAtomic, String stmtText,
-		ParameterValueSet pvs, boolean rollbackParentContext)
+		ParameterValueSet pvs, boolean rollbackParentContext, long timeoutMillis)
 	{
 		int					parentStatementDepth = statementDepth;
 		boolean				inTrigger = false;
@@ -1933,7 +1930,7 @@
 
 		incrementStatementDepth();
 
-		statementContext.setInUse(inTrigger, isAtomic || parentIsAtomic, stmtText, pvs);
+		statementContext.setInUse(inTrigger, isAtomic || parentIsAtomic, stmtText, pvs, timeoutMillis);
 		if (rollbackParentContext)
 			statementContext.setParentRollback();
 		return statementContext;
@@ -1944,9 +1941,6 @@
 	 *
 	 * @param statementContext  The statement context.
 	 * @param error				The error, if any  (Only relevant for DEBUG)
-	 *
-	 * @return Nothing.
-	 *
 	 */
 	public void popStatementContext(StatementContext statementContext,
 									Throwable error) 
@@ -2507,7 +2501,7 @@
      * Convert an identifier to the proper case for this connection. This method
      * is here to support the Plugin.
      *
-     * @param	an identifier string
+     * @param id an identifier string
      * @return  the string converted to upper or lower case, as appropriate
      *
      * @exception StandardException thrown if something goes wrong
@@ -2930,8 +2924,6 @@
 	 * used when as autoincrement column is added to a table by an alter 
 	 * table statemenet and during bulk insert.
 	 *
-	 * @param init		Initial value, used the first time this routine is called.
-	 * @param increment how much to increment by.
 	 * @param schemaName
 	 * @param tableName
 	 * @param columnName identify the column uniquely in the system.

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericStatementContext.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericStatementContext.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericStatementContext.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericStatementContext.java Thu Jun 30 10:37:35 2005
@@ -24,6 +24,10 @@
 
 import org.apache.derby.iapi.services.sanity.SanityManager;
 
+import org.apache.derby.iapi.services.monitor.Monitor;
+
+import org.apache.derby.iapi.services.timer.TimerFactory;
+
 import org.apache.derby.iapi.error.StandardException;
 
 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
@@ -45,6 +49,8 @@
 import org.apache.derby.iapi.reference.SQLState;
 import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.Timer;
+import java.util.TimerTask;
 import java.sql.SQLException;
 
 /**
@@ -67,6 +73,18 @@
 	private NoPutResultSet[] materializedSubqueries;
 	private	final LanguageConnectionContext lcc;
 	private boolean		inUse = true;
+
+    // This flag satisfies all the conditions
+    // for using volatile instead of synchronized.
+    // (Source: Doug Lea, Concurrent Programming in Java, Second Edition,
+    // section 2.2.7.4, page 97)
+    // true if statement has been cancelled
+    private volatile boolean cancellationFlag = false;
+
+    // Reference to the TimerTask that will time out this statement.
+    // Needed for stopping the task when execution completes before timeout.
+    private CancelQueryTask cancelTask = null;
+        
     private	boolean		parentInTrigger;	// whetherparent started with a trigger on stack
     private	boolean		isAtomic;	
 	private boolean		isSystemCode;
@@ -99,6 +117,72 @@
 
 	}
 
+    /**
+     * This is a TimerTask that is responsible for timing out statements,
+     * typically when an application has called Statement.setQueryTimeout().
+     *
+     * When the application invokes execute() on a statement object, or
+     * fetches data on a ResultSet, a StatementContext object is allocated
+     * for the duration of the execution in the engine (until control is
+     * returned to the application).
+     *
+     * When the StatementContext object is assigned with setInUse(),
+     * a CancelQueryTask is scheduled if a timeout > 0 has been set.
+     */
+    private static class CancelQueryTask
+        extends
+            TimerTask
+    {
+        /**
+         * Reference to the StatementContext for the executing statement
+         * which might time out.
+         */
+        private StatementContext statementContext;
+
+        /**
+         * Initializes a new task for timing out a statement's execution.
+         * This does not schedule it for execution, the caller is
+         * responsible for calling Timer.schedule() with this object
+         * as parameter.
+         */
+        public CancelQueryTask(StatementContext ctx)
+        {
+            statementContext = ctx;
+        }
+
+        /**
+         * Invoked by a Timer class to cancel an executing statement.
+         * This method just sets a volatile flag in the associated
+         * StatementContext object by calling StatementContext.cancel();
+         * it is the responsibility of the thread executing the statement
+         * to check this flag regularly.
+         */
+        public void run()
+        {
+            synchronized (this) {
+                if (statementContext != null) {
+                    statementContext.cancel();
+                }
+            }
+        }
+
+        /**
+         * Stops this task and prevents it from cancelling a statement.
+         * Guarantees that after this method returns, the associated
+         * StatementContext object will not be tampered with by this task.
+         * Thus, the StatementContext object may safely be allocated to
+         * other executing statements.
+         */
+        public void forgetContext() {
+            boolean mayStillRun = !cancel();
+            if (mayStillRun) {
+                synchronized (this) {
+                    statementContext = null;
+                }
+            }
+        }
+    }
+
 	// StatementContext Interface
 
 	public void setInUse
@@ -106,7 +190,8 @@
 		boolean parentInTrigger,
 		boolean isAtomic, 
 		String stmtText,
-		ParameterValueSet pvs
+		ParameterValueSet pvs,
+        long timeoutMillis
 	) 
 	{
 		inUse = true;
@@ -116,6 +201,12 @@
 		this.stmtText = stmtText;
 		this.pvs = pvs;
 		rollbackParentContext = false;
+        if (timeoutMillis > 0) {
+            TimerFactory factory = Monitor.getMonitor().getTimerFactory();
+            Timer timer = factory.getCancellationTimer();
+            cancelTask = new CancelQueryTask(this);
+            timer.schedule(cancelTask, timeoutMillis);
+        }
 	}
 
 	public void clearInUse() {
@@ -131,6 +222,12 @@
 		sqlAllowed = -1;
 		isSystemCode = false;
 		rollbackParentContext = false;
+
+        if (cancelTask != null) {
+            cancelTask.forgetContext();
+            cancelTask = null;
+        }
+        cancellationFlag = false;
 	}
 
 	/**
@@ -216,7 +313,6 @@
 	 * an error.
 	 *
 	 * @exception StandardException thrown on error.
-	 * @return Nothing.
 	 */
 	public void setTopResultSet(ResultSet topResultSet, 
 							    NoPutResultSet[] subqueryTrackingArray)
@@ -267,8 +363,6 @@
 	  *
 	  *	@param	topResultSet	make this the top result set
 	  *	@param	subqueryTrackingArray	where to keep track of subqueries in this statement
-	  *
-	  * @return Nothing.
 	  */
 	private	void	stuffTopResultSet(ResultSet topResultSet, 
 									  NoPutResultSet[] subqueryTrackingArray)
@@ -289,7 +383,6 @@
 	 * @param numSubqueries		The total # of subqueries in the entire query
 	 *
 	 * @exception StandardException thrown on error.
-	 * @return Nothing.
 	 */
 	public void setSubqueryResultSet(int subqueryNumber,
 									 NoPutResultSet subqueryResultSet,
@@ -350,7 +443,6 @@
 	 *
 	 * @param dy	The dependency to track.
 	 *
-	 * @return Nothing.
 	 * @exception StandardException thrown on error.
 	 */
 	public void addDependency(Dependency dy)
@@ -551,6 +643,31 @@
 	{
 		return inUse;
 	}
+        
+    /**
+     * Tests whether the statement which has allocated this StatementContext
+     * object has been cancelled. This method is typically called from the
+     * thread which is executing the statement, to test whether execution
+     * should continue or stop.
+     *
+     * @return whether the statement which has allocated this StatementContext
+     *  object has been cancelled.
+     */
+    public boolean isCancelled()
+    {
+        return cancellationFlag;
+    }
+
+    /**
+     * Cancels the statement which has allocated this StatementContext object.
+     * This is done by setting a flag in the StatementContext object. For
+     * this to have any effect, it is the responsibility of the executing
+     * statement to check this flag regularly.
+     */
+    public void cancel()
+    {
+        cancellationFlag = true;
+    }
 
 	public void setSQLAllowed(short allow, boolean force) {
 

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/AlterTableConstantAction.java Thu Jun 30 10:37:35 2005
@@ -1557,8 +1557,6 @@
 	/**
 	 * Get info on the indexes on the table being compress. 
 	 *
-	 * @return	Nothing
-	 *
 	 * @exception StandardException		Thrown on error
 	 */
 	private void getAffectedIndexes(Activation activation)
@@ -2054,6 +2052,12 @@
 	private static void executeUpdate(LanguageConnectionContext lcc, String updateStmt) throws StandardException
 	{
 		PreparedStatement ps = lcc.prepareInternalStatement(updateStmt);
+
+        // This is a substatement; for now, we do not set any timeout
+        // for it. We might change this behaviour later, by linking
+        // timeout to its parent statement's timeout settings.
+        ps.setQueryTimeout(0L);
+
 		ResultSet rs = ps.execute(lcc, true);
 		rs.close();
 		rs.finish();
@@ -2073,6 +2077,10 @@
 
 		LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
 		PreparedStatement ps = lcc.prepareInternalStatement(maxStmt);
+
+        // This is a substatement, for now we do not set any timeout for it
+        // We might change this later by linking timeout to parent statement
+        ps.setQueryTimeout(0L);
 
 		ResultSet rs = ps.execute(lcc, false);
 		DataValueDescriptor[] rowArray = rs.getNextRow().getRowArray();

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BasicNoPutResultSetImpl.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BasicNoPutResultSetImpl.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BasicNoPutResultSetImpl.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BasicNoPutResultSetImpl.java Thu Jun 30 10:37:35 2005
@@ -182,8 +182,6 @@
 	/**
 	 * Mark the ResultSet as the topmost one in the ResultSet tree.
 	 * Useful for closing down the ResultSet on an error.
-	 *
-	 * @return Nothing.
 	 */
 	public void markAsTopResultSet()
 	{
@@ -1056,6 +1054,27 @@
 	{
 		return false;
 	}
+
+    /**
+     * Checks whether the currently executing statement has been cancelled.
+     * This is done by checking the statement's allocated StatementContext
+     * object.
+     *
+     * @see StatementContext
+     */
+	public void checkCancellationFlag()
+        throws
+            StandardException
+	{
+        StatementContext localStatementContext = getLanguageConnectionContext().getStatementContext();            
+        if (localStatementContext == null) {
+            return;
+        }
+
+        if (localStatementContext.isCancelled()) {
+            throw StandardException.newException(SQLState.LANG_STATEMENT_CANCELLED_OR_TIMED_OUT);
+        }
+    }
 
 	protected final void addWarning(SQLWarning w) {
 

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BulkTableScanResultSet.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BulkTableScanResultSet.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BulkTableScanResultSet.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BulkTableScanResultSet.java Thu Jun 30 10:37:35 2005
@@ -158,7 +158,7 @@
     /**
  	 * Open the scan controller
 	 *
-	 * @param transaction controller will open one if null
+	 * @param tc transaction controller will open one if null
      *
 	 * @exception StandardException thrown on failure to open
 	 */
@@ -261,6 +261,8 @@
 	public ExecRow getNextRowCore() throws StandardException
 	{
 	    ExecRow result = null;
+            
+        checkCancellationFlag();
 
 		beginTime = getCurrentTimeMillis();
 		if (isOpen && scanControllerOpened)

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstraintConstantAction.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstraintConstantAction.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstraintConstantAction.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/ConstraintConstantAction.java Thu Jun 30 10:37:35 2005
@@ -91,7 +91,6 @@
 	 *  @param tableName		Table name.
 	 *  @param tableId			UUID of table.
 	 *  @param schemaName		schema that table and constraint lives in.
-	 *  @param tdSd				the schema that table lives in.
 	 *  @param indexAction		IndexConstantAction for constraint (if necessary)
 	 *  RESOLVE - the next parameter should go away once we use UUIDs
 	 *			  (Generated constraint names will be based off of uuids)
@@ -310,6 +309,11 @@
 		try
 		{
 			PreparedStatement ps = lcc.prepareInternalStatement(td.getSchemaDescriptor(), checkStmt.toString());
+
+            // This is a substatement; for now, we do not set any timeout
+            // for it. We might change this behaviour later, by linking
+            // timeout to its parent statement's timeout settings.
+            ps.setQueryTimeout(0L);
 
 			rs = ps.execute(lcc, false);
 			ExecRow row = rs.getNextRow();

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericTriggerExecutor.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericTriggerExecutor.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericTriggerExecutor.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericTriggerExecutor.java Thu Jun 30 10:37:35 2005
@@ -163,6 +163,11 @@
 			*/
 			try
 			{
+                // This is a substatement; for now, we do not set any timeout
+                // for it. We might change this behaviour later, by linking
+                // timeout to its parent statement's timeout settings.
+                ps.setQueryTimeout(0L);
+
 				ResultSet rs = ps.execute(spsActivation, false, false, false);
                 if( rs.returnsRows())
                 {

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/TableScanResultSet.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/TableScanResultSet.java?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/TableScanResultSet.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/TableScanResultSet.java Thu Jun 30 10:37:35 2005
@@ -599,6 +599,8 @@
 	 */
 	public ExecRow getNextRowCore() throws StandardException
 	{
+        checkCancellationFlag();
+            
 		if (currentRow == null)
 		{
 			currentRow =

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties Thu Jun 30 10:37:35 2005
@@ -1019,7 +1019,7 @@
 XCL49.S= TRUNCATE TABLE is not permitted on ''{0}'' because it has an enabled DELETE trigger ({1}).
 XCL50.S=Upgrading the database from a previous version is not supported.  The database being accessed is at version level ''{0}'', this software is at version level ''{1}''.    
 XCL51.S=The requested function can not reference tables in SESSION schema.
-
+XCL52.S=The statement has been cancelled or timed out.
 
 # Transaction states, matches DB2
 25000=Invalid transaction state.
@@ -1085,6 +1085,7 @@
 XJ067.S=SQL text pointer is null.
 XJ068.S=Only executeBatch and clearBatch allowed in the middle of a batch.
 XJ069.S=No SetXXX methods allowed in case of USING execute statement.
+XJ074.S=Invalid parameter value ''{0}'' for Statement.setQueryTimeout(int seconds).
 XJ080.S=USING execute statement passed {0} parameters rather than {1}.
 XJ081.S=Invalid value ''{0}'' passed as parameter ''{1}'' to method ''{2}''
 XJ070.S=Negative or zero position argument ''{0}'' passed in a Blob or Clob method.

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/modules.properties
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/modules.properties?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/modules.properties (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/modules.properties Thu Jun 30 10:37:35 2005
@@ -111,6 +111,9 @@
 derby.module.uuidJ1=org.apache.derby.impl.services.uuid.BasicUUIDFactory
 cloudscape.config.uuidJ1=all
 
+derby.module.timer=org.apache.derby.impl.services.timer.SingletonTimerFactory
+cloudscape.config.timer=all
+
 derby.module.cacheManager=org.apache.derby.impl.services.cache.ClockFactory
 cloudscape.config.cacheManager=all
 

Added: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/SetQueryTimeoutTest.out
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/SetQueryTimeoutTest.out?rev=208650&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/SetQueryTimeoutTest.out (added)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/SetQueryTimeoutTest.out Thu Jun 30 10:37:35 2005
@@ -0,0 +1,20 @@
+Test SetQueryTimeoutTest starting
+Got connections
+Preparing for testing queries with timeout
+Initializing tables with prefix t
+Initializing tables with prefix u
+Initializing tables with prefix v
+Initializing tables with prefix x
+Testing timeout with fetch operations
+Statement 0 timed out
+Statement 1 completed
+Statement 2 completed
+Statement 3 completed
+Testing timeout with an execute operation
+Statement 0 timed out
+Statement 1 completed
+Testing setting a negative timeout value
+Negative timeout value caused exception, as expected
+Execute returned a ResultSet
+Test SetQueryTimeoutTest PASSED
+Closed connections

Propchange: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/SetQueryTimeoutTest.out
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude (original)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude Thu Jun 30 10:37:35 2005
@@ -4,6 +4,7 @@
 # excluding batchUpdate.java for it hits a problem in networkserver ('beetle' 5561)
 # excluding statementJdbc20.java because this tests fetch_reverse throughout the test
 # excluding jdbcapi/testRelative.java because this is a new test contributed by Shreyas Kaushik and needs to be debugged with JCC  in order to get it running with network server
+# excluding jdbcapi/SetQueryTimeoutTest.java because neither the JCC driver nor the ClientDriver support setQueryTimeout() yet.
 # excluding lang/updatableResultSet.java because changes are required in JCC Driver for this test to run correctly
 # excluding jdbcapi/rsgetXXXcolumnNames.java as it fails incorrectly, according to JDBC spec. Forwarding test case to JCC team.
 jdbcapi/resultsetStream.java
@@ -13,4 +14,5 @@
 jdbcapi/statementJdbc20.java
 jdbcapi/testRelative.java
 jdbcapi/rsgetXXXcolumnNames.java
+jdbcapi/SetQueryTimeoutTest.java
 lang/updatableResultSet.java

Modified: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNetClient.exclude
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNetClient.exclude?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNetClient.exclude (original)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNetClient.exclude Thu Jun 30 10:37:35 2005
@@ -4,9 +4,11 @@
 # excluding batchUpdate.java for it hits a problem in networkserver ('beetle' 5561)
 # excluding statementJdbc20.java because this tests fetch_reverse throughout the test
 # excluding jdbcapi/testRelative.java because it is a new test that requires debugging with the IBM Driver
+# excluding jdbcapi/SetQueryTimeoutTest.java because neither the JCC driver nor the ClientDriver support setQueryTimeout() yet.
 jdbcapi/resultsetStream.java
 lang/errorStream.java
 lang/scrollCursors2.java
 jdbcapi/batchUpdate.java
 jdbcapi/statementJdbc20.java
 jdbcapi/testRelative.java
+jdbcapi/SetQueryTimeoutTest.java

Modified: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall?rev=208650&r1=208649&r2=208650&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall (original)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall Thu Jun 30 10:37:35 2005
@@ -13,6 +13,7 @@
 jdbcapi/blobclob4BLOB.java
 jdbcapi/parameterMapping.java
 jdbcapi/setTransactionIsolation.java
+jdbcapi/SetQueryTimeoutTest.java
 jdbcapi/prepStmtNull.java
 jdbcapi/testRelative.java
 jdbcapi/rsgetXXXcolumnNames.java