db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From be...@apache.org
Subject svn commit: r408612 - in /db/derby/code/branches/10.1/java: client/org/apache/derby/client/am/ drda/org/apache/derby/impl/drda/ testing/org/apache/derbyTesting/functionTests/master/ testing/org/apache/derbyTesting/functionTests/suites/ testing/org/apac...
Date Mon, 22 May 2006 09:01:23 GMT
Author: bernt
Date: Mon May 22 02:01:22 2006
New Revision: 408612

URL: http://svn.apache.org/viewvc?rev=408612&view=rev
Log:
DERBY-1103 Ported to 10.1 by Deepa Remesh

Added:
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/derbyStress.out
  (with props)
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress.java
  (with props)
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress_app.properties
  (with props)
Modified:
    db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/Connection.java
    db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/Lob.java
    db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/PreparedStatement.java
    db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/ResultSet.java
    db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/Statement.java
    db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java
    db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/DRDAStatement.java
    db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/Database.java
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/lang/procedure.java
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/util/ProcedureTest.java

Modified: db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/Connection.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/Connection.java?rev=408612&r1=408611&r2=408612&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/Connection.java (original)
+++ db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/Connection.java Mon
May 22 02:01:22 2006
@@ -30,20 +30,23 @@
     public Agent agent_;
 
     public DatabaseMetaData databaseMetaData_;
-    // Since DERBY prepared statements must be re-prepared after a commit,
-    // then we must traverse this list after a commit and notify statements
-    // that they are now in an un-prepared state.
-    final java.util.LinkedList openStatements_ = new java.util.LinkedList();
+    // DERBY-210 -  WeakHashMap is used to store references to objects to avoid
+    // memory leaks. When there are no other references to the keys in a 
+    // WeakHashMap, they will get removed from the map and can thus get 
+    // garbage-collected. They do not have to wait till the Connection object 
+    // is collected.
+        
+    // In Connection.markStatementsClosed() method, this list is traversed to get a
+    // list of open statements, which are marked closed and removed from the list.
+    final java.util.WeakHashMap openStatements_ = new java.util.WeakHashMap();
 
-    // Some statuses of DERBY objects may be invalid on server either after only rollback
-    // or after both commit and rollback. For example,
+    // Some statuses of DERBY objects may be invalid on server
+    // after both commit and rollback. For example,
     // (1) prepared statements need to be re-prepared
     //     after both commit and rollback
     // (2) result set will be unpositioned on server after both commit and rollback.
-    // If they only depend on rollback, they need to get on RollbackOnlyListeners_.
     // If they depend on both commit and rollback, they need to get on CommitAndRollbackListeners_.
-    final java.util.LinkedList RollbackOnlyListeners_ = new java.util.LinkedList();
-    final java.util.LinkedList CommitAndRollbackListeners_ = new java.util.LinkedList();
+    final java.util.WeakHashMap CommitAndRollbackListeners_ = new java.util.WeakHashMap();
     private SqlWarning warnings_ = null;
 
     // ------------------------properties set for life of connection--------------
@@ -400,7 +403,7 @@
         PreparedStatement ps = newPreparedStatement_(sql, java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY, holdability(), java.sql.Statement.NO_GENERATED_KEYS,
null);
         ps.isCatalogQuery_ = true;
         ps.prepare();
-        openStatements_.add(ps);
+        openStatements_.put(ps, null);
         return ps;
     }
 
@@ -741,7 +744,6 @@
         inUnitOfWork_ = false;
         markStatementsClosed();
         CommitAndRollbackListeners_.clear();
-        RollbackOnlyListeners_.clear();
         markClosed_();
     }
 
