[
https://issues.apache.org/jira/browse/DERBY-6214?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Mamta A. Satoor updated DERBY-6214:
-----------------------------------
Attachment: DERBY6214_patch2_diff.txt
Thanks for looking at the patch, Mike. I am attaching another patch which
addresses most of your comments. The files touched by this patch are as follows
$ svn stat -q
M java\engine\org\apache\derby\iapi\reference\Limits.java
M
java\testing\org\apache\derbyTesting\functionTests\tests\jdbcapi\ParameterMappingTest.java
M java\client\org\apache\derby\client\net\NetStatementRequest.java
M java\client\org\apache\derby\client\am\CrossConverters.java
M java\client\org\apache\derby\client\am\ClientPreparedStatement.java
This patch makes PreparedStatement.setObject work same as
PreparedStatement.setString for small strings(<=10922 characters in length).
Additionally, I have modularized the tests from the previous patch and made
changes to verify the updated data for that test. The changes to verify the
updated data use ResultSet.getString and ResultSet.getObject thus verifying
that those apis work fine with the changed made for
PreparedStatement.setObject. In addition, I have added new tests for
ResultSet.updateString and ResultSet.updateObject to make sure the changes for
PreparedStatement.setObject has not broken these apis since they share the same
code. I have added lot more comments into the code changes. I have also created
a constant in java\engine\org\apache\derby\iapi\reference\Limits.java for the
length 10922 so in the code, we use that constant rather than the actual
number. I think it is ok to add the constant in the Limits file since I have
seen other client code using constants from that file.
Here is the response to some of the questions in your comments
********************************
o you added the following with no comment as to why, I would prefer not to add
an extra call level to this high traffic routine if possible. Is it just to
save some
typing to change all the callse in the following setObject routine? If
so I would just rather see the code change made. all the overriding based on
num arguments can
easily lead to bugs when making changes like this, other routine may
start getting called that you don't expect. :
final Object setObject(int targetType, Object source) throws SqlException {
return setObject(targetType, source, false);
}
Yes, the reason for the new method is so that we don't have to change all the
callers of CrossConverts.setObject(targetType, source) to have to pass the new
parameter which will be false for all except ClientPreparedStatement.setObjectX
method. I do see your point about this causing possible confusion and
unintentional method being called. I can go ahead and change all the callers to
pass false when they call this method and just have
ClientPreparedStatement.setObjectX pass the value true. This will eliminate the
need for a new method in CrossConverts class.
********************************
********************************
4) what problems result if you don't have the originalSetObject information? It
would be better if we did not have the special case if we can help it, just
always send string in small string case.
It seems likely there are existing problems with updateXXX also. maybe just
is not right for getXXX, not sure. I'd like to see if there is any way to fix
this without adding a param/extra call to
this high traffic routine.
When originally I didn't have the check in my code, it caused the existing
junit test UpdatableResultSetTest to fail. Now, that I have added
ResultSet.updateXXX calls test in my junit test, I see the same failure with
that new junit test if I remove the originalSetObject information. The
exception is as follows. I have not spent the reason behind the class cast
exception but I can spend some time on it to see if it is easy to fix this
exception so we do not need to have special parameter originalSetObject anymore.
1)
testDerby6214updateXXX(org.apache.derbyTesting.functionTests.tests.jdbcapi.ParameterMappingTest)java.lang.ClassCastException:
java.lang.String incompatible with java.sql.Clob
at
org.apache.derby.client.net.NetStatementRequest.computeProtocolTypesAndLengths(NetStatementRequest.java:1462)
at
org.apache.derby.client.net.NetStatementRequest.buildSQLDTAcommandData(NetStatementRequest.java:545)
at
org.apache.derby.client.net.NetStatementRequest.writeExecute(NetStatementRequest.java:162)
at
org.apache.derby.client.net.NetPreparedStatement.writeExecute_(NetPreparedStatement.java:156)
at
org.apache.derby.client.am.ClientResultSet.writeUpdateRow(ClientResultSet.java:4357)
at
org.apache.derby.client.am.ClientResultSet.positionToCurrentRowAndUpdate(ClientResultSet.java:4098)
at
org.apache.derby.client.am.ClientResultSet.updateRowX(ClientResultSet.java:3651)
at
org.apache.derby.client.am.ClientResultSet.updateRow(ClientResultSet.java:3555)
at
org.apache.derbyTesting.functionTests.tests.jdbcapi.ParameterMappingTest.testDerby6214updateXXX(ParameterMappingTest.java:439)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at
org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:117)
at
org.apache.derbyTesting.junit.BaseJDBCTestCase.runBareOverridable(BaseJDBCTestCase.java:439)
at
org.apache.derbyTesting.junit.BaseJDBCTestCase.runBare(BaseJDBCTestCase.java:456)
at junit.extensions.TestDecorator.basicRun(TestDecorator.java:24)
at junit.extensions.TestSetup$1.protect(TestSetup.java:21)
at junit.extensions.TestSetup.run(TestSetup.java:25)
at
org.apache.derbyTesting.junit.BaseTestSetup.run(BaseTestSetup.java:57)
at junit.extensions.TestDecorator.basicRun(TestDecorator.java:24)
at junit.extensions.TestSetup$1.protect(TestSetup.java:21)
at junit.extensions.TestSetup.run(TestSetup.java:25)
at junit.extensions.TestDecorator.basicRun(TestDecorator.java:24)
at junit.extensions.TestSetup$1.protect(TestSetup.java:21)
at junit.extensions.TestSetup.run(TestSetup.java:25)
at
org.apache.derbyTesting.junit.BaseTestSetup.run(BaseTestSetup.java:57)
********************************
> PreparedStatement.setObject(int, Object, Types.CLOB) fail with DerbyNet
> -----------------------------------------------------------------------
>
> Key: DERBY-6214
> URL: https://issues.apache.org/jira/browse/DERBY-6214
> Project: Derby
> Issue Type: Bug
> Affects Versions: 10.8.3.0, 10.9.1.0
> Reporter: Rong Qu
> Assignee: Mamta A. Satoor
> Attachments: Derby6214.java, DERBY6214_patch1_diff.txt,
> DERBY6214_patch1_stat.txt, DERBY6214_patch2_diff.txt, Derby6214_setup.sql,
> Derby6214_ver2.java, derby.log, DerbyNet_client_test.sql
>
>
> The issue is specific to the DerbyNet client driver, and doesn't seem to
> occur using embedded Derby.
> "PreparedStatement.setObject(int, Object, Types.CLOB)". It seems to be a
> problem updating a CLOB column with a parameterized value using the DerbyNet
> client driver, and if the update SQL ends up updating more than one row. I
> attached a simple test case that just uses JDBC to reproduce the error. The
> exception looks like this:
> org.apache.derby.client.am.BatchUpdateException: Non-atomic batch failure.
> The batch was submitted, but at least one exception occurred on an individual
> member of the batch. Use getNextException() to retrieve the exceptions for
> specific batched elements.
> at org.apache.derby.client.am.Agent.endBatchedReadChain(Unknown Source)
> at
> org.apache.derby.client.am.PreparedStatement.executeBatchRequestX(Unknown
> Source)
> at org.apache.derby.client.am.PreparedStatement.executeBatchX(Unknown
> Source)
> at org.apache.derby.client.am.PreparedStatement.executeBatch(Unknown
> Source)
> ...
> Caused by: org.apache.derby.client.am.SqlException: Error for batch element
> #0: An unexpected exception was thrown
> at org.apache.derby.client.am.Statement.completeExecute(Unknown Source)
> at
> org.apache.derby.client.net.NetStatementReply.parseEXCSQLSTTreply(Unknown
> Source)
> at org.apache.derby.client.net.NetStatementReply.readExecute(Unknown
> Source)
> at org.apache.derby.client.net.StatementReply.readExecute(Unknown Source)
> at org.apache.derby.client.net.NetPreparedStatement.readExecute_(Unknown
> Source)
> at org.apache.derby.client.am.PreparedStatement.readExecute(Unknown
> Source)
> ... 4 more
> Caused by: org.apache.derby.client.am.SqlException: Error for batch element
> #0: Java exception: 'Stream has already been read and end-of-file reached and
> cannot be re-used.: java.io.EOFException'.
> at org.apache.derby.client.am.SqlException.<init>(Unknown Source)
> at org.apache.derby.client.am.SqlException.<init>(Unknown Source)
> ... 10 more
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira