Issue Details (XML | Word | Printable)

Key: DERBY-3304
Type: Bug Bug
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Mamta A. Satoor
Reporter: Daniel John Debrunner
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Derby

Explicit commit inside a java procedure makes a dynamic result sets passed out unavailable

Created: 08/Jan/08 04:26 PM   Updated: 30/Jun/09 03:55 PM
Return to search
Component/s: JDBC
Affects Version/s: 10.4.1.3
Fix Version/s: 10.3.3.0, 10.4.1.3

Time Tracking:
Not Specified

File Attachments:
  Size
Java Source File Licensed for inclusion in ASF works Main.java 2008-01-08 04:26 PM Daniel John Debrunner 3 kB

Bug behavior facts: Regression
Resolution Date: 06/Mar/08 05:18 PM


 Description  « Hide
Repro (Main.java) that shows changed behavior after svn 602991
(the patch committed for this issue). It seems a regression: (originally from Dag H. Wanvik attached to DERBY-1585)

An explicit commit inside a stored procedure makes a dynamic result sets passed out unavailable, even if the commit is executed *prior* to the result set; as in the repro.

 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Repository Revision Date User Message
ASF #614292 Tue Jan 22 19:29:50 UTC 2008 mamta Adding a junit test for the standalone test case provided by Dag for DERBY-3304. Here, we
are adding a Java procedure which does a commit and then returns a resultset back to the
caller. The resultset should not get closed as part of the commit.
Files Changed
MODIFY /db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangProcedureTest.java

Repository Revision Date User Message
ASF #614298 Tue Jan 22 19:46:05 UTC 2008 mamta Migrating revision 614292 from trunk into 10.3 codeline. This just adds a junit test case
for DERBY-3304. The commit comments for 614292 were as follows

Adding a junit test for the standalone test case provided by Dag for DERBY-3304. Here, we
are adding a Java procedure which does a commit and then returns a resultset back to the
caller. The resultset should not get closed as part of the commit.
Files Changed
MODIFY /db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangProcedureTest.java

Repository Revision Date User Message
ASF #618788 Tue Feb 05 21:50:16 UTC 2008 mamta DERBY-3304

This commit addresses two issues.

First of all, it cleanups up reset method in BaseActivation which was doing more than just bringing the Activation back
to pre-execution state. The method had to make itself aware of holdability and what
kind of resultset it was dealing with
before closing or clearing the row of the resultset. The reason for this behavior
is commit code path was relying on
Activation.reset to do more than just bringing the activation to pre-execution state.
 I fixed this by moving this code
from BaseActivation.reset to GenericLanguageConnectionContext.resetActivations.



Additionally, in the new code in GenericLanguageConnectionContext.resetActivations, I added the code to not close the

language result sets associated with activations that do not return rows even if activation may have holdability set to

false. This will ensure that a commit inside a java procedure will not inadvertantly close the resultset associated with

the java procedure call.

 Additionally, I copied some of the cleanup work(as shown below) from BaseActivation.reset into
new code in GenericLanguageConnectionContext.resetActivations
   a.clearHeapConglomerateController();
   if (!a.isSingleExecution())
      a.clearWarnings();

This code above was always getting executed at the time of commit before my commit and because of that, I decided to copy
it in GenericLanguageConnectionContext.resetActivations. If anyone has any comments on this, please let me know.

(Andrew trying to change commit message for Mamta)
Files Changed
MODIFY /db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
MODIFY /db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java

Repository Revision Date User Message
ASF #619279 Thu Feb 07 05:48:54 UTC 2008 mamta DERBY-3304

This is a followup commit for DERBY-3304 based on various comments. It does following
1)The existing method resetActivations in GenericLanguageConnectionContext has been renamed to better reflect it's
functionality. It will be now called endTransactionActivationHandling since it gets called for commit/rollback.
2)The javadoc comments for resetActivations(now called endTransactionActivationHandling) were not valid. Fixed that in
this commit.
3)Took out the redundant code about setting the holdability to false if we were in rollback. It was needed earlier
because the method that took care of activations at rollback time needed to check the holdability. That method
(BaseActivation.reset) does not check holdability anymore and hence we do not need to set the activations to false
holdability when we are dealing with rollback.
4)Lastly, JDBC api for Connection.commit does not ask for clearing of warnings and hence we should not have code to
clear the warnings at the time of commit. I removed the warning clearing code from resetActivations(now called
endTransactionActivationHandling) in GenericLanguageConnectionContext.
Files Changed
MODIFY /db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java