@@ -752,7 +754,8 @@
     }
 
     private void markStatementsClosed() {
-        for (java.util.ListIterator i = openStatements_.listIterator(); i.hasNext();) {
+    	java.util.Set keySet = openStatements_.keySet();
+        for (java.util.Iterator i = keySet.iterator(); i.hasNext();) {
             Statement stmt = (Statement) i.next();
             stmt.markClosed();
             i.remove();
@@ -760,13 +763,15 @@
     }
 
     private void writeCloseStatements() throws SqlException {
-        for (java.util.ListIterator i = openStatements_.listIterator(); i.hasNext();) {
+    	java.util.Set keySet = openStatements_.keySet();
+        for (java.util.Iterator i = keySet.iterator(); i.hasNext();) {
             ((Statement) i.next()).writeClose(false);  // false means don't permit auto-commits
         }
     }
 
     private void readCloseStatements() throws SqlException {
-        for (java.util.ListIterator i = openStatements_.listIterator(); i.hasNext();) {
+    	java.util.Set keySet = openStatements_.keySet();
+        for (java.util.Iterator i = keySet.iterator(); i.hasNext();) {
             ((Statement) i.next()).readClose(false);  // false means don't permit auto-commits
         }
     }
@@ -1253,7 +1258,7 @@
         }
         Statement s = newStatement_(resultSetType, resultSetConcurrency, resultSetHoldability);
         s.cursorAttributesToSendOnPrepare_ = s.cacheCursorAttributesToSendOnPrepare();
-        openStatements_.add(s);
+        openStatements_.put(s, null);
         return s;
     }
 
@@ -1299,7 +1304,7 @@
         PreparedStatement ps = newPreparedStatement_(sql, resultSetType, resultSetConcurrency,
resultSetHoldability, autoGeneratedKeys, columnNames);
         ps.cursorAttributesToSendOnPrepare_ = ps.cacheCursorAttributesToSendOnPrepare();
         ps.prepare();
-        openStatements_.add(ps);
+        openStatements_.put(ps,null);
         return ps;
     }
 
@@ -1337,7 +1342,7 @@
         CallableStatement cs = newCallableStatement_(sql, resultSetType, resultSetConcurrency,
resultSetHoldability);
         cs.cursorAttributesToSendOnPrepare_ = cs.cacheCursorAttributesToSendOnPrepare();
         cs.prepare();
-        openStatements_.add(cs);
+        openStatements_.put(cs,null);
         return cs;
     }
 
