db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kmars...@apache.org
Subject svn commit: r381937 - in /db/derby/code/trunk/java: drda/org/apache/derby/impl/drda/ testing/org/apache/derbyTesting/functionTests/tests/lang/
Date Wed, 01 Mar 2006 07:29:36 GMT
Author: kmarsden
Date: Tue Feb 28 23:29:33 2006
New Revision: 381937

URL: http://svn.apache.org/viewcvs?rev=381937&view=rev
Log:
DERBY-1002 - Check that DRDAStatement and DRDAResultSet states are reset when they are re-used

Contributed by Deepa  Remesh

Please take a look at following two patches - patch 1 contains code changes and patch 2 contains
tests. These have to be committed together.

------------------------------------------
1. derby1002-patch1-v1
------------------------------------------
* Adds reset() methods to DRDAStatement and DRDAResultSet objects. The purpose of reset method
is to reset the states of all variables so that the objects can be re-used and will not have
left-over states.

* In case of DRDAStatement, the following variables are not reset:
+ * 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.

* close() methods are changed to only close and dereference objects.

* DRDAStatement.rsClose() method is not used in close() or reset(). This method has some checks
which were causing the method to return without resetting currentDrdaRs. Now, close() calls
currentDrdaRs.close() and reset() calls currentDrdaRs.reset().

* In Database.newDrdaStatement, close() method is called followed by reset() when the server
finds the statement can be re-used.

------------------------------------------
2. derby1002-patch2-v2
------------------------------------------
Modifies test lang/procedure.java. Adds a method 'setupStatementReuse' which creates and uses
statements in such a way as to provoke re-use of statements and result sets on network server.
This method is called from tests for jira-491 and 'testImplicitClose'.

------------------------------------------------------------------------------------
Remaining TODOs for DERBY-1002
------------------------------------------------------------------------------------
* pkgcnstkn, pkgid, pkgsn variables can be removed from DRDAStatement since these are derived
from pkgnamcsn object.
* Look into what is required by initialize() of default statement. Currently, initialize just
calls setTypDefValues(). Once the purpose of this method is confirmed, we may need to modify
the comments at places it is currently called.



Modified:
    db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java
    db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java
    db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Database.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/procedure.java

Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java?rev=381937&r1=381936&r2=381937&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAResultSet.java Tue Feb 28
23:29:33 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;
@@ -341,19 +345,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;
@@ -361,8 +364,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;
+		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/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java?rev=381937&r1=381936&r2=381937&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAStatement.java Tue Feb 28
23:29:33 2006
@@ -50,7 +50,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
@@ -462,7 +467,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() 
 	{
@@ -949,9 +960,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
 	{
@@ -959,29 +972,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/trunk/java/drda/org/apache/derby/impl/drda/Database.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Database.java?rev=381937&r1=381936&r2=381937&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Database.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/Database.java Tue Feb 28 23:29:33
2006
@@ -168,10 +168,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  
 	 */
@@ -179,8 +184,10 @@
 	throws SQLException
 	{
 		DRDAStatement stmt = getDRDAStatement(pkgnamcsn);
-		if (stmt != null)
+		if (stmt != null) {
 			stmt.close();
+			stmt.reset();
+		}
 		else
 		{
 			stmt = new DRDAStatement(this);

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/procedure.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/procedure.java?rev=381937&r1=381936&r2=381937&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/procedure.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/procedure.java
Tue Feb 28 23:29:33 2006
@@ -478,6 +478,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 {
@@ -1834,6 +1836,9 @@
 		stmt.execute("create procedure jira821 (name varchar(50)) " +
 					 "parameter style java language java external name " +
 					 "'" + proc + "' dynamic result sets 1 reads sql data");
+		
+        // Call setupStatementReuse which will make the server to reuse an existing statement.
+		setupStatementReuse(conn);
 		CallableStatement cs = conn.prepareCall("call jira821 (?)");
 		cs.setString(1, "derby821");
 		cs.execute();
@@ -1862,6 +1867,67 @@
 		conn.setAutoCommit(savedAutoCommit);
 	}
 
+    /**
+     * 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();
+    	
+    }    
+    
     /**
      * Checks to see if there is a lock on a table by attempting to modify the
      * same table. If the first connection was serializable then it will 



Mime
View raw message