Repository Revision Date User Message
ASF #619772 Fri Feb 08 05:42:05 UTC 2008 mamta DERBY-3304

Some code cleanup in GenericLanguageConnectionContext.endTransactionActivationHandling so the code is more readable.
No functionality change, just consolidated various if statements and used some local variables to replace repeated
method calls like a.getResultSet() and a.getResultSet().returnsRows()
Files Changed
MODIFY /db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java

Repository Revision Date User Message
ASF #619958 Fri Feb 08 17:57:22 UTC 2008 mamta Merging changes 618788, 619279 and 619772 into 10.3 codeline for DERBY-3304.

For reference, copying the commit comments for each of these revisions that are getting merged into 10.3 codeline

*********commit comments for 619772****************
DERBY-3304
Some code cleanup in GenericLanguageConnectionContext.endTransactionActivationHandling so the code is more readable.
No functionality change, just consolidated various if statements and used some local variables to replace repeated
method calls like a.getResultSet() and a.getResultSet().returnsRows()
*********end of commit comments for 619772*********


*********commit comments for 619279****************
This is a followup commit for DERBY-3304 based on various comments. It does following
1)The existing method resetActivations in GenericLanguageConnectionContext has been renamed to better reflect it's
functionality. It will be now called endTransactionActivationHandling since it gets called for commit/rollback.
2)The javadoc comments for resetActivations(now called endTransactionActivationHandling) were not valid. Fixed that in
this commit.
3)Took out the redundant code about setting the holdability to false if we were in rollback. It was needed earlier
because the method that took care of activations at rollback time needed to check the holdability. That method
(BaseActivation.reset) does not check holdability anymore and hence we do not need to set the activations to false
holdability when we are dealing with rollback.
4)Lastly, JDBC api for Connection.commit does not ask for clearing of warnings and hence we should not have code to
clear the warnings at the time of commit. I removed the warning clearing code from resetActivations(now called
endTransactionActivationHandling) in GenericLanguageConnectionContext.
*********end of commit comments for 619279*********


*********commit comments for 618788****************
DERBY-3304
This commit addresses two issues.
First of all, it cleanups up reset method in BaseActivation which was doing more than just bringing the Activation back
to pre-execution state. The method had to make itself aware of holdability and what kind of resultset it was dealing with
before closing or clearing the row of the resultset. The reason for this behavior is commit code path was relying on
Activation.reset to do more than just bringing the activation to pre-execution state. I fixed this by moving this code
from BaseActivation.reset to GenericLanguageConnectionContext.resetActivations.

Additionally, in the new code in GenericLanguageConnectionContext.resetActivations, I added the code to not close the
language result sets associated with activations that do not return rows even if activation may have holdability set to
false. This will ensure that a commit inside a java procedure will not inadvertantly close the resultset associated with
the java procedure call.

Additionally, I copied some of the cleanup work(as shown below) from BaseActivation.reset into
new code in GenericLanguageConnectionContext.resetActivations
   a.clearHeapConglomerateController();
   if (!a.isSingleExecution())
      a.clearWarnings();

This code above was always getting executed at the time of commit before my commit and because of that, I decided to copy
it in GenericLanguageConnectionContext.resetActivations. If anyone has any comments on this, please let me know.
*********end of commit comments for 618788*********
Files Changed
MODIFY /db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
MODIFY /db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/execute/BaseActivation.java

Repository Revision Date User Message
ASF #627673 Thu Feb 14 06:24:50 UTC 2008 mamta DERBY-3304 and DERBY-3414

This serves as a test case for both the jira entries above.

Number of code changes for transaction ending time went in as part of DERBY-3304 and this
new test will check those code changes for specific case of rollback inside a java procedure
call.

The test case is currently disabled for network server because the rollback inside the
procedure is not closing all the resultsets and DERBY-3414 is to track this behavior of
network server. Once DERBY-3414 is fixed, we should enable the test for network server.
Files Changed
MODIFY /db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangProcedureTest.java

Repository Revision Date User Message
ASF #627674 Thu Feb 14 06:28:43 UTC 2008 mamta Merging revision 627673 from trunk into 10.3 codeline. The commit comments for 627673 were
as follows