@@ -1477,7 +1482,8 @@
     public abstract void readLocalCommit_() throws SqlException;
 
     public void completeLocalCommit() {
-        for (java.util.Iterator i = CommitAndRollbackListeners_.iterator(); i.hasNext();)
{
+    	java.util.Set keySet = CommitAndRollbackListeners_.keySet();
+        for (java.util.Iterator i = keySet.iterator(); i.hasNext();) {
             UnitOfWorkListener listener = (UnitOfWorkListener) i.next();
             listener.completeLocalCommit(i);
         }
@@ -1492,11 +1498,8 @@
     // This is a client-side only operation.
     // This method will only throw an exception on bug check.
     public void completeLocalRollback() {
-        for (java.util.Iterator i = CommitAndRollbackListeners_.iterator(); i.hasNext();)
{
-            UnitOfWorkListener listener = (UnitOfWorkListener) i.next();
-            listener.completeLocalRollback(i);
-        }
-        for (java.util.Iterator i = RollbackOnlyListeners_.iterator(); i.hasNext();) {
+    	java.util.Set keySet = CommitAndRollbackListeners_.keySet();
+    	for (java.util.Iterator i = keySet.iterator(); i.hasNext();) {
             UnitOfWorkListener listener = (UnitOfWorkListener) i.next();
             listener.completeLocalRollback(i);
         }
@@ -1598,7 +1601,8 @@
         // Notice that these physical statements may not belong to this logical connection.
         // Iterate through the physical statements and re-enable them for reuse.
 
-        for (java.util.Iterator i = openStatements_.iterator(); i.hasNext();) {
+        java.util.Set keySet = openStatements_.keySet();
+        for (java.util.Iterator i = keySet.iterator(); i.hasNext();) {
             Object o = i.next();
             ((Statement) o).reset(recomputeFromDataSource);
 

Modified: db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/Lob.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/Lob.java?rev=408612&r1=408611&r2=408612&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/Lob.java (original)
+++ db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/Lob.java Mon May 22
02:01:22 2006
@@ -64,7 +64,7 @@
     //-----------------------event callback methods-------------------------------
 
     public void listenToUnitOfWork() {
-        agent_.connection_.CommitAndRollbackListeners_.add(this);
+        agent_.connection_.CommitAndRollbackListeners_.put(this,null);
     }
 
     public void completeLocalCommit(java.util.Iterator listenerIterator) {

Modified: db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/PreparedStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/PreparedStatement.java?rev=408612&r1=408611&r2=408612&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/PreparedStatement.java
(original)
+++ db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/PreparedStatement.java
Mon May 22 02:01:22 2006
@@ -218,18 +218,6 @@
         }
     }
 
-    protected void finalize() throws java.lang.Throwable {
-        if (agent_.loggingEnabled()) {
-            agent_.logWriter_.traceEntry(this, "finalize");
-        }
-        if (openOnClient_) {
-            synchronized (connection_) {
-                closeX();
-            }
-        }
-        super.finalize();
-    }
-
     // called immediately after the constructor by Connection prepare*() methods
     void prepare() throws SqlException {
         try {
@@ -1607,7 +1595,7 @@
     public void listenToUnitOfWork() {
         if (!listenToUnitOfWork_) {
             listenToUnitOfWork_ = true;
-            connection_.CommitAndRollbackListeners_.add(this);
+            connection_.CommitAndRollbackListeners_.put(this,null);
         }
     }
 
@@ -1711,22 +1699,13 @@
         }
     }
 
-    public void close() throws SqlException {
-        synchronized (connection_) {
-            if (agent_.loggingEnabled()) {
-                agent_.logWriter_.traceEntry(this, "close");
-            }
-            closeX();
-        }
-    }
-
-    // An untraced version of close()
-    public void closeX() throws SqlException {
-        if (!openOnClient_) {
-            return;
-        }
-        super.closeX();
-        if (parameterMetaData_ != null) {
+    /* (non-Javadoc)
+     * @see org.apache.derby.client.am.Statement#markClosed(boolean)
+     */
+    protected void markClosed(boolean removeListener){
+    	super.markClosed(removeListener);
+    	
+    	if (parameterMetaData_ != null) {
             parameterMetaData_.markClosed();
             parameterMetaData_ = null;
         }
@@ -1741,7 +1720,8 @@
         }
         parameters_ = null;
 
-        connection_.CommitAndRollbackListeners_.remove(this);
+        if(removeListener)
+        	connection_.CommitAndRollbackListeners_.remove(this);
     }
 
 }

Modified: db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/ResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/ResultSet.java?rev=408612&r1=408611&r2=408612&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/ResultSet.java (original)
+++ db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/ResultSet.java Mon
May 22 02:01:22 2006
@@ -2973,7 +2973,7 @@
     public void listenToUnitOfWork() {
         if (!listenToUnitOfWork_) {
             listenToUnitOfWork_ = true;
-            connection_.CommitAndRollbackListeners_.add(this);
+            connection_.CommitAndRollbackListeners_.put(this, null);
         }
     }
 

Modified: db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/Statement.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/Statement.java?rev=408612&r1=408611&r2=408612&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/Statement.java (original)
+++ db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/Statement.java Mon
May 22 02:01:22 2006
@@ -349,14 +349,19 @@
         generatedKeysColumnNames_ = columnNames;
     }
 
+    /* (non-Javadoc)
+     * @see java.lang.Object#finalize()
+     * 
+     * This method cleans up client-side resources by calling markClosed().
+     * It is different from close() method, which also does clean up on server.
+     * Changes done as part of DERBY-210. 
+     */
     protected void finalize() throws java.lang.Throwable {
         if (agent_.loggingEnabled()) {
             agent_.logWriter_.traceEntry(this, "finalize");
         }
         if (openOnClient_) {
-            synchronized (connection_) {
-                closeX();
-            }
+            markClosed();
         }
         super.finalize();
     }
@@ -444,7 +449,25 @@
         }
     }
 
-    // An untraced version of close()
+    /**
+     * An untraced version of <code>close</code>. This method cleans up 
+     * client-side resources and also sends commands to network server to 
+     * perform clean up. This should not be called in the finalizer. 
+     * Difference between <code>finalize</code> and <code>close</code>
is
+     * that close method does these things additionally (Changes done as 
+     * part of DERBY-210):
+     * 1) Sends commands to the server to close the result sets.
+     * 2) Sends commands to the server to close the result sets of the 
+     * generated keys query.
+     * 3) Sends a commit if autocommit is on and it is appropriate.
+     * 4) Explicitly removes the statement from connection_.openStatements_ 
+     * and CommitAndRollbackListeners_ by passing true to markClosed.  
+     * 
+     * We may need to do 1) in finalizer too. This is being tracked in 
+     * DERBY-1021
+     * 
+     * @throws SqlException
+     */
     public void closeX() throws SqlException {
         if (!openOnClient_) {
             return;
@@ -460,13 +483,7 @@
                 flowCloseOutsideUOW();
             }
         } finally {
-            markClosed();
-            connection_.openStatements_.remove(this);
-        }
-        // push the mark close of rsmd into Statement.markClosed() method
-        if (resultSetMetaData_ != null) {
-            resultSetMetaData_.markClosed();
-            resultSetMetaData_ = null;
+            markClosed(true);
         }
     }
 
@@ -1375,7 +1392,39 @@
         }
     }
 
