[
https://issues.apache.org/jira/browse/DERBY-1599?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12538681
]
Mamta A. Satoor commented on DERBY-1599:
----------------------------------------
I spent some time on this Jira entry and here is what I found.
When the sample program does rs.updateCharacterStream() on a Clob column, we
generate a derby.client.am.Clob object with it's dataType_ as CHARACTER_STREAM
Thread [main] (Suspended)
Clob.<init>(Agent, Reader, int) line: 170
CrossConverters.setObject(int, Reader, int) line: 651
NetResultSet(ResultSet).updateCharacterStream(int, Reader, int) line:
3066
DERBY_1599_Repro.main(String[]) line: 56
In other words, the resultant derby.client.am.Clob object has a character
stream associated with it but it's string_ variable is NULL.
Later, when the sample program retrieve the Clob object using
Clob clob = rs.getClob(1);
we get the Clob object with character stream associated with it but no direct
string value. The return of Clob object for the call above is shown in the
following call stack
Thread [main] (Suspended)
NetResultSet(ResultSet).getClob(int) line: 1256
DERBY_1599_Repro.main(String[]) line: 57
The problem happens for the next call in the user program when we try to use
substring, ie
String string = clob.getSubString(1, (int) clob.length());
This is implemented in
derby.client.am.Clob.getSubStringX(long, int) line: 326
and the code for Clob.getSubStringX in derby network client looks as follows
private String getSubStringX(long pos, int length) throws SqlException
{
checkForClosedConnection();
// actual length is the lesser of the length requested
// and the number of characters available from pos to the end
long actualLength = Math.min(this.sqlLength() - pos + 1, (long) length);
//Check to see if the Clob object is locator enabled.
if (isLocator()) {
//The Clob object is locator enabled. Hence call the stored
//procedure CLOBGETLENGTH to determine the length of the Clob.
return agent_.connection_.locatorProcedureCall()
.clobGetSubString(locator_, pos, (int)actualLength);
}
else {
//The Clob object is not locator enabled.
return string_.substring
((int) pos - 1, (int) (pos - 1 + actualLength));
}
}
Since this Clob object is not locator enabled, the code control goes to else in
the code above and since string_ is NULL, we end up getting null pointer
exception.
To fix the problem, should we be checking if string_ is null, and if yes, then
check what stream is associated with the Clob object and then materialize the
string_ from the stream? Would like to know if anyone has any thoughts on this.
BTW, I tried modifying the repro program so that we try to do
rs.updateCharacterStream(1, r, 3);
rs.getCharacterStream(1);
but that didn't go very well either. It resulted in following exception
$ java org.apache.derbyTesting.functionTests.tests.lang.DERBY_1599_Repro
Exception in thread "main" java.sql.SQLException: An attempt was made to put a
data value of type 'java.sql.Clob' into a data value of type 'CHAR'.
at
org.apache.derby.client.am.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:46)
at
org.apache.derby.client.am.SqlException.getSQLException(SqlException.java:362)
at
org.apache.derby.client.am.ResultSet.getCharacterStream(ResultSet.java:1211)
at
org.apache.derbyTesting.functionTests.tests.lang.DERBY_1599_Repro.main(DERBY_1599_Repro.java:57)
Caused by: org.apache.derby.client.am.SqlException: An attempt was made to put
a data value of type 'java.sql.Clob' into a data value of type 'CHAR'.
at
org.apache.derby.client.am.CrossConverters.setObject(CrossConverters.java:810)
at
org.apache.derby.client.am.CrossConverters.setObject(CrossConverters.java:846)
at
org.apache.derby.client.am.ResultSet.getCharacterStream(ResultSet.java:1198)
... 1 more
> Clob.getSubString() throws NullPointerException when created by updatable
> result set
> ------------------------------------------------------------------------------------
>
> Key: DERBY-1599
> URL: https://issues.apache.org/jira/browse/DERBY-1599
> Project: Derby
> Issue Type: Bug
> Components: JDBC, Network Client
> Affects Versions: 10.1.3.1, 10.2.1.6
> Reporter: Knut Anders Hatlen
> Priority: Minor
> Attachments: Repro.java
>
>
> If you create a clob value with one of the ResultSet.updateXXX methods that
> take a stream or a reader, and retrieve that value with ResultSet.getClob(),
> a NullPointerException will be thrown when getSubString() is called on the
> returned Clob object. This happens with the network client driver, and it has
> been observed on Derby 10.1.3.1 and trunk.
> Exception in thread "main" java.lang.NullPointerException
> at org.apache.derby.client.am.Clob.getSubStringX(Clob.java:229)
> at org.apache.derby.client.am.Clob.getSubString(Clob.java:210)
> at Repro.main(Repro.java:24)
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.