DERBY-3304 and DERBY-3414

This serves as a test case for both the jira entries above.

Number of code changes for transaction ending time went in as part of DERBY-3304 and this
new test will check those code changes for specific case of rollback inside a java procedure
call.

The test case is currently disabled for network server because the rollback inside the
procedure is not closing all the resultsets and DERBY-3414 is to track this behavior of
network server. Once DERBY-3414 is fixed, we should enable the test for network server.
Files Changed
MODIFY /db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangProcedureTest.java

Repository Revision Date User Message
ASF #628130 Fri Feb 15 17:36:50 UTC 2008 mamta DERBY-3304
DERBY-3037
DERBY-1585

I am adding a test case to check for the resultset from the java procedure call when the
java procedure has done a rollback inside it. This test shows that in trunk, after checkin
602991 for DERBY-1585, a procedure does not return a resultset if there was a rollbck
inside the procedure with resultset creation before rollback. This behavior is different
than what happens in 10.2 codeline. In 10.2, a procedure will return a *closed* resultset
if there was a rollback inside the procedure. But a procedure should not return closed
result sets, so it appears that trunk is behaving correctly and 10.2's behavior was
incorrect.
Files Changed
MODIFY /db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/JDBC.java
MODIFY /db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangProcedureTest.java

Repository Revision Date User Message
ASF #629926 Thu Feb 21 18:47:17 UTC 2008 mamta DERBY-3304

The main purpose of this patch is to fix the rollback handling for resultsets that do not
return rows. An example case for this is a java procedure which has a Connection.rollback
inside it. When the user calls the java procedure, and Connection.rollback is made inside
of it, Derby should not be closing the resultset assoicated with the java procedure call
(that resultset is a CallStatementResultSet). In other words, a user initiated rollback
through JDBC Connection object should leave the resultsets that do not return rows open. In
order to implement this, I had to make changes to ignore resultsets that do not return rows
in
GenericLanguageConnectionContext.endTransactionActivationHandling. As a result of this
change, for the eg case given above, the activation assoicated with the java procedure
will not be reset (which also means that, CallStatementResultSet.close will not be called)
inside GenericLanguageConnectionContext.endTransactionActivationHandling.

But the code inside CallStatementResultset.close() took care of the closed dynamic resultset
and it took out the closed dynamic resultset from the list of resultsets that would be
available to user through the Statement.getResultSet api. With my changes through this
patch, we are going to skip the CallStatementResultset.close during
GenericLanguageConnectionContext.endTransactionActivationHandling which means that we have
to deal with those closed dynamic resultsets on our own. I did that part of logic
changes in EmbedStatement.processDynamicResults

EmbedStatement.processDynamicResults used to check if the JDBC Resultset is closed by
directly checking the field isClosed in the EmbedResultSet. But it is not sufficient to
check only JDBC Resultset. We need to check the underlying language Resultset too to
determine if the dynamic resultset is closed. There is no direct api on EmbedResultset
which will return a boolean after checking the JDBC Resultset and language Resulset. Instead,
there is a method called EmbedResultSet.checkIfClosed. This method will throw an exception
if it finds the JDBC ResultSet or language ResultSet closed. So, my changes in
EmbedStatement.processDynamicResults make a call to EmbedResultSet.checkIfClosed and if
there is an exception thrown, then we know that the resultset is closed and hence we should
move to the next resultset.

In addition to these code changes, I have added a new test to LangProcedureTest. The new
java procedure is defined to return 2 dynamic resultsets. One of these resultsets is
created before Connection.rollback inside the java procedure. The other dynamic resultset
is created after Connection.rollback. As as result of Connection.rollback, the first
dynamic resultset will be closed but the second one will remain open. The test makes sure
that only one dynamic resultset is returned by the java procedure.

Also, made one minor change in LangProcedureTest for an existing test. The test at line 804
was getting a resultset from the Statement object without asserting that there are no more
resultsets. The resultset object would have been null anyways in this test because there
are no open resulsets from the Java procedure. Because of this, I took out the redundant
code of getting null resultset object from Statement using getResultset,
Files Changed
MODIFY /db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
MODIFY /db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java
MODIFY /db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangProcedureTest.java