+    /**
+     * This method cleans up client-side resources held by this Statement. 
+     * The Statement will not be removed from the open statements list and 
+     * PreparedStatement will also not be removed from the commit and rollback 
+     * listeners list in <code>org.apache.derby.client.am.Connection</code>.
+     * 
+     * This method is called from:
+     * 1. finalize() - For the finaizer to be called, the Statement 
+     * should not have any references and so it should have been already 
+     * removed from the lists.  
+     * 
+     * 2. <code>org.apache.derby.client.am.Connection#markStatementsClosed</code>

+     * This method explicitly removes the Statement from open statements list.
+     *  
+     * 3. To close positioned update statements - These statements are not
+     * added to the list of open statements.
+     */
     void markClosed() {
+    	markClosed(false);
+    }
+    
+    /**
+     * This method cleans up client-side resources held by this Statement. 
+     * If removeListener is true, the Statement is removed from open statements
+     * list and PreparedStatement is also removed from commit and rollback 
+     * listeners list. This is called from the close methods.
+     * 
+     * @param removeListener if true the Statement will be removed
+     * from the open statements list and PreparedStatement will also be removed
+     * from commit and rollback listeners list in 
+     * <code>org.apache.derby.client.am.Connection</code>.
+     */
+    void markClosed(boolean removeListener) {
         openOnClient_ = false;
         markResultSetsClosed();
         // in case a cursorName was set on the Statement but the Statement was
@@ -1385,6 +1434,15 @@
         removeClientCursorNameFromCache();
         markPreparedStatementForAutoGeneratedKeysClosed();
         markClosedOnServer();
+
+        // mark close ResultSetMetaData
+        if (resultSetMetaData_ != null) {
+            resultSetMetaData_.markClosed();
+            resultSetMetaData_ = null;
+        }
+        
+        if(removeListener)
+        	connection_.openStatements_.remove(this);
     }
 
     void markPreparedStatementForAutoGeneratedKeysClosed() {
@@ -2012,13 +2070,22 @@
         return connection_;
     }
 
