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 be...@apache.org on 2006/02/13 13:44:17 UTC
svn commit: r377367 - in /db/derby/code/trunk/java:
client/org/apache/derby/client/am/ client/org/apache/derby/client/net/
drda/org/apache/derby/impl/drda/
testing/org/apache/derbyTesting/functionTests/master/
testing/org/apache/derbyTesting/functionTe...
Author: bernt
Date: Mon Feb 13 04:44:07 2006
New Revision: 377367
URL: http://svn.apache.org/viewcvs?rev=377367&view=rev
Log:
DERBY-821 Client driver: Implicitly close exhausted result sets on the server.
Submitted by Knut Anders Hatlen
Modified:
db/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java
db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java
db/derby/code/trunk/java/client/org/apache/derby/client/am/SqlCode.java
db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java
db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java
db/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java
db/derby/code/trunk/java/client/org/apache/derby/client/net/NetResultSet.java
db/derby/code/trunk/java/client/org/apache/derby/client/net/NetSqldta.java
db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java
db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementRequest.java
db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/AppRequester.java
db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/CodePointNameTable.java
db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
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/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/forupdate.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/holdCursorIJ.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/procedure.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/forupdate.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/holdCursorIJ.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/holdCursorJava.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk14/procedure.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk14/updatableResultSet.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/procedure.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/updatableResultSet.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/forupdate.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/holdCursorIJ.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/holdCursorJava.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/j9_foundation/holdCursorJava.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/procedure.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/testProtocol.out
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/protocol.tests
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/setTransactionIsolation.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/forupdate.sql
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/holdCursorIJ.sql
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/holdCursorJava.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/procedure.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/ProcedureTest.java
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Cursor.java Mon Feb 13 04:44:07 2006
@@ -69,7 +69,7 @@
// This flag indicates that the server has returned all the rows, and is positioned
// after last, for both scrollable and forward-only cursors.
// For singleton cursors, this memeber will be set to true as soon as next is called.
- public boolean allRowsReceivedFromServer_;
+ private boolean allRowsReceivedFromServer_;
// Total number of rows read so far.
// This should never exceed this.statement.maxRows
@@ -116,7 +116,7 @@
public Cursor(Agent agent, byte[] dataBuffer) {
this(agent);
dataBuffer_ = dataBuffer;
- allRowsReceivedFromServer_ = false;
+ setAllRowsReceivedFromServer(false);
}
public void setNumberOfColumns(int numberOfColumns) {
@@ -133,9 +133,16 @@
jdbcTypes_ = new int[numberOfColumns];
}
- // Makes the next row the current row.
- // Returns true if the current row position is a valid row position.
- public boolean next() throws SqlException {
+ /**
+ * Makes the next row the current row. Returns true if the current
+ * row position is a valid row position.
+ *
+ * @param allowServerFetch if false, don't fetch more data from
+ * the server even if more data is needed
+ * @return <code>true</code> if current row position is valid
+ * @exception SqlException if an error occurs
+ */
+ protected boolean stepNext(boolean allowServerFetch) throws SqlException {
// local variable usd to hold the returned value from calculateColumnOffsetsForRow()
boolean rowPositionIsValid = true;
@@ -162,17 +169,45 @@
// The parameter passed in here is used as an index into the cached rowset for
// scrollable cursors, for the arrays to be reused. It is not used for forward-only
// cursors, so just pass in 0.
- rowPositionIsValid = calculateColumnOffsetsForRow_(0); // readFetchedRows()
+ rowPositionIsValid = calculateColumnOffsetsForRow_(0, allowServerFetch);
markNextRowPosition();
return rowPositionIsValid;
}
+ /**
+ * Makes the next row the current row. Returns true if the current
+ * row position is a valid row position.
+ *
+ * @return <code>true</code> if current row position is valid
+ * @exception SqlException if an error occurs
+ */
+ public boolean next() throws SqlException {
+ return stepNext(true);
+ }
+
//--------------------------reseting cursor state-----------------------------
- public final void setAllRowsReceivedFromServer(boolean b) {
+ /**
+ * Set the value of value of allRowsReceivedFromServer_.
+ *
+ * @param b a <code>boolean</code> value indicating whether all
+ * rows are received from the server
+ */
+ public void setAllRowsReceivedFromServer(boolean b) {
allRowsReceivedFromServer_ = b;
}
+ /**
+ * Return <code>true</code> if all rows are received from the
+ * server.
+ *
+ * @return <code>true</code> if all rows are received from the
+ * server.
+ */
+ public final boolean allRowsReceivedFromServer() {
+ return allRowsReceivedFromServer_;
+ }
+
public final boolean currentRowPositionIsEqualToNextRowPosition() {
return (currentRowPosition_ == nextRowPosition_);
}
@@ -186,7 +221,7 @@
lastValidBytePosition_ = 0;
currentRowPosition_ = 0;
nextRowPosition_ = 0;
- allRowsReceivedFromServer_ = false;
+ setAllRowsReceivedFromServer(false);
dataBufferStream_.reset();
}
@@ -194,7 +229,20 @@
return (lastValidBytePosition_ - position_) > 0;
}
- protected abstract boolean calculateColumnOffsetsForRow_(int row) throws SqlException, DisconnectException;
+ /**
+ * Calculate the column offsets for a row.
+ *
+ * @param row row index
+ * @param allowServerFetch if true, allow fetching more data from
+ * server
+ * @return <code>true</code> if the current row position is a
+ * valid row position.
+ * @exception SqlException
+ * @exception DisconnectException
+ */
+ protected abstract boolean
+ calculateColumnOffsetsForRow_(int row, boolean allowServerFetch)
+ throws SqlException, DisconnectException;
protected abstract void clearLobData_();
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java Mon Feb 13 04:44:07 2006
@@ -420,6 +420,7 @@
if (!openOnClient_) {
return;
}
+ preClose_();
try {
if (openOnServer_) {
flowCloseAndAutoCommitIfNotAutoCommitted();
@@ -2264,7 +2265,7 @@
// for forward-only cursors, getRow() should return 0 if cursor is not on a valid row,
// i.e. afterlast.
{
- row = (cursor_.allRowsReceivedFromServer_ &&
+ row = (cursor_.allRowsReceivedFromServer() &&
cursor_.currentRowPositionIsEqualToNextRowPosition()) ? 0 : cursor_.rowsRead_;
} else {
if (rowCountIsUnknown()) {
@@ -4184,7 +4185,10 @@
}
}
- void markClosedOnServer() {
+ /**
+ * Mark this ResultSet as closed on the server.
+ */
+ public void markClosedOnServer() {
openOnServer_ = false;
}
@@ -4214,19 +4218,6 @@
return sqlcode;
}
- public void setCloseOnlyStateForSingletonCursors() {
- markClosedOnServer();
- }
-
- // If autocommit is on, the commit was already flowed with the execute() that
- // generated the singleton cursor. The correct state needs to be set into
- // the result set now.
- public void setAutoCommitStateForSingletonCursors() {
- if (connection_.autoCommit_) {
- markAutoCommitted();
- }
- }
-
// Set rowCount.
public void setRowCountEvent(long rowCount) throws DisconnectException {
// Only set the row count if it's unknown, to prevent clobbering of a valid value.
@@ -4650,7 +4641,8 @@
// This method is only called after open query to parse out the very first rowset
// received.
- if (cursor_.allRowsReceivedFromServer_ && rowsReceivedInCurrentRowset_ == 0) {
+ if (cursor_.allRowsReceivedFromServer() &&
+ rowsReceivedInCurrentRowset_ == 0) {
setRowsetNoRowsEvent();
}
}
@@ -4756,7 +4748,7 @@
if (resultSetContainsNoRows() || isAfterLastX()) {
return false;
} else if (firstRowInRowset_ + currentRowInRowset_ == lastRowInRowset_ &&
- cursor_.allRowsReceivedFromServer_) {
+ cursor_.allRowsReceivedFromServer()) {
isAfterLast_ = true;
setRowsetAfterLastEvent();
return false;
@@ -4789,7 +4781,8 @@
// If no row was received but received sqlcode +100, then the cursor is
// positioned after last.
- if (rowsReceivedInCurrentRowset_ == 0 && cursor_.allRowsReceivedFromServer_) {
+ if (rowsReceivedInCurrentRowset_ == 0 &&
+ cursor_.allRowsReceivedFromServer()) {
isAfterLast_ = true;
setRowsetAfterLastEvent();
return false;
@@ -4861,8 +4854,8 @@
// If no row was received but received sqlcode +100, then the cursor is
// positioned before first.
- if (rowsReceivedInCurrentRowset_ == 0 && cursor_.allRowsReceivedFromServer_) {
- //cursor_.beginningOfResultSetIsReached_ = true;
+ if (rowsReceivedInCurrentRowset_ == 0 &&
+ cursor_.allRowsReceivedFromServer()) {
isBeforeFirst_ = true;
setRowsetBeforeFirstEvent();
return false;
@@ -4911,7 +4904,8 @@
// If no row was received but received sqlcode +100, then the cursor is
// positioned after last or before first.
- if ((rowsReceivedInCurrentRowset_ == 0 && cursor_.allRowsReceivedFromServer_) ||
+ if ((rowsReceivedInCurrentRowset_ == 0 &&
+ cursor_.allRowsReceivedFromServer()) ||
orientation == scrollOrientation_before__) {
if (row > 0) {
setRowsetAfterLastEvent();
@@ -4940,7 +4934,8 @@
private boolean getRelativeRowset(long rows) throws SqlException {
if (rows == 0 &&
- (cursor_.allRowsReceivedFromServer_ || absolutePosition_ > rowCount_)) {
+ (cursor_.allRowsReceivedFromServer() ||
+ absolutePosition_ > rowCount_)) {
setRowsetAfterLastEvent();
isAfterLast_ = true;
return false;
@@ -4949,7 +4944,8 @@
flowGetRowset(scrollOrientation_relative__, rows);
parseRowset_();
- if (rowsReceivedInCurrentRowset_ == 0 && cursor_.allRowsReceivedFromServer_) {
+ if (rowsReceivedInCurrentRowset_ == 0 &&
+ cursor_.allRowsReceivedFromServer()) {
if (rows > 0) {
setRowsetAfterLastEvent();
isAfterLast_ = true;
@@ -4979,7 +4975,8 @@
parseRowset_();
// If no row was received but received sqlcode +100, then no row in the result set
- if (rowsReceivedInCurrentRowset_ == 0 && cursor_.allRowsReceivedFromServer_) {
+ if (rowsReceivedInCurrentRowset_ == 0 &&
+ cursor_.allRowsReceivedFromServer()) {
resetRowsetFlags();
this.setRowsetNoRowsEvent();
return false;
@@ -5022,7 +5019,8 @@
}
parseRowset_();
- if (rowsReceivedInCurrentRowset_ == 0 && cursor_.allRowsReceivedFromServer_) {
+ if (rowsReceivedInCurrentRowset_ == 0 &&
+ cursor_.allRowsReceivedFromServer()) {
isAfterLast_ = true;
setRowsetAfterLastEvent();
return false;
@@ -5070,7 +5068,7 @@
}
private void setAbsolutePositionBasedOnAllRowsReceived() {
- absolutePosition_ = (cursor_.allRowsReceivedFromServer_) ?
+ absolutePosition_ = (cursor_.allRowsReceivedFromServer()) ?
lastRowInRowset_ + 1 : lastRowInRowset_;
}
@@ -5103,6 +5101,15 @@
protected abstract void parseRowset_() throws SqlException;
public abstract void setFetchSize_(int rows);
+
+ /**
+ * Method that is invoked by <code>closeX()</code> before the
+ * result set is actually being closed. Subclasses may override
+ * this method if work needs to be done before closing.
+ *
+ * @exception SqlException
+ */
+ protected abstract void preClose_() throws SqlException;
public ConnectionCallbackInterface getConnectionCallbackInterface() {
return connection_;
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/SqlCode.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/client/org/apache/derby/client/am/SqlCode.java?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/SqlCode.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/SqlCode.java Mon Feb 13 04:44:07 2006
@@ -34,7 +34,12 @@
code_ = code;
}
- int getCode() {
+ /**
+ * Return the SQL code represented by this instance.
+ *
+ * @return an SQL code
+ */
+ public final int getCode() {
return code_;
}
@@ -48,4 +53,7 @@
public final static SqlCode undefinedError = new SqlCode(-99999);
+ /** SQL code for SQL state 02000 (end of data). DRDA does not
+ * specify the SQL code for this SQL state, but Derby uses 100. */
+ public final static SqlCode END_OF_DATA = new SqlCode(100);
}
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetConnection.java Mon Feb 13 04:44:07 2006
@@ -1523,5 +1523,18 @@
public void setConnectionNull(boolean connectionNull) {
this.connectionNull = connectionNull;
}
+
+ /**
+ * Check whether the server has full support for the QRYCLSIMP
+ * parameter in OPNQRY.
+ *
+ * @return true if QRYCLSIMP is fully supported
+ */
+ public final boolean serverSupportsQryclsimp() {
+ NetDatabaseMetaData metadata =
+ (NetDatabaseMetaData) databaseMetaData_;
+ return metadata.serverSupportsQryclsimp();
+ }
+
}
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetCursor.java Mon Feb 13 04:44:07 2006
@@ -28,6 +28,7 @@
import org.apache.derby.client.am.SqlException;
import org.apache.derby.client.am.SqlWarning;
import org.apache.derby.client.am.Types;
+import org.apache.derby.client.am.SqlCode;
public class NetCursor extends org.apache.derby.client.am.Cursor {
@@ -55,6 +56,10 @@
boolean rtnextrow_ = true;
+ /** Flag indicating whether the result set on the server is
+ * implicitly closed when end-of-data is received. */
+ private boolean qryclsimpEnabled_;
+
//-----------------------------constants--------------------------------------
//---------------------constructors/finalizer---------------------------------
@@ -80,18 +85,42 @@
}
//-----------------------------parsing the data buffer------------------------
- // Pseudo-code:
- // parse thru the current row in dataBuffer computing column offsets
- // if (we hit the super.lastValidBytePosition, ie. encounter partial row) {
- // shift partial row bytes to beginning of dataBuffer (this.shiftPartialRowToBeginning())
- // reset current row position (also done by this.shiftPartialRowToBeginning())
- // send and recv continue-query into commBuffer (rs.flowContinueQuery())
- // parse commBuffer up to QRYDTA (rs.flowContinueQuery())
- // copy query data from reply's commBuffer to our dataBuffer (this.copyQrydta())
- // }
- // Returns true if the current row position is a valid row position.
- // rename this to parse*()
- protected boolean calculateColumnOffsetsForRow_(int rowIndex) throws SqlException, org.apache.derby.client.am.DisconnectException {
+ /**
+ * Calculate the column offsets for a row.
+ * <p>
+ * Pseudo-code:
+ * <ol>
+ * <li>parse thru the current row in dataBuffer computing column
+ * offsets</li>
+ * <li>if (we hit the super.lastValidBytePosition, ie. encounter
+ * partial row)
+ * <ol>
+ * <li>shift partial row bytes to beginning of dataBuffer
+ * (this.shiftPartialRowToBeginning())</li>
+ * <li>reset current row position (also done by
+ * this.shiftPartialRowToBeginning())</li>
+ * <li>send and recv continue-query into commBuffer
+ * (rs.flowContinueQuery())</li>
+ * <li>parse commBuffer up to QRYDTA
+ * (rs.flowContinueQuery())</li>
+ * <li>copy query data from reply's commBuffer to our
+ * dataBuffer (this.copyQrydta())</li>
+ * </ol>
+ * </ol>
+ *
+ * @param rowIndex row index
+ * @param allowServerFetch if true, allow fetching more data from
+ * server
+ * @return <code>true</code> if the current row position is a
+ * valid row position.
+ * @exception SqlException
+ * @exception DisconnectException
+ */
+ protected
+ boolean calculateColumnOffsetsForRow_(int rowIndex,
+ boolean allowServerFetch)
+ throws SqlException, DisconnectException
+ {
int daNullIndicator = CodePoint.NULLDATA;
int colNullIndicator = CodePoint.NULLDATA;
int length;
@@ -117,8 +146,8 @@
throw new SqlException(netAgent_.logWriter_, netSqlca);
} else {
if (sqlcode > 0) {
- if (sqlcode == 100) {
- allRowsReceivedFromServer_ = true;
+ if (sqlcode == SqlCode.END_OF_DATA.getCode()) {
+ setAllRowsReceivedFromServer(true);
if (netResultSet_ != null && netSqlca.containsSqlcax()) {
netResultSet_.setRowCountEvent(netSqlca.getRowCount(qrydscTypdef_));
}
@@ -146,7 +175,8 @@
// since it's only resetting nextRowPosition_ to position_ and position_ will
// not change again from this point.
- if (allRowsReceivedFromServer_ && (position_ == lastValidBytePosition_)) {
+ if (allRowsReceivedFromServer() &&
+ (position_ == lastValidBytePosition_)) {
markNextRowPosition();
makeNextRowPositionCurrent();
return false;
@@ -266,16 +296,19 @@
columnDataComputedLength_ = columnDataComputedLength;
isNull_ = columnDataIsNull;
- if (!allRowsReceivedFromServer_) {
+ if (!allRowsReceivedFromServer()) {
calculateLobColumnPositionsForRow();
// Flow another CNTQRY if we are blocking, are using rtnextrow, and expect
// non-trivial EXTDTAs for forward only cursors. Note we do not support
// EXTDTA retrieval for scrollable cursors.
// if qryrowset was sent on excsqlstt for a sp call, which is only the case
if (blocking_ && rtnextrow_ &&
- extdtaPositions_.size() > 0 && !netResultSet_.scrollable_) {
- if (!extdtaPositions_.isEmpty()) {
+ !netResultSet_.scrollable_ &&
+ !extdtaPositions_.isEmpty()) {
+ if (allowServerFetch) {
netResultSet_.flowFetch();
+ } else {
+ return false;
}
}
}
@@ -294,13 +327,29 @@
// the flag for allRowsReceivedFromServer_ is set, we still want to continue to parse through
// the data in the dataBuffer.
// But in the case where fixed row protocol is used,
- if (!blocking_ && allRowsReceivedFromServer_ && daNullIndicator == 0xFF) {
+ if (!blocking_ && allRowsReceivedFromServer() &&
+ daNullIndicator == 0xFF) {
return false;
} else {
return true;
}
}
+ /**
+ * Scan the data buffer to see if end of data (SQL state 02000)
+ * has been received. This method should only be called when the
+ * cursor is being closed since the pointer to the current row can
+ * be modified.
+ *
+ * @exception SqlException
+ */
+ void scanDataBufferForEndOfData() throws SqlException {
+ while (!allRowsReceivedFromServer() &&
+ (position_ != lastValidBytePosition_)) {
+ stepNext(false);
+ }
+ }
+
protected boolean isDataBufferNull() {
if (dataBuffer_ == null) {
return true;
@@ -1047,4 +1096,34 @@
return (((fdocaLength_[index] >> 8) & 0xff) + 2) / 2;
}
+ /**
+ * Set the value of value of allRowsReceivedFromServer_.
+ *
+ * @param b a <code>boolean</code> value indicating whether all
+ * rows are received from the server
+ */
+ public final void setAllRowsReceivedFromServer(boolean b) {
+ if (b && qryclsimpEnabled_) {
+ netResultSet_.markClosedOnServer();
+ }
+ super.setAllRowsReceivedFromServer(b);
+ }
+
+ /**
+ * Set a flag indicating whether QRYCLSIMP is enabled.
+ *
+ * @param flag true if QRYCLSIMP is enabled
+ */
+ final void setQryclsimpEnabled(boolean flag) {
+ qryclsimpEnabled_ = flag;
+ }
+
+ /**
+ * Check whether QRYCLSIMP is enabled on this cursor.
+ *
+ * @return true if QRYCLSIMP is enabled
+ */
+ final boolean getQryclsimpEnabled() {
+ return qryclsimpEnabled_;
+ }
}
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetDatabaseMetaData.java Mon Feb 13 04:44:07 2006
@@ -28,6 +28,8 @@
private final NetAgent netAgent_;
+ /** True if the server supports QRYCLSIMP. */
+ private boolean supportsQryclsimp_;
public NetDatabaseMetaData(NetAgent netAgent, NetConnection netConnection) {
// Consider setting product level during parse
@@ -61,17 +63,47 @@
// Support for a specific server version can be set as follows. For example
// if (productLevel_.greaterThanOrEqualTo(11,1,0))
// supportsTheBestThingEver = true
+ //
+ // WARNING WARNING WARNING !!!!
+ //
+ // If you define an instance variable of NetDatabaseMetaData that
+ // you want computeFeatureSet_() to compute, DO NOT assign an
+ // initial value to the variable in the
+ // declaration. NetDatabaseMetaData's constructor will invoke
+ // DatabaseMetaData's constructor, which then invokes
+ // computeFeatureSet_(). Initialization of instance variables in
+ // NetDatabaseMetaData will happen *after* the invocation of
+ // computeFeatureSet_() and will therefore overwrite the computed
+ // values. So, LEAVE INSTANCE VARIABLES UNINITIALIZED!
+ //
+ // END OF WARNING
protected void computeFeatureSet_() {
if (connection_.resultSetHoldability_ == 0) // property not set
{
setDefaultResultSetHoldability();
}
+ // Support for QRYCLSIMP was added in 10.2.0
+ if (productLevel_.greaterThanOrEqualTo(10, 2, 0)) {
+ supportsQryclsimp_ = true;
+ } else {
+ supportsQryclsimp_ = false;
+ }
}
public void setDefaultResultSetHoldability() {
connection_.resultSetHoldability_ = org.apache.derby.jdbc.ClientDataSource.HOLD_CURSORS_OVER_COMMIT;
+ }
+
+ /**
+ * Check whether the server has full support for the QRYCLSIMP
+ * parameter in OPNQRY.
+ *
+ * @return true if QRYCLSIMP is fully supported
+ */
+ final boolean serverSupportsQryclsimp() {
+ return supportsQryclsimp_;
}
}
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetResultSet.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetResultSet.java?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetResultSet.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetResultSet.java Mon Feb 13 04:44:07 2006
@@ -112,7 +112,7 @@
// Parse all the rows received in the rowset
// The index we are passing will keep track of which row in the rowset we are parsing
// so we can reuse the columnDataPosition/Length/IsNull arrays.
- while (netCursor_.calculateColumnOffsetsForRow_(row)) {
+ while (netCursor_.calculateColumnOffsetsForRow_(row, true)) {
rowsReceivedInCurrentRowset_++;
row++;
}
@@ -124,10 +124,10 @@
// the end of data is returned or when an error occurs. all successfully fetched rows
// are returned to the user. the specific error is not returned until the next fetch.
while (rowsReceivedInCurrentRowset_ != fetchSize_ &&
- !netCursor_.allRowsReceivedFromServer_ && !isRowsetCursor_ &&
+ !netCursor_.allRowsReceivedFromServer() && !isRowsetCursor_ &&
sensitivity_ != sensitivity_sensitive_dynamic__) {
flowFetchToCompleteRowset();
- while (netCursor_.calculateColumnOffsetsForRow_(row)) {
+ while (netCursor_.calculateColumnOffsetsForRow_(row, true)) {
rowsReceivedInCurrentRowset_++;
row++;
}
@@ -219,5 +219,20 @@
public void readCursorClose_() throws SqlException {
netAgent_.resultSetReply_.readCursorClose(this);
+ }
+
+ /**
+ * Method that is invoked by <code>closeX()</code> before the
+ * result set is actually being closed. If QRYCLSIMP is enabled on
+ * the cursor, scan data buffer for end of data (SQL state
+ * 02000). If end of data is received, the result set is closed on
+ * the server.
+ *
+ * @exception SqlException
+ */
+ protected void preClose_() throws SqlException {
+ if (netCursor_.getQryclsimpEnabled()) {
+ netCursor_.scanDataBufferForEndOfData();
+ }
}
}
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetSqldta.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetSqldta.java?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetSqldta.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetSqldta.java Mon Feb 13 04:44:07 2006
@@ -31,10 +31,10 @@
}
public boolean next() throws org.apache.derby.client.am.SqlException {
- if (allRowsReceivedFromServer_) {
+ if (allRowsReceivedFromServer()) {
return false;
} else {
- allRowsReceivedFromServer_ = true;
+ setAllRowsReceivedFromServer(true);
return true;
}
}
@@ -128,7 +128,7 @@
}
}
- if (!allRowsReceivedFromServer_) {
+ if (!allRowsReceivedFromServer()) {
calculateLobColumnPositionsForRow();
}
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementReply.java Mon Feb 13 04:44:07 2006
@@ -397,7 +397,7 @@
protected NetResultSet parseResultSetCursor(StatementCallbackInterface statementI,
Section section) throws DisconnectException {
// The first item returne is an OPNQRYRM.
- NetResultSet netResultSet = parseOPNQRYRM(statementI);
+ NetResultSet netResultSet = parseOPNQRYRM(statementI, false);
// The next to be returned is an OBJDSS so check for any TYPDEF overrides.
int peekCP = parseTypdefsOrMgrlvlovrs();
@@ -439,7 +439,7 @@
}
protected void parseOpenQuery(StatementCallbackInterface statementI) throws DisconnectException {
- NetResultSet netResultSet = parseOPNQRYRM(statementI);
+ NetResultSet netResultSet = parseOPNQRYRM(statementI, true);
NetSqlca sqlca = null;
int peekCP = peekCodePoint();
@@ -694,13 +694,26 @@
//-----------------------------parse DDM Reply Messages-----------------------
- // Open Query Complete Reply Message indicates to the requester that
- // an OPNQRY or EXCSQLSTT command completed normally and that the query
- // process has been initiated. It also indicates the type of query protocol
- // and cursor used for the query.
- // When an EXCSQLSTT contains an SQL statement that invokes a stored procedure,
- // and the procedure completes, an OPNQRYRM is returned for each answer set.
- protected NetResultSet parseOPNQRYRM(StatementCallbackInterface statementI) throws DisconnectException {
+ /**
+ * Open Query Complete Reply Message indicates to the requester
+ * that an OPNQRY or EXCSQLSTT command completed normally and that
+ * the query process has been initiated. It also indicates the
+ * type of query protocol and cursor used for the query.
+ * <p>
+ * When an EXCSQLSTT contains an SQL statement that invokes a
+ * stored procedure, and the procedure completes, an OPNQRYRM is
+ * returned for each answer set.
+ *
+ * @param statementI statement callback interface
+ * @param isOPNQRYreply If true, parse a reply to an OPNQRY
+ * command. Otherwise, parse a reply to an EXCSQLSTT command.
+ * @return a <code>NetResultSet</code> value
+ * @exception DisconnectException
+ */
+ protected NetResultSet parseOPNQRYRM(StatementCallbackInterface statementI,
+ boolean isOPNQRYreply)
+ throws DisconnectException
+ {
// these need to be initialized to the correct default values.
int svrcod = CodePoint.SVRCOD_INFO;
boolean svrcodReceived = false;
@@ -851,6 +864,13 @@
calculateResultSetConcurrency(qryattupd, statement.resultSetConcurrency_),
calculateResultSetHoldability(sqlcsrhld));
}
+
+ // QRYCLSIMP only applies to OPNQRY, not EXCSQLSTT
+ final boolean qryclsimp =
+ isOPNQRYreply &&
+ (rs.resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY) &&
+ netAgent_.netConnection_.serverSupportsQryclsimp();
+ rs.netCursor_.setQryclsimpEnabled(qryclsimp);
return rs;
}
Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementRequest.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementRequest.java?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementRequest.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetStatementRequest.java Mon Feb 13 04:44:07 2006
@@ -339,6 +339,13 @@
buildQRYROWSET(fetchSize);
}
+ // Tell the server to close forward-only result sets
+ // implicitly when they are exhausted. The server will ignore
+ // this parameter if the result set is scrollable.
+ if (netAgent_.netConnection_.serverSupportsQryclsimp()) {
+ buildQRYCLSIMP();
+ }
+
updateLengthBytes(); // opnqry is complete
}
@@ -1448,6 +1455,14 @@
}
}
+ /**
+ * Build QRYCLSIMP (Query Close Implicit). Query Close Implicit
+ * controls whether the target server implicitly closes a
+ * non-scrollable query upon end of data (SQLSTATE 02000).
+ */
+ private void buildQRYCLSIMP() {
+ writeScalar1Byte(CodePoint.QRYCLSIMP, CodePoint.QRYCLSIMP_YES);
+ }
// helper method to buildFDODTA to build the actual data length
private void setFDODTALobLength(int[][] protocolTypesAndLengths, int i, long dataLength) throws SqlException {
Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/AppRequester.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/AppRequester.java?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/AppRequester.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/AppRequester.java Mon Feb 13 04:44:07 2006
@@ -133,6 +133,17 @@
}
/**
+ * Check if the client expects QRYCLSIMP to be supported when the
+ * protocol is LMTBLKPRC.
+ *
+ * @return <code>true</code> if QRYCLSIMP is supported for
+ * LMTBLKPRC
+ */
+ protected final boolean supportsQryclsimpForLmtblkprc() {
+ return clientType == DNC_CLIENT;
+ }
+
+ /**
* Check if provided JCC version level is greaterThanOrEqualTo current level
*
* @param vLevel Version level
Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/CodePointNameTable.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/CodePointNameTable.java?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/CodePointNameTable.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/CodePointNameTable.java Mon Feb 13 04:44:07 2006
@@ -65,6 +65,7 @@
put (new Integer (CodePoint.EXCSQLSET), "EXCSQLSET");
put (new Integer (CodePoint.EXCSQLSTT), "EXCSQLSTT");
put (new Integer (CodePoint.EXTNAM), "EXTNAM");
+ put (new Integer (CodePoint.FRCFIXROW), "FRCFIXROW");
put (new Integer (CodePoint.MAXBLKEXT), "MAXBLKEXT");
put (new Integer (CodePoint.MAXRSLCNT), "MAXRSLCNT");
put (new Integer (CodePoint.MGRDEPRM), "MGRDEPRM");
@@ -93,6 +94,7 @@
put (new Integer (CodePoint.QRYBLKCTL), "QRYBLKCTL");
put (new Integer (CodePoint.QRYBLKRST), "QRYBLKRST");
put (new Integer (CodePoint.QRYBLKSZ), "QRYBLKSZ");
+ put (new Integer (CodePoint.QRYCLSIMP), "QRYCLSIMP");
put (new Integer (CodePoint.QRYCLSRLS), "QRYCLSRLS");
put (new Integer (CodePoint.QRYDSC), "QRYDSC");
put (new Integer (CodePoint.QRYDTA), "QRYDTA");
Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java Mon Feb 13 04:44:07 2006
@@ -6043,9 +6043,12 @@
if (! sentExtData)
writer.endDdmAndDss();
- if( (!stmt.hasdata()) &&
- stmt.isRSCloseImplicit()) {
- stmt.rsClose();
+ if (!stmt.hasdata()) {
+ final boolean qryclsOnLmtblkprc =
+ appRequester.supportsQryclsimpForLmtblkprc();
+ if (stmt.isRSCloseImplicit(qryclsOnLmtblkprc)) {
+ stmt.rsClose();
+ }
}
}
@@ -6416,8 +6419,9 @@
}
else // non-scrollable cursor
{
- if (stmt.isRSCloseImplicit())
- {
+ final boolean qryclsOnLmtblkprc =
+ appRequester.supportsQryclsimpForLmtblkprc();
+ if (stmt.isRSCloseImplicit(qryclsOnLmtblkprc)) {
stmt.rsClose();
stmt.rsSuspend();
}
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=377367&r1=377366&r2=377367&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 Mon Feb 13 04:44:07 2006
@@ -59,7 +59,7 @@
protected int blksize; // Query block size
protected int maxblkext; // Maximum number of extra blocks
protected int outovropt; // Output Override option
- private int qryclsimp; // Implicit Query Close Setting
+ protected int qryclsimp; // Implicit Query Close Setting
protected boolean qryrelscr; // Query relative scrolling
protected long qryrownbr; // Query row number
protected boolean qryrfrtbl; // Query refresh answer set table
@@ -92,6 +92,10 @@
protected DRDAResultSet()
{
state = NOT_OPENED;
+ // Initialize qryclsimp to NO. Only result sets requested by
+ // an OPNQRY command should be implicitly closed. OPNQRY will
+ // set qryclsimp later in setOPNQRYOptions().
+ qryclsimp = CodePoint.QRYCLSIMP_NO;
}
/**
@@ -487,19 +491,6 @@
return "UNKNOWN_STATE";
}
- }
-
- /**
- * Method to decide weather the ResultSet should be closed implicitly.
- * When the protocol type is Limited Block Query Protocol we should not
- * close implicitly even if qryclsimp is set to YES.
- *
- * @return close implicit boolean
- * @throws SQLException
- */
- boolean isRSCloseImplicit() throws SQLException {
- return qryclsimp == CodePoint.QRYCLSIMP_YES &&
- getQryprctyp() != CodePoint.LMTBLKPRC;
}
/**
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=377367&r1=377366&r2=377367&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 Mon Feb 13 04:44:07 2006
@@ -1623,14 +1623,23 @@
}
/**
- * Delegation method to call DRDAResultSet.isRSCloseImplicit()
- *
- * @see DRDAResultSet#isRSCloseImplicit()
+ * Method to decide whether the ResultSet should be closed
+ * implicitly based on the QRYCLSIMP value sent from the
+ * client. Only forward-only result sets should be implicitly
+ * closed. Some clients do not expect result sets to be closed
+ * implicitly if the protocol is LMTBLKPRC.
+ *
+ * @param lmtblkprcOK <code>true</code> if the client expects
+ * QRYCLSIMP to be respected for the LMTBLKPRC protocol
* @return implicit close boolean
- * @throws SQLException
+ * @exception SQLException
*/
- boolean isRSCloseImplicit() throws SQLException {
- return currentDrdaRs.isRSCloseImplicit();
+ boolean isRSCloseImplicit(boolean lmtblkprcOK) throws SQLException {
+ return
+ (currentDrdaRs.qryclsimp == CodePoint.QRYCLSIMP_YES) &&
+ !isScrollable() &&
+ (lmtblkprcOK ||
+ (currentDrdaRs.getQryprctyp() != CodePoint.LMTBLKPRC));
}
}
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/forupdate.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/forupdate.out?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/forupdate.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/forupdate.out Mon Feb 13 04:44:07 2006
@@ -121,18 +121,22 @@
ij> -- unions are not updatable
select * from t1 union all select * from t1 for update;
ERROR 42Y90: FOR UPDATE is not permitted in this type of statement.
+ij> insert into t1 (i) values (1);
+1 row inserted/updated/deleted
ij> -- . table with/without correlation name
----- the idea is that the delete is against the table name, not the correlation name
----- we've already seen the without correlation name case in previous tests
get cursor c4 as 'select i from t1 s1 for update';
ij> next c4;
-No current row
+I
+-----------
+1
ij> -- this will get a target table mismatch error, it uses the correlation name:
delete from s1 where current of c4;
-ERROR (no SQLState): Invalid cursor name "C4" in the Update/Delete statement.
-ij> -- this will compile and get a 'no current row' error, it uses the table name:
+ERROR 42X28: Delete table 'S1' is not target of cursor 'SQL_CURSH200C1'.
+ij> -- this will compile and succeed, it uses the table name:
delete from t1 where current of c4;
-ERROR (no SQLState): Invalid cursor name "C4" in the Update/Delete statement.
+1 row inserted/updated/deleted
ij> close c4;
ij> -- . list columns in order same/different from appearance in table
----- the columns are 'found' regardless of their order.
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/holdCursorIJ.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/holdCursorIJ.out?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/holdCursorIJ.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/holdCursorIJ.out Mon Feb 13 04:44:07 2006
@@ -94,13 +94,16 @@
-----
1 |1
ij> -- wont' be able to drop table because of cursors jdk1 and jdk4
+-- in DerbyNetClient, cursor is closed on server and DROP TABLE succeeds
drop table t1;
ERROR X0X95: Operation 'DROP TABLE' cannot be performed on object 'T1' because there is an open ResultSet dependent on that object.
ij> commit;
ij> -- drop table still won't work because jdk4 is still open after commit
+-- in DerbyNetClient, the table is already dropped
drop table t1;
ERROR X0X95: Operation 'DROP TABLE' cannot be performed on object 'T1' because there is an open ResultSet dependent on that object.
ij> -- close cursor jdk4 and try then deleting the table
+-- in DerbyNetClient, the table is already dropped
close jdk4;
ij> drop table t1;
0 rows inserted/updated/deleted
@@ -126,10 +129,12 @@
-----
1 |1
ij> -- try to change the isolation level. will give error because of jdk1 and jdk4
+-- no error in DerbyNetClient because cursor is closed on server
set current isolation RR;
ERROR X0X03: Invalid transaction state - held cursor requires same isolation level
ij> commit;
ij> -- attempt to change isolation level should give error because of jdk4 hold cursor
+-- no error in DerbyNetClient because cursor is closed on server
set isolation = REPEATABLE READ;
ERROR X0X03: Invalid transaction state - held cursor requires same isolation level
ij> -- close jdk4 and then should be able to change isolation
@@ -151,9 +156,11 @@
-----
1 |1
ij> -- following should fail because of cursor jdk4
+-- no error in DerbyNetClient because cursor is closed on server
set isolation RS;
ERROR X0X03: Invalid transaction state - held cursor requires same isolation level
ij> -- following should fail because of cursor jdk4
+-- no error in DerbyNetClient because cursor is closed on server
set isolation UR;
ERROR X0X03: Invalid transaction state - held cursor requires same isolation level
ij> close jdk4;
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/procedure.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/procedure.out?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/procedure.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/procedure.out Mon Feb 13 04:44:07 2006
@@ -937,3 +937,4 @@
CALL LITT.TY_VARCHAR ('12.34', ?)=>12.34<
JIRA-491 Successful.
JIRA-492 successful -- no hang!
+testImplicitClose(): PASSED
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/forupdate.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/forupdate.out?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/forupdate.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/forupdate.out Mon Feb 13 04:44:07 2006
@@ -56,7 +56,7 @@
ij> -- the delete will get a 'cursor not updatable' execution error, but won't get
----- a compile time error
delete from t1 where current of c1;
-ERROR 42X23: Cursor SQL_CURLH000C1 is not updatable.
+ERROR 42X30: Cursor 'SQL_CURLH000C1' not found. Verify that autocommit is OFF.
ij> close c1;
ij> -- . read only for read only cursor spec
----- we know because the delete is refused with a 'cursor not updatable' message
@@ -121,18 +121,22 @@
ij> -- unions are not updatable
select * from t1 union all select * from t1 for update;
ERROR 42Y90: FOR UPDATE is not permitted in this type of statement.
+ij> insert into t1 (i) values (1);
+1 row inserted/updated/deleted
ij> -- . table with/without correlation name
----- the idea is that the delete is against the table name, not the correlation name
----- we've already seen the without correlation name case in previous tests
get cursor c4 as 'select i from t1 s1 for update';
ij> next c4;
-No current row
+I
+-----
+1
ij> -- this will get a target table mismatch error, it uses the correlation name:
delete from s1 where current of c4;
ERROR 42X28: Delete table 'S1' is not target of cursor 'SQL_CURLH000C1'.
-ij> -- this will compile and get a 'no current row' error, it uses the table name:
+ij> -- this will compile and succeed, it uses the table name:
delete from t1 where current of c4;
-ERROR XCL08: Cursor 'SQL_CURLH000C1' is not on a row.
+1 row inserted/updated/deleted
ij> close c4;
ij> -- . list columns in order same/different from appearance in table
----- the columns are 'found' regardless of their order.
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/holdCursorIJ.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/holdCursorIJ.out?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/holdCursorIJ.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/holdCursorIJ.out Mon Feb 13 04:44:07 2006
@@ -94,16 +94,19 @@
-----
1 |1
ij> -- wont' be able to drop table because of cursors jdk1 and jdk4
+-- in DerbyNetClient, cursor is closed on server and DROP TABLE succeeds
drop table t1;
-ERROR X0X95: Operation 'DROP TABLE' cannot be performed on object 'T1' because there is an open ResultSet dependent on that object.
+0 rows inserted/updated/deleted
ij> commit;
ij> -- drop table still won't work because jdk4 is still open after commit
+-- in DerbyNetClient, the table is already dropped
drop table t1;
-ERROR X0X95: Operation 'DROP TABLE' cannot be performed on object 'T1' because there is an open ResultSet dependent on that object.
+ERROR 42Y55: 'DROP TABLE' cannot be performed on 'T1' because it does not exist.
ij> -- close cursor jdk4 and try then deleting the table
+-- in DerbyNetClient, the table is already dropped
close jdk4;
ij> drop table t1;
-0 rows inserted/updated/deleted
+ERROR 42Y55: 'DROP TABLE' cannot be performed on 'T1' because it does not exist.
ij> -- clean up.
close jdk1;
ij> -- recreate and populate the table for next test
@@ -126,12 +129,14 @@
-----
1 |1
ij> -- try to change the isolation level. will give error because of jdk1 and jdk4
+-- no error in DerbyNetClient because cursor is closed on server
set current isolation RR;
-ERROR X0X03: Invalid transaction state - held cursor requires same isolation level
+0 rows inserted/updated/deleted
ij> commit;
ij> -- attempt to change isolation level should give error because of jdk4 hold cursor
+-- no error in DerbyNetClient because cursor is closed on server
set isolation = REPEATABLE READ;
-ERROR X0X03: Invalid transaction state - held cursor requires same isolation level
+0 rows inserted/updated/deleted
ij> -- close jdk4 and then should be able to change isolation
close jdk4;
ij> set isolation to serializable;
@@ -151,11 +156,13 @@
-----
1 |1
ij> -- following should fail because of cursor jdk4
+-- no error in DerbyNetClient because cursor is closed on server
set isolation RS;
-ERROR X0X03: Invalid transaction state - held cursor requires same isolation level
+0 rows inserted/updated/deleted
ij> -- following should fail because of cursor jdk4
+-- no error in DerbyNetClient because cursor is closed on server
set isolation UR;
-ERROR X0X03: Invalid transaction state - held cursor requires same isolation level
+0 rows inserted/updated/deleted
ij> close jdk4;
ij> -- should be able to change the isolation now
set isolation READ UNCOMMITTED;
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/holdCursorJava.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/holdCursorJava.out?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/holdCursorJava.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/holdCursorJava.out Mon Feb 13 04:44:07 2006
@@ -48,3 +48,4 @@
ERROR X0X03: Invalid transaction state - held cursor requires same isolation level
PASS: Can't change isolation if they are open cursor
Isolation level change test over
+testCloseCursor()
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk14/procedure.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk14/procedure.out?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk14/procedure.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk14/procedure.out Mon Feb 13 04:44:07 2006
@@ -939,3 +939,4 @@
MultipleRSNoCommit: PASS.
JIRA-491 Successful.
JIRA-492 successful -- no hang!
+testImplicitClose(): PASSED
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk14/updatableResultSet.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk14/updatableResultSet.out?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk14/updatableResultSet.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk14/updatableResultSet.out Mon Feb 13 04:44:07 2006
@@ -67,8 +67,8 @@
SQL State : null
Got expected exception Invalid operation to update at current cursor position
ResultSet is positioned after the last row. attempt to deleteRow at this point should fail!
-SQL State : XCL08
-Got expected exception Cursor '<xxx-cursor-name-xxx>' is not on a row.
+SQL State : XCL07
+Got expected exception Cursor '<xxx-cursor-name-xxx>' is closed. Verify that autocommit is OFF.
ResultSet is positioned after the last row. attempt to updateRow at this point should fail!
SQL State : null
Got expected exception Invalid operation to update at current cursor position
@@ -396,8 +396,8 @@
Positive Test13a - Another test case for delete trigger
column 1 on this row is 1
this delete row will fire the delete trigger which will delete all the rows from the table and from the resultset
-SQL State : XCL08
-Got expected exception Cursor '<xxx-cursor-name-xxx>' is not on a row.
+SQL State : XCL07
+Got expected exception Cursor '<xxx-cursor-name-xxx>' is closed. Verify that autocommit is OFF.
Verify that delete trigger got fired by verifying the row count to be 0 in table1WithTriggers
1
-
@@ -430,8 +430,8 @@
{e4,e3}
column 1 on this row is e1
this delete row will cause the delete cascade constraint to delete all the rows from the table and from the resultset
-SQL State : XCL08
-Got expected exception Cursor '<xxx-cursor-name-xxx>' is not on a row.
+SQL State : XCL07
+Got expected exception Cursor '<xxx-cursor-name-xxx>' is closed. Verify that autocommit is OFF.
Verify that delete trigger got fired by verifying the row count to be 0 in selfReferencingT1
1
-
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/procedure.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/procedure.out?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/procedure.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/procedure.out Mon Feb 13 04:44:07 2006
@@ -939,3 +939,4 @@
MultipleRSNoCommit: PASS.
JIRA-491 Successful.
JIRA-492 successful -- no hang!
+testImplicitClose(): PASSED
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/updatableResultSet.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/updatableResultSet.out?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/updatableResultSet.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/updatableResultSet.out Mon Feb 13 04:44:07 2006
@@ -67,8 +67,8 @@
SQL State : null
Got expected exception Invalid operation to update at current cursor position
ResultSet is positioned after the last row. attempt to deleteRow at this point should fail!
-SQL State : XCL08
-Got expected exception Cursor '<xxx-cursor-name-xxx>' is not on a row.
+SQL State : XCL07
+Got expected exception Cursor '<xxx-cursor-name-xxx>' is closed. Verify that autocommit is OFF.
ResultSet is positioned after the last row. attempt to updateRow at this point should fail!
SQL State : null
Got expected exception Invalid operation to update at current cursor position
@@ -396,8 +396,8 @@
Positive Test13a - Another test case for delete trigger
column 1 on this row is 1
this delete row will fire the delete trigger which will delete all the rows from the table and from the resultset
-SQL State : XCL08
-Got expected exception Cursor '<xxx-cursor-name-xxx>' is not on a row.
+SQL State : XCL07
+Got expected exception Cursor '<xxx-cursor-name-xxx>' is closed. Verify that autocommit is OFF.
Verify that delete trigger got fired by verifying the row count to be 0 in table1WithTriggers
1
-
@@ -430,8 +430,8 @@
{e4,e3}
column 1 on this row is e1
this delete row will cause the delete cascade constraint to delete all the rows from the table and from the resultset
-SQL State : XCL08
-Got expected exception Cursor '<xxx-cursor-name-xxx>' is not on a row.
+SQL State : XCL07
+Got expected exception Cursor '<xxx-cursor-name-xxx>' is closed. Verify that autocommit is OFF.
Verify that delete trigger got fired by verifying the row count to be 0 in selfReferencingT1
1
-
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/forupdate.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/forupdate.out?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/forupdate.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/forupdate.out Mon Feb 13 04:44:07 2006
@@ -121,18 +121,22 @@
ij> -- unions are not updatable
select * from t1 union all select * from t1 for update;
ERROR 42Y90: FOR UPDATE is not permitted in this type of statement.
+ij> insert into t1 (i) values (1);
+1 row inserted/updated/deleted
ij> -- . table with/without correlation name
-- the idea is that the delete is against the table name, not the correlation name
-- we've already seen the without correlation name case in previous tests
get cursor c4 as 'select i from t1 s1 for update';
ij> next c4;
-No current row
+I
+-----------
+1
ij> -- this will get a target table mismatch error, it uses the correlation name:
delete from s1 where current of c4;
ERROR 42X28: Delete table 'S1' is not target of cursor 'C4'.
-ij> -- this will compile and get a 'no current row' error, it uses the table name:
+ij> -- this will compile and succeed, it uses the table name:
delete from t1 where current of c4;
-ERROR XCL08: Cursor 'C4' is not on a row.
+1 row inserted/updated/deleted
ij> close c4;
ij> -- . list columns in order same/different from appearance in table
-- the columns are 'found' regardless of their order.
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/holdCursorIJ.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/holdCursorIJ.out?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/holdCursorIJ.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/holdCursorIJ.out Mon Feb 13 04:44:07 2006
@@ -94,13 +94,16 @@
-----------------------
1 |1
ij> -- wont' be able to drop table because of cursors jdk1 and jdk4
+-- in DerbyNetClient, cursor is closed on server and DROP TABLE succeeds
drop table t1;
ERROR X0X95: Operation 'DROP TABLE' cannot be performed on object 'T1' because there is an open ResultSet dependent on that object.
ij> commit;
ij> -- drop table still won't work because jdk4 is still open after commit
+-- in DerbyNetClient, the table is already dropped
drop table t1;
ERROR X0X95: Operation 'DROP TABLE' cannot be performed on object 'T1' because there is an open ResultSet dependent on that object.
ij> -- close cursor jdk4 and try then deleting the table
+-- in DerbyNetClient, the table is already dropped
close jdk4;
ij> drop table t1;
0 rows inserted/updated/deleted
@@ -126,10 +129,12 @@
-----------------------
1 |1
ij> -- try to change the isolation level. will give error because of jdk1 and jdk4
+-- no error in DerbyNetClient because cursor is closed on server
set current isolation RR;
ERROR X0X03: Invalid transaction state - held cursor requires same isolation level
ij> commit;
ij> -- attempt to change isolation level should give error because of jdk4 hold cursor
+-- no error in DerbyNetClient because cursor is closed on server
set isolation = REPEATABLE READ;
ERROR X0X03: Invalid transaction state - held cursor requires same isolation level
ij> -- close jdk4 and then should be able to change isolation
@@ -151,9 +156,11 @@
-----------------------
1 |1
ij> -- following should fail because of cursor jdk4
+-- no error in DerbyNetClient because cursor is closed on server
set isolation RS;
ERROR X0X03: Invalid transaction state - held cursor requires same isolation level
ij> -- following should fail because of cursor jdk4
+-- no error in DerbyNetClient because cursor is closed on server
set isolation UR;
ERROR X0X03: Invalid transaction state - held cursor requires same isolation level
ij> close jdk4;
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/holdCursorJava.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/holdCursorJava.out?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/holdCursorJava.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/holdCursorJava.out Mon Feb 13 04:44:07 2006
@@ -48,3 +48,4 @@
ERROR X0X03: Invalid transaction state - held cursor requires same isolation level
PASS: Can't change isolation if they are open cursor
Isolation level change test over
+testCloseCursor()
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/j9_foundation/holdCursorJava.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/j9_foundation/holdCursorJava.out?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/j9_foundation/holdCursorJava.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/j9_foundation/holdCursorJava.out Mon Feb 13 04:44:07 2006
@@ -10,3 +10,4 @@
ERROR X0X03: Invalid transaction state - held cursor requires same isolation level
PASS: Can't change isolation if they are open cursor
Isolation level change test over
+testCloseCursor()
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/procedure.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/procedure.out?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/procedure.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/procedure.out Mon Feb 13 04:44:07 2006
@@ -1015,3 +1015,4 @@
MultipleRSNoCommit: PASS.
JIRA-491 Successful.
JIRA-492 successful -- no hang!
+testImplicitClose(): PASSED
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/testProtocol.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/testProtocol.out?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/testProtocol.out (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/testProtocol.out Mon Feb 13 04:44:07 2006
@@ -289,3 +289,5 @@
Test for missing SQLSTT in EXCSQLSET - PKGNAMCT is ignored
PASSED
PASSED
+Test explicitly closing implicitly closed cursor
+PASSED
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/protocol.tests
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/protocol.tests?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/protocol.tests (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/protocol.tests Mon Feb 13 04:44:07 2006
@@ -3186,5 +3186,101 @@
skipDss // ENDUOWRM
skipDss //SQLCARD for commit
endTest
+//
+DISPLAY "Test explicitly closing implicitly closed cursor"
+include connect.inc
+// prepare statement
+createDssRequest
+startDdm PRPSQLSTT
+startDdm PKGNAMCSN
+writePaddedString "test" 18
+writePaddedString "rdbcolid" 18
+writePaddedString "pkgid" 18
+writeBytes "0x0101010101010101"
+writeShort 1
+endDdm
+endDdm
+endDss
+createDssObject
+startDdm SQLSTT
+writeByte 0 // null indicator
+writeEncodedLDString "values(1)" "UTF-8" 4
+writeByte 255 // null indicator
+endDdm
+endDss
+flush
+checkSQLCard 0 " "
+// execute query
+createDssRequest
+startDdm OPNQRY
+startDdm PKGNAMCSN
+writePaddedString "test" 18
+writePaddedString "rdbcolid" 18
+writePaddedString "pkgid" 18
+writeBytes "0x0101010101010101"
+writeShort 1
+endDdm
+writeScalar1Byte QRYCLSIMP 1
+startDdm QRYBLKSZ
+writeInt 32767
+endDdm
+writeScalar2Bytes QRYBLKCTL FRCFIXROW
+endDdm
+endDss
+flush
+readReplyDss
+readLengthAndCodepoint OPNQRYRM
+skipBytes
+readReplyDss
+readLengthAndCodepoint QRYDSC
+skipBytes
+// fetch data
+createDssRequest
+startDdm CNTQRY
+startDdm PKGNAMCSN
+writePaddedString "test" 18
+writePaddedString "rdbcolid" 18
+writePaddedString "pkgid" 18
+writeBytes "0x0101010101010101"
+writeShort 1
+endDdm
+startDdm QRYBLKSZ
+writeInt 32767
+endDdm
+startDdm QRYINSID
+writeInt 0
+writeInt 1
+endDdm
+endDdm
+endDss
+flush
+readReplyDss
+readLengthAndCodepoint QRYDTA
+skipBytes
+// all rows are fetched, cursor is implicitly closed on server
+// close result set explicitly
+createDssRequest
+startDdm CLSQRY
+startDdm PKGNAMCSN
+writePaddedString "test" 18
+writePaddedString "rdbcolid" 18
+writePaddedString "pkgid" 18
+writeBytes "0x0101010101010101"
+writeShort 1
+endDdm
+startDdm QRYINSID
+writeInt 0
+writeInt 1
+endDdm
+endDdm
+endDss
+flush
+// DRDA says QRYNOPRM is to be expected here
+//readReplyDss
+//readLengthAndCodepoint QRYNOPRM
+// but JCC expects SQLCARD and we're nice guys...
+checkSQLCard 0 " "
+endTest
+//
completeTest
//
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/setTransactionIsolation.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/setTransactionIsolation.java?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/setTransactionIsolation.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/setTransactionIsolation.java Mon Feb 13 04:44:07 2006
@@ -83,9 +83,27 @@
System.out.println("Creating table...");
- stmt.executeUpdate( "CREATE TABLE TAB1 (c11 int, c12 int)" );
- stmt.executeUpdate("INSERT INTO TAB1 VALUES(1,1)");
- stmt.executeUpdate("INSERT INTO TAB1 VALUES(2,1)");
+ final int stringLength = 400;
+ stmt.executeUpdate("CREATE TABLE TAB1 (c11 int, " +
+ "c12 varchar(" + stringLength + "))");
+ PreparedStatement insertStmt =
+ conn.prepareStatement("INSERT INTO TAB1 VALUES(?,?)");
+ // We need to ensure that there is more data in the table than the
+ // client can fetch in one message (about 32K). Otherwise, the
+ // cursor might be closed on the server and we are not testing the
+ // same thing in embedded mode and client/server mode.
+ final int rows = 40000 / stringLength;
+ StringBuffer buff = new StringBuffer(stringLength);
+ for (int i = 0; i < stringLength; i++) {
+ buff.append(" ");
+ }
+ for (int i = 1; i <= rows; i++) {
+ insertStmt.setInt(1, i);
+ insertStmt.setString(2, buff.toString());
+ insertStmt.executeUpdate();
+ }
+ insertStmt.close();
+
stmt.execute("create table t1(I int, B char(15))");
stmt.execute("create table t1copy(I int, B char(15))");
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/forupdate.sql
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/forupdate.sql?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/forupdate.sql (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/forupdate.sql Mon Feb 13 04:44:07 2006
@@ -105,6 +105,7 @@
-- unions are not updatable
select * from t1 union all select * from t1 for update;
+insert into t1 (i) values (1);
-- . table with/without correlation name
-- the idea is that the delete is against the table name, not the correlation name
-- we've already seen the without correlation name case in previous tests
@@ -112,7 +113,7 @@
next c4;
-- this will get a target table mismatch error, it uses the correlation name:
delete from s1 where current of c4;
--- this will compile and get a 'no current row' error, it uses the table name:
+-- this will compile and succeed, it uses the table name:
delete from t1 where current of c4;
close c4;
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/holdCursorIJ.sql
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/holdCursorIJ.sql?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/holdCursorIJ.sql (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/holdCursorIJ.sql Mon Feb 13 04:44:07 2006
@@ -73,13 +73,16 @@
next jdk1;
next jdk4;
-- wont' be able to drop table because of cursors jdk1 and jdk4
+-- in DerbyNetClient, cursor is closed on server and DROP TABLE succeeds
drop table t1;
commit;
-- drop table still won't work because jdk4 is still open after commit
+-- in DerbyNetClient, the table is already dropped
drop table t1;
-- close cursor jdk4 and try then deleting the table
+-- in DerbyNetClient, the table is already dropped
close jdk4;
drop table t1;
@@ -99,11 +102,13 @@
next jdk4;
-- try to change the isolation level. will give error because of jdk1 and jdk4
+-- no error in DerbyNetClient because cursor is closed on server
set current isolation RR;
commit;
-- attempt to change isolation level should give error because of jdk4 hold cursor
+-- no error in DerbyNetClient because cursor is closed on server
set isolation = REPEATABLE READ;
-- close jdk4 and then should be able to change isolation
@@ -120,8 +125,10 @@
next jdk4;
next jdk1;
-- following should fail because of cursor jdk4
+-- no error in DerbyNetClient because cursor is closed on server
set isolation RS;
-- following should fail because of cursor jdk4
+-- no error in DerbyNetClient because cursor is closed on server
set isolation UR;
close jdk4;
-- should be able to change the isolation now
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/holdCursorJava.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/holdCursorJava.java?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/holdCursorJava.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/holdCursorJava.java Mon Feb 13 04:44:07 2006
@@ -76,6 +76,8 @@
testHoldCursorOnMultiTableQuery(conn);
testIsolationLevelChange(conn);
+ testCloseCursor(conn);
+ testDropTable(conn);
conn.rollback();
conn.setAutoCommit(true);
@@ -100,9 +102,26 @@
TestUtil.cleanUpTest(stmt, databaseObjects);
System.out.println("Creating table...");
- stmt.executeUpdate( "CREATE TABLE T1 (c11 int, c12 int)" );
- stmt.executeUpdate("INSERT INTO T1 VALUES(1,1)");
- stmt.executeUpdate("INSERT INTO T1 VALUES(2,1)");
+ final int stringLength = 400;
+ stmt.executeUpdate("CREATE TABLE T1 (c11 int, c12 int, junk varchar(" +
+ stringLength + "))");
+ PreparedStatement insertStmt =
+ conn.prepareStatement("INSERT INTO T1 VALUES(?,1,?)");
+ // We need to ensure that there is more data in the table than the
+ // client can fetch in one message (about 32K). Otherwise, the
+ // cursor might be closed on the server and we are not testing the
+ // same thing in embedded mode and client/server mode.
+ final int rows = 40000 / stringLength;
+ StringBuffer buff = new StringBuffer(stringLength);
+ for (int i = 0; i < stringLength; i++) {
+ buff.append(" ");
+ }
+ for (int i = 1; i <= rows; i++) {
+ insertStmt.setInt(1, i);
+ insertStmt.setString(2, buff.toString());
+ insertStmt.executeUpdate();
+ }
+ insertStmt.close();
stmt.executeUpdate( "CREATE TABLE T2 (c21 int, c22 int)" );
stmt.executeUpdate("INSERT INTO T2 VALUES(1,1)");
stmt.executeUpdate("INSERT INTO T2 VALUES(1,2)");
@@ -242,6 +261,56 @@
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
}
+ /**
+ * Test that drop table cannot be performed when there is an open
+ * cursor on that table.
+ *
+ * @param conn a <code>Connection</code> object
+ * @exception SQLException if an error occurs
+ */
+ private static void testDropTable(Connection conn) throws SQLException {
+ conn.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
+ final String dropTable = "DROP TABLE T1";
+ Statement stmt1 = conn.createStatement();
+ Statement stmt2 = conn.createStatement();
+ ResultSet rs = stmt1.executeQuery("SELECT * FROM T1");
+ rs.next();
+
+ // dropping t1 should fail because there is an open cursor on t1
+ boolean ok = false;
+ try {
+ stmt2.executeUpdate(dropTable);
+ } catch (SQLException sqle) {
+ ok = true;
+ }
+ if (!ok) {
+ System.out.println("FAIL: Expected DROP TABLE to fail " +
+ "because of open cursor.");
+ }
+
+ conn.commit();
+
+ // cursors are held over commit, so dropping should still fail
+ ok = false;
+ try {
+ stmt2.executeUpdate(dropTable);
+ } catch (SQLException sqle) {
+ ok = true;
+ }
+ if (!ok) {
+ System.out.println("FAIL: Expected DROP TABLE to fail " +
+ "because of held cursor.");
+ }
+
+ rs.close();
+
+ // cursor is closed, so this one should succeed
+ stmt2.executeUpdate(dropTable);
+ stmt1.close();
+ stmt2.close();
+ conn.rollback();
+ }
+
//set connection holdability and test holdability of statements inside and outside procedures
//test that holdability of statements always overrides holdability of connection
private static void testHoldability(Connection conn,int holdability) throws SQLException{
@@ -303,6 +372,36 @@
cs1.close();
cs2.close();
+ }
+
+ // DERBY-821: Test that cursors are closed when close() is
+ // called. Since the network server implicitly closes a
+ // forward-only result set when all rows are read, the call to
+ // close() might be a no-op.
+ private static void testCloseCursor(Connection conn)
+ throws SQLException
+ {
+ System.out.println("\ntestCloseCursor()\n");
+ // Run this test on one large table (T1) where the network
+ // server won't close the cursor implicitly, and on one small
+ // table (T2) where the network server will close the cursor
+ // implicitly.
+ final String[] tables = { "T1", "T2" };
+ Statement stmt1 = conn.createStatement();
+ Statement stmt2 = conn.createStatement();
+ for (int i = 0; i < tables.length; i++) {
+ String table = tables[i];
+ ResultSet rs = stmt1.executeQuery("SELECT * FROM " + table);
+ rs.next();
+ rs.close();
+ // Cursor is closed, so this should succeed. If the cursor
+ // is open, it will fail because an table cannot be
+ // dropped when there are open cursors depending on it.
+ stmt2.executeUpdate("DROP TABLE " + table);
+ }
+ stmt1.close();
+ stmt2.close();
+ conn.rollback();
}
//check if resultset is accessible
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=377367&r1=377366&r2=377367&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 Mon Feb 13 04:44:07 2006
@@ -88,6 +88,7 @@
multipleRSTests(conn);
jira_491_492(conn);
+ testImplicitClose(conn);
cleanUp(conn);
} catch (SQLException sqle) {
org.apache.derby.tools.JDBCDisplayUtil.ShowSQLException(System.out, sqle);
@@ -1818,8 +1819,49 @@
cs.close();
}
-
-
+ // DERBY-821: Test that the result set is not implicitly closed on
+ // the server when EXCSQLSTT is used to open the result set.
+ private static void testImplicitClose(Connection conn) throws SQLException {
+ System.out.print("testImplicitClose(): ");
+ final String proc =
+ "org.apache.derbyTesting.functionTests.util.ProcedureTest." +
+ "selectRows";
+ boolean savedAutoCommit = conn.getAutoCommit();
+ conn.setAutoCommit(false);
+ Statement stmt = conn.createStatement();
+ stmt.executeUpdate("create table derby821 (id int)");
+ stmt.executeUpdate("insert into derby821 (id) values (1), (2)");
+ stmt.execute("create procedure jira821 (name varchar(50)) " +
+ "parameter style java language java external name " +
+ "'" + proc + "' dynamic result sets 1 reads sql data");
+ CallableStatement cs = conn.prepareCall("call jira821 (?)");
+ cs.setString(1, "derby821");
+ cs.execute();
+ ResultSet rs = cs.getResultSet();
+ rs.next();
+ boolean passed = false;
+ try {
+ // We expect the result set to be open, so dropping the
+ // table should fail.
+ stmt.executeUpdate("drop table derby821");
+ } catch (SQLException sqle) {
+ if (sqle.getSQLState().equals("X0X95")) {
+ System.out.println("PASSED");
+ passed = true;
+ } else {
+ System.out.println("FAILED");
+ throw sqle;
+ }
+ }
+ if (!passed) {
+ // Table was successfully dropped, hence the result set
+ // must have been implicitly closed.
+ System.out.println("FAILED (no exception thrown)");
+ }
+ conn.rollback();
+ conn.setAutoCommit(savedAutoCommit);
+ }
+
/**
* 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
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/ProcedureTest.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/ProcedureTest.java?rev=377367&r1=377366&r2=377367&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/ProcedureTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/util/ProcedureTest.java Mon Feb 13 04:44:07 2006
@@ -192,6 +192,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");