Repository Revision Date User Message
ASF #630941 Mon Feb 25 17:22:58 UTC 2008 mamta Merging revision 629395 from trunk into 10.3 codeline. The reason for merge is I would like
to merge changes for DERBY-3304 (629926) into trunk but that revision depends on
DERBY-3404 (629712) which depends on DERBY-3422 (629395)

The commit comments for 629395 were as follows

DERBY-3422: Embedded returns wrong value for DatabaseMetaData.autoCommitFailureClosesAllResultSets()

Return the correct value (true) and update the test so that it is able
to detect differences between returned value and actual behaviour.
Files Changed
MODIFY /db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedDatabaseMetaData40.java
MODIFY /db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/TestDbMetaData.java

Repository Revision Date User Message
ASF #631108 Tue Feb 26 07:26:25 UTC 2008 mamta DERBY-3304

When a SQL exception is thrown, make sure that rollback caused by it closes all the resultsets
irrespective of whether they return rows or not. This cleanup was not happening for
CallableStatementResultSet. To fix this, in CallableStatementResultSet class, I have changed
the no-op cleanup() method to call close(). Without this, the locks held by the resultsets
created inside the Java procedure method were not getting released.

I have added a test case to make sure that this code change is tested. I have created a
Java procedure which creates a dynamic resultset, a local resultset and then does an
insert which will cause duplicate key exception. As part of rollback for exception, Derby
closes the dynamic resultset and local resultset along with the CallableStatementResultset.
And the test case is able to drop the tables which were used by the dynamic and local
resultset without running into locking issues.
Files Changed
MODIFY /db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/CallStatementResultSet.java
MODIFY /db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangProcedureTest.java

Repository Revision Date User Message
ASF #631302 Tue Feb 26 17:15:59 UTC 2008 mamta Merging revision 631108 from trunk into 10.3 codeline. In addition, adding method
assertNoMoreResults in junit/JDBC.java since it is used by the test which is getting merged
through 631108.

The commit comments for 631108
were as follows
DERBY-3304

When a SQL exception is thrown, make sure that rollback caused by it closes all the resultsets
irrespective of whether they return rows or not. This cleanup was not happening for
CallableStatementResultSet. To fix this, in CallableStatementResultSet class, I have changed
the no-op cleanup() method to call close(). Without this, the locks held by the resultsets
created inside the Java procedure method were not getting released.

I have added a test case to make sure that this code change is tested. I have created a
Java procedure which creates a dynamic resultset, a local resultset and then does an
insert which will cause duplicate key exception. As part of rollback for exception, Derby
closes the dynamic resultset and local resultset along with the CallableStatementResultset.
And the test case is able to drop the tables which were used by the dynamic and local
resultset without running into locking issues.
Files Changed
MODIFY /db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/execute/CallStatementResultSet.java
MODIFY /db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/junit/JDBC.java
MODIFY /db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangProcedureTest.java

Repository Revision Date User Message
ASF #631307 Tue Feb 26 17:25:05 UTC 2008 mamta Fixing the typo in the tests where I was referncing the incorrect jira entry. These tests
were added for DERBY-3304
Files Changed
MODIFY /db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangProcedureTest.java

Repository Revision Date User Message
ASF #631311 Tue Feb 26 17:33:57 UTC 2008 mamta Fixing the typo in the comments in the tests where I was referncing the incorrect jira entry.
These tests were added for DERBY-3304
Files Changed
MODIFY /db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangProcedureTest.java

Repository Revision Date User Message
ASF #631481 Wed Feb 27 04:51:47 UTC 2008 mamta Checking in code cleanup for DERBY-3304. This code cleanup is based on Knut's review of my
earlier commit 629926. No functionality has changed, but code will be now much easier to
read.
Files Changed
MODIFY /db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java

Repository Revision Date User Message
ASF #633778 Wed Mar 05 06:03:22 UTC 2008 mamta I am backporting quite a few checkins from trunk into 10.3 codeline for DERBY-3304 and
DERBY-3404.

The main functionality that is getting ported is when a user initiates a rollback through
JDBC Connection object, the rollback should not close the resultsets that do not return
rows.

This functionality was checked in into trunk through multiple checkins for DERBY-3304 and
those checkins are 628130, 629926, 631481. In addition, there was a supporting checkin into
trunk by Knut for DERBY-3404 (revision 629712) on which the 3 checkins listed earlier rely.
I am backporting all of these 4 checkins from trunk into 10.3 codeline.