-    // Only called on positioned upate statements
+    // This was being called only on positioned update statements. When working 
+    // on DERBY-210, it was found that result sets of all statements (not just
+    // positioned update statements) get added to the table. So, this is called
+    // for all statements. Otherwise, this will cause memory leaks when statements
+    // are not explicitly closed in the application. 
     void resetCursorNameAndRemoveFromWhereCurrentOfMappings() {
         // Remove client/server cursorName -> ResultSet mapping from the hashtable.
         // If Statement.close() is called before ResultSet.close(), then statement_.section
is null.
         if (section_ != null) {
             agent_.sectionManager_.removeCursorNameToResultSetMapping(cursorName_,
                     section_.getServerCursorNameForPositionedUpdate());
+
+            // remove resultset mapping for other cursors (other than positioned
+            // update statements) - DERBY-210
+            agent_.sectionManager_.removeCursorNameToResultSetMapping(cursorName_,
+                    section_.getServerCursorName());
 
             // Remove client and server cursorName -> QuerySection mapping from the hashtable
             // if one exists

Modified: db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java?rev=408612&r1=408611&r2=408612&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java (original)
+++ db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java Mon
May 22 02:01:22 2006
@@ -33,6 +33,10 @@
 */
 class DRDAResultSet
 {
+	//NOTE!
+	//
+	// Since DRDAResultSets are reused, ALL variables should be set 
+	// to their default values in reset().
 
 	// resultSet states are NOT_OPENED and SUSPENDED
 	protected static final int NOT_OPENED = 1;
@@ -347,19 +351,18 @@
 	}
 	
 	
-	/** Clean up statements and resultSet
+	/**
+	 * This method closes the JDBC objects and frees up all references held by
+	 * this object.
 	 * 
+	 * @throws SQLException
 	 */
 	protected void close()  throws SQLException
 	{
 		if (rs != null)
 			rs.close();
 		rs = null;
-		gotPrctyp = false;
 		outovr_drdaType = null;
-		scrollType = ResultSet.TYPE_FORWARD_ONLY;	
-		concurType = 0;
-		rowCount = 0;
 		rsLens = null;
 		rsDRDATypes = null;
 		rsPrecision = null;
@@ -367,9 +370,52 @@
 		extDtaObjects = null;
 		splitQRYDTA = null;
 		rsExtPositions = null;
-		state=NOT_OPENED;
+	}
+	
+	/**
+	 * This method resets the state of this DRDAResultset object so that it can
+	 * be re-used. This method should reset all variables of this class.
+	 * 
+	 */
+	protected void reset() {
+		explicitlyClosed = false;
+		state = NOT_OPENED;
 		hasdata = true;
-		splitQRYDTA = null;
+		rsLens = null;
+		rsDRDATypes = null;
+		rsPrecision = null;
+		rsScale = null;
+		
+		outovr_drdaType = null;
+		
+		withHoldCursor = 0;	
+		scrollType = ResultSet.TYPE_FORWARD_ONLY;
+		concurType = 0;
+		rowCount = 0;
+		rs = null;
+		
+		blksize = 0;
+		maxblkext = 0;	
+		outovropt = 0;
+		qryclsimp = CodePoint.QRYCLSIMP_NO;	
+		qryrelscr = false;
+		qryrownbr = 0;
+		qryrfrtbl = false;	
+		qryscrorn = 0;
+		qryrowsns = false; 
+		qryblkrst = false;
+		qryrtndta = false;	
+		qryrowset = 0;
+		qryprctyp = 0;
+		gotPrctyp = false; 	
+		rtnextdta = 0;	
+		nbrrow = 0;
+		rslsetflg = null;	
+
+		extDtaObjects = null;
+		rsExtPositions = null;
+		pkgcnstkn = null;
+		splitQRYDTA = null;	
 	}
 
 

Modified: db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/DRDAStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/DRDAStatement.java?rev=408612&r1=408611&r2=408612&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/DRDAStatement.java (original)
+++ db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/DRDAStatement.java Mon
May 22 02:01:22 2006
@@ -51,7 +51,12 @@
 class DRDAStatement
 {
 
-
+	//NOTE!
+	//
+	// Since DRDAStatements are reused, ALL variables (except those noted in 
+	// the comments for reset method) should be set to their default values 
+	// in reset().
+	
 
 	protected String typDefNam;		//TYPDEFNAM for this statement
 	protected int byteOrder;		//deduced from typDefNam, save String comparisons
@@ -455,7 +460,13 @@
 	}
 
 	/**
-	 * Initialize for reuse
+	 * This method is used to initialize the default statement of the database
+	 * for re-use. It is different from reset() method since default statements
+	 * get initiliazed differently. e.g: stmt variable used in default statement
+	 * is created only once in Database.makeConnection. 
+	 * TODO: Need to see what exactly it means to initialize the default 
+	 * statement. (DERBY-1002)
+	 * 
 	 */
 	protected void initialize() 
 	{
@@ -943,9 +954,11 @@
 		return currentDrdaRs.wasExplicitlyClosed();
 	}
 
-	/** 
-	 * Clean up statements and resultSet
+	/**
+	 * This method closes the JDBC objects and frees up all references held by
+	 * this object.
 	 * 
+	 * @throws SQLException
 	 */
 	protected void close()  throws SQLException
 	{
@@ -953,29 +966,71 @@
 			ps.close();
 		if (stmt != null)
 			stmt.close();
-		rsClose();
+		currentDrdaRs.close();
 		resultSetTable = null;
 		resultSetKeyList = null;
-		numResultSets = 0;
 		ps = null;
 		stmtPmeta = null;
 		stmt = null;
+		rslsetflg = null;
+		procName = null;
+		outputTypes = null;
+		cliParamDrdaTypes = null;
+		cliParamLens = null;
+		cliParamExtPositions = null;
+
+	}
+	
+	/**
+	 * This method resets the state of this DRDAStatement object so that it can
+	 * be re-used. This method should reset all variables of this class except 
+	 * the following:
+     * 1. database - This variable gets initialized in the constructor and by
+     * call to setDatabase.
+     * 2. members which get initialized in setPkgnamcsn (pkgnamcsn, pkgcnstkn, 
+     * pkgid, pkgsn, isolationLevel, cursorName). pkgnamcsn is the key used to 
+     * find if the DRDAStatement can be re-used. Hence its value will not change 
+     * when the object is re-used.
+	 * 
+	 */
+	protected void reset() 
+	{
+		setTypDefValues();
+		
+		withHoldCursor = -1;
 		scrollType = ResultSet.TYPE_FORWARD_ONLY;	
 		concurType = ResultSet.CONCUR_READ_ONLY;;
-		withHoldCursor = -1;
 		rowCount = 0;
 		rslsetflg = null;
 		maxrslcnt = 0;
+		ps = null;
+		stmtPmeta = null;
+		isCall = false;
 		procName = null;
 		outputTypes = null;
 		outputExpected = false;
-		isCall = false;
-		explicitlyPrepared = false;
-		cliParamDrdaTypes = null;
-		cliParamLens = null;
+		stmt = null;
+		
+		currentDrdaRs.reset();
+		resultSetTable = null;
+		resultSetKeyList = null;
+		numResultSets = 0;
+		
+		cliParamDrdaTypes = new Vector();
+		cliParamLens = new Vector();
 		cliParamExtPositions = null;
+		
+		nbrrow = 0;
+		qryrowset = 0;	
+		blksize = 0;		
+		maxblkext = 0;	
+		outovropt = 0;	
+		qryrfrtbl = false;
+		qryprctyp = CodePoint.QRYBLKCTL_DEFAULT;
 
-	}	
+		needsToSendParamData = false;
+		explicitlyPrepared = false;
+	}
 
 	/**
 	 * is Statement closed

Modified: db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/Database.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/Database.java?rev=408612&r1=408611&r2=408612&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/Database.java (original)
+++ db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/Database.java Mon May
22 02:01:22 2006
@@ -183,10 +183,15 @@
 	}
 	
 	/**
-	 * Get a new DRDA statement and store it in the stmtTable if stortStmt is true
-	 * If possible recycle an existing statement
-	 * If we are asking for one with the same name it means it
-	 * was already closed.
+	 * Get a new DRDA statement and store it in the stmtTable if stortStmt is 
+	 * true. If possible recycle an existing statement. When the server gets a
+	 * new statement with a previously used pkgnamcsn, it means that 
+	 * client-side statement associated with this pkgnamcsn has been closed. In 
+	 * this case, server can re-use the DRDAStatement by doing the following:  
+	 * 1) Retrieve the old DRDAStatement associated with this pkgnamcsn and
+	 * close it.
+	 * 2) Reset the DRDAStatement state for re-use.
+	 * 
 	 * @param pkgnamcsn  Package name and section
 	 * @return DRDAStatement  
 	 */
@@ -194,8 +199,10 @@
 	throws SQLException
 	{
 		DRDAStatement stmt = getDRDAStatement(pkgnamcsn);
-		if (stmt != null)
+		if (stmt != null) {
 			stmt.close();
+			stmt.reset();
+		}
 		else
 		{
 			stmt = new DRDAStatement(this);

Added: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/derbyStress.out
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/derbyStress.out?rev=408612&view=auto
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/derbyStress.out
(added)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/derbyStress.out
Mon May 22 02:01:22 2006
@@ -0,0 +1,4 @@
+Test derbyStress starting
+Testing with 2000 prepared statements
+PASS -- Prepared statement test
+Test derbyStress finished.
\ No newline at end of file

Propchange: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/derbyStress.out
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude?rev=408612&r1=408611&r2=408612&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude
(original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/DerbyNet.exclude
Mon May 22 02:01:22 2006
@@ -6,6 +6,7 @@
 # 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 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.
+# excluding jdbcapi/derbyStress.java - jcc runs out of memory with this test
 jdbcapi/resultsetStream.java
 lang/errorStream.java
 lang/scrollCursors2.java
@@ -14,3 +15,4 @@
 jdbcapi/testRelative.java
 jdbcapi/rsgetXXXcolumnNames.java
 lang/updatableResultSet.java
+jdbcapi/derbyStress.java

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall?rev=408612&r1=408611&r2=408612&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall
(original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall
Mon May 22 02:01:22 2006
@@ -1,6 +1,7 @@
 jdbcapi/bestrowidentifier.sql
 jdbcapi/characterStreams.java
 jdbcapi/checkDriver.java
+jdbcapi/derbyStress.java
 jdbcapi/nullSQLText.java
 jdbcapi/prepStmtMetaData.java
 jdbcapi/resultset.java

Added: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress.java?rev=408612&view=auto
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress.java
(added)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress.java
Mon May 22 02:01:22 2006
@@ -0,0 +1,120 @@
+/*
+
+Derby - Class org.apache.derbyTesting.functionTests.tests.jdbcapi.derbyStress
+
+Copyright 1999, 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.derbyTesting.functionTests.tests.jdbcapi;
+
+import java.sql.Connection;
+import java.sql.Statement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.apache.derby.tools.ij;
+import org.apache.derbyTesting.functionTests.util.TestUtil;
+
+public class derbyStress {
+	
+	private static String[] testObjects = {"table t1"};
+	
+	private static int numConn = 1;
+	private static int numRows = 100;
+	private static int numPreparedStmts = 2000; 
+
+	public static void main(String[] args) {
+		try {
+			System.out.println("Test derbyStress starting");
+
+			// use the ij utility to read the property file and
+			// make the initial connection.
+			ij.getPropertyArg(args);
+			Connection conn = null;
+			
+			for (int i = 0; i < numConn; i++) {
+				 conn = ij.startJBMS();
+				 System.out.println("Testing with " + numPreparedStmts + " prepared statements");
+				 prepStmtTest(conn, numRows, numPreparedStmts);
+				 System.out.println("PASS -- Prepared statement test");
+				 conn.close();
+			}
+			System.out.println("Test derbyStress finished.");
+		} catch (SQLException se) {
+			TestUtil.dumpSQLExceptions(se);
+		} catch (Throwable e) {
+			System.out.println("FAIL -- unexpected exception caught in main():\n");
+			System.out.println(e.getMessage());
+			e.printStackTrace();
+		}
+	}
+	
+	private static void createTables(Connection conn, int numRows) throws SQLException{
+		Statement stmt = conn.createStatement();
+		
+		TestUtil.cleanUpTest(stmt, testObjects);
+		
+		stmt.execute("create table t1 (lvc  LONG VARCHAR)");
+		stmt.close();
+		
+		String insertTabSql = "insert into t1 values(?)";
+		PreparedStatement ps = conn.prepareStatement(insertTabSql);
+		 for (int i = 0; i < numRows; i++)
+		 {
+			 ps.setString(1,"Hello" + i);
+			 ps.executeUpdate();
+		 }
+		 ps.close();
+	}
+	
+	// Tests prepared statements are not leaked if not explicitly closed by
+	// user (DERBY-210)
+	private static void prepStmtTest(Connection conn, int numRows, int numPreparedStmts) throws
Exception
+	{
+		PreparedStatement ps = null;
+		ResultSet rs = null;
+		conn.setAutoCommit(false);
+		 
+		try {
+		
+			createTables(conn, numRows);
+			
+			String selTabSql = "select * from t1";
+			
+			for (int i = 0 ; i  < numPreparedStmts; i++)
+			{
+				ps = conn.prepareStatement(selTabSql);
+				rs = ps.executeQuery();
+
+				while (rs.next())
+				{
+					rs.getString(1);
+				}
+
+				rs.close();
+			
+				// Do not close the prepared statement
+				//ps.close();
+			}
+			conn.commit();
+		} 
+		catch (SQLException e) {
+			TestUtil.dumpSQLExceptions(e);
+			conn.rollback();
+		}
+	}
+}

Propchange: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress_app.properties
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress_app.properties?rev=408612&view=auto
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress_app.properties
(added)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress_app.properties
Mon May 22 02:01:22 2006
@@ -0,0 +1,5 @@
+usedefaults=true
+jvmflags=-Xmx64M
+
+#OutOfMemoryError when run with j9. It passes with j9 foundation profile
+runwithj9=false

Propchange: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/derbyStress_app.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/lang/procedure.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/lang/procedure.java?rev=408612&r1=408611&r2=408612&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/lang/procedure.java
(original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/lang/procedure.java
Mon May 22 02:01:22 2006
@@ -467,6 +467,8 @@
             se.printStackTrace(System.out);
         }
 
+        // Call setupStatementReuse which will make the server to reuse an existing statement.

+        setupStatementReuse(conn);
         CallableStatement cSt = conn.prepareCall("call TEST_PROC_JIRA_491(?)");
         cSt.setInt(1, 3);
         try {
@@ -1695,4 +1697,64 @@
 
 	}
 
+    /**
+     * This method is used to set up an environment which can be used to test 
+     * DERBY-1002. It creates statements and closes them to provoke the client
+     * driver to re-use sections which in turn will make the network server to
+     * re-use statements and result sets. It does not test anything by itself.
+     * It just sets up an environment where the statements used in this test 
+     * will be re-used in later tests. It is called from methods 
+     * 'jira_491_492' and 'testImplicitClose'. When the re-use was not happening 
+     * correctly, 'jira_491_492' and 'testImplicitClose' were giving following 
+     * errors:
+     * 
+     * 1. In the test for jira491, client expects a QRYDTA for the CNTQRY request. 
+     * Instead, it recieves a QRYNOPRM reply because server closes the query 
+     * wrongly.
+     * 2. In testImplicitClose, the query is not supposed to be closed in case
+     * of EXCSQLSTT commands. If re-use happens wrongly, server closes the query 
+     * for EXCSQLSTT commands too.
+     *   
+     * @param conn Connection
+     */
+    private static void setupStatementReuse(Connection conn)
+    							throws SQLException{
+    	
+    	Statement stmt = conn.createStatement();
+		try {
+			stmt.execute("drop table test_table_jira_1002");
+		} catch (SQLException se) { }
+
+		try {
+			stmt.execute("drop procedure test_proc_jira_1002");
+		} catch (SQLException se) { }
+
+		stmt.execute("create table test_table_jira_1002(id int)");
+		stmt.execute("insert into test_table_jira_1002 values(1) , (2)");
+
+		//create a procedure which returns a result set
+		stmt.execute("create procedure test_proc_jira_1002(name varchar(50)) " +
+					"language java parameter style java external name " +
+					"'org.apache.derbyTesting.functionTests.util.ProcedureTest.selectRows'" +
+					"dynamic result sets 1");
+    	
+    	
+		// Create a select statement to make currentDrdaRs.qryclsimp=CodePoint.QRYCLSIMP_YES
+    	Statement st_opnqry = conn.createStatement();
+		ResultSet rs_opnqry = st_opnqry.executeQuery("SELECT * FROM TEST_TABLE_JIRA_1002");
+		rs_opnqry.next();
+		// Close st_opnqry so that cSt1 will reuse same DRDAStatement
+		st_opnqry.close();
+
+		// Use up the next statement's result set to make currentDrdaRs.hasdata=false
+		CallableStatement cSt1 = conn.prepareCall("call test_proc_jira_1002(?)");
+		cSt1.setString(1, "test_table_jira_1002");
+		cSt1.execute();
+		ResultSet rs1 = cSt1.getResultSet();
+		rs1.next();
+		// Close cSt1 so that a statement created after a call to this method 
+		// will cause the server to use same DRDAStatement.
+		cSt1.close();
+    	
+    }    
 }

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/util/ProcedureTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/util/ProcedureTest.java?rev=408612&r1=408611&r2=408612&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/util/ProcedureTest.java
(original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/util/ProcedureTest.java
Mon May 22 02:01:22 2006
@@ -274,6 +274,16 @@
 		conn.close();
 	}
 
+	// select all rows from a table
+	public static void selectRows(String table, ResultSet[] rs)
+		throws SQLException
+	{
+		Connection conn = DriverManager.getConnection("jdbc:default:connection");
+		Statement stmt = conn.createStatement();
+		rs[0] = stmt.executeQuery("SELECT * FROM " + table);
+		conn.close();
+	}
+	
 	public static void fivejp(ResultSet[] data1, ResultSet[] data2, ResultSet[] data3, ResultSet[]
data4, ResultSet[] data5) throws SQLException {
 
 		Connection conn = DriverManager.getConnection("jdbc:default:connection");



Mime
View raw message