The tests have run fine with no new regression.

I am including checkin comments for all these revisions for easy reference here.
**********checkin comments for 628130)**************
DERBY-3304
DERBY-3037
DERBY-1585

I am adding a test case to check for the resultset from the java procedure call when the
java procedure has done a rollback inside it. This test shows that in trunk, after checkin
602991 for DERBY-1585, a procedure does not return a resultset if there was a rollbck
inside the procedure with resultset creation before rollback. This behavior is different
than what happens in 10.2 codeline. In 10.2, a procedure will return a *closed* resultset
if there was a rollback inside the procedure. But a procedure should not return closed
result sets, so it appears that trunk is behaving correctly and 10.2's behavior was
incorrect.
**********end of checkin comments for 628130)*******


**********checkin comments for 629712)**************
DERBY-3404: EmbedResultSet.getString() returns wrong value after auto-commit with
CLOSE_CURSORS_AT_COMMIT
**********end of checkin comments for 629712)*******


**********checkin comments for 629926)**************
DERBY-3304

The main purpose of this patch is to fix the rollback handling for resultsets that do not
return rows. An example case for this is a java procedure which has a Connection.rollback
inside it. When the user calls the java procedure, and Connection.rollback is made inside
of it, Derby should not be closing the resultset assoicated with the java procedure call
(that resultset is a CallStatementResultSet). In other words, a user initiated rollback
through JDBC Connection object should leave the resultsets that do not return rows open. In
order to implement this, I had to make changes to ignore resultsets that do not return rows
in
GenericLanguageConnectionContext.endTransactionActivationHandling. As a result of this
change, for the eg case given above, the activation assoicated with the java procedure
will not be reset (which also means that, CallStatementResultSet.close will not be called)
inside GenericLanguageConnectionContext.endTransactionActivationHandling.

But the code inside CallStatementResultset.close() took care of the closed dynamic resultset
and it took out the closed dynamic resultset from the list of resultsets that would be
available to user through the Statement.getResultSet api. With my changes through this
patch, we are going to skip the CallStatementResultset.close during
GenericLanguageConnectionContext.endTransactionActivationHandling which means that we have
to deal with those closed dynamic resultsets on our own. I did that part of logic
changes in EmbedStatement.processDynamicResults

EmbedStatement.processDynamicResults used to check if the JDBC Resultset is closed by
directly checking the field isClosed in the EmbedResultSet. But it is not sufficient to
check only JDBC Resultset. We need to check the underlying language Resultset too to
determine if the dynamic resultset is closed. There is no direct api on EmbedResultset
which will return a boolean after checking the JDBC Resultset and language Resulset. Instead,
there is a method called EmbedResultSet.checkIfClosed. This method will throw an exception
if it finds the JDBC ResultSet or language ResultSet closed. So, my changes in
EmbedStatement.processDynamicResults make a call to EmbedResultSet.checkIfClosed and if
there is an exception thrown, then we know that the resultset is closed and hence we should
move to the next resultset.

In addition to these code changes, I have added a new test to LangProcedureTest. The new
java procedure is defined to return 2 dynamic resultsets. One of these resultsets is
created before Connection.rollback inside the java procedure. The other dynamic resultset
is created after Connection.rollback. As as result of Connection.rollback, the first
dynamic resultset will be closed but the second one will remain open. The test makes sure
that only one dynamic resultset is returned by the java procedure.

Also, made one minor change in LangProcedureTest for an existing test. The test at line 804
was getting a resultset from the Statement object without asserting that there are no more
resultsets. The resultset object would have been null anyways in this test because there
are no open resulsets from the Java procedure. Because of this, I took out the redundant
code of getting null resultset object from Statement using getResultset,
**********end of checkin comments for 629926)*******


**********checkin comments for 631481)**************
Checking in code cleanup for DERBY-3304. This code cleanup is based on Knut's review of my
earlier commit 629926. No functionality has changed, but code will be now much easier to
read.
**********end of checkin comments for 631481)*******
Files Changed
MODIFY /db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
MODIFY /db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/jdk16/closed.out
MODIFY /db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java
MODIFY /db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/closed.out
MODIFY /db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/ResultSetTest.java
MODIFY /db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedStatement.java
MODIFY /db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/DataSourceTest.java
MODIFY /db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/master/nestedCommit.out
MODIFY /db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LangProcedureTest.java