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 km...@apache.org on 2007/07/17 14:56:26 UTC
svn commit: r556914 - in /db/derby/code/branches/10.2/java:
drda/org/apache/derby/impl/drda/ engine/org/apache/derby/iapi/jdbc/
engine/org/apache/derby/impl/jdbc/
testing/org/apache/derbyTesting/functionTests/master/DerbyNet/
testing/org/apache/derbyTe...
Author: kmarsden
Date: Tue Jul 17 05:56:22 2007
New Revision: 556914
URL: http://svn.apache.org/viewvc?view=rev&rev=556914
Log:
DERBY-2941 With 10.2, Closing a resultset after retrieving a large > 32665 bytes value with Network Server does not release locks
Modified:
db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/EXTDTAInputStream.java
db/derby/code/branches/10.2/java/engine/org/apache/derby/iapi/jdbc/EngineResultSet.java
db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java
db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/blobclob4BLOB.out
db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/blobclob4BLOB.out
db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall
Modified: db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java?view=diff&rev=556914&r1=556913&r2=556914
==============================================================================
--- db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java (original)
+++ db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java Tue Jul 17 05:56:22 2007
@@ -6531,7 +6531,7 @@
if (SanityManager.DEBUG)
trace("!!drdaType = " + java.lang.Integer.toHexString(drdaType) +
- "precision = " + precision +" scale = " + scale);
+ " precision=" + precision +" scale = " + scale);
switch (ndrdaType)
{
case DRDAConstants.DRDA_TYPE_NLOBBYTES:
@@ -6539,7 +6539,7 @@
EXTDTAInputStream extdtaStream=
EXTDTAInputStream.getEXTDTAStream(rs, i, drdaType);
writeFdocaVal(i,extdtaStream, drdaType,
- precision,scale,rs.wasNull(),stmt);
+ precision,scale,extdtaStream.isNull(),stmt);
break;
case DRDAConstants.DRDA_TYPE_NINTEGER:
int ival = rs.getInt(i);
@@ -7802,7 +7802,9 @@
Object o = extdtaValues.get(i);
if (o instanceof EXTDTAInputStream) {
EXTDTAInputStream stream = (EXTDTAInputStream) o;
+
try{
+ stream.initInputStream();
writer.writeScalarStream (chainedWithSameCorrelator,
CodePoint.EXTDTA,
stream,
Modified: db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/EXTDTAInputStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/EXTDTAInputStream.java?view=diff&rev=556914&r1=556913&r2=556914
==============================================================================
--- db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/EXTDTAInputStream.java (original)
+++ db/derby/code/branches/10.2/java/drda/org/apache/derby/impl/drda/EXTDTAInputStream.java Tue Jul 17 05:56:22 2007
@@ -20,23 +20,21 @@
*/
package org.apache.derby.impl.drda;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedInputStream;
+import java.io.Reader;
import java.sql.ResultSet;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.SQLException;
-import java.io.UnsupportedEncodingException;
-
+import org.apache.derby.iapi.jdbc.EngineResultSet;
import org.apache.derby.iapi.reference.DRDAConstants;
import org.apache.derby.iapi.services.sanity.SanityManager;
import org.apache.derby.impl.jdbc.Util;
/**
- * @author marsden
*
* EXTDTAObjectHolder provides Externalized Large Object representation that
* does not hold locks until the end of the transaction (DERBY-255)
@@ -49,35 +47,33 @@
class EXTDTAInputStream extends InputStream {
private InputStream binaryInputStream = null;
-
- private boolean isEmptyStream;
-
- private ResultSet dataResultSet = null;
- private Blob blob = null;
- private Clob clob = null;
+
+
+ /** ResultSet that contains the stream*/
+ EngineResultSet rs;
+ /** Column index starting with 1 */
+ int columnNumber;
+ /** DRDA Type of column */
+ int ndrdaType;
+
private EXTDTAInputStream(ResultSet rs,
int columnNumber,
int ndrdaType)
- throws SQLException, IOException
{
- this.dataResultSet = rs;
- this.isEmptyStream = ! initInputStream(rs,
- columnNumber,
- ndrdaType);
-
- }
+ this.rs = (EngineResultSet) rs;
+ this.columnNumber = columnNumber;
+ this.ndrdaType = ndrdaType;
+ }
-
/**
- * Retrieve stream from the ResultSet and column specified. Create an
- * input stream for the large object being retrieved. Do not hold
- * locks until end of transaction. DERBY-255.
+ * Create a new EXTDTAInputStream. Before read the stream must be
+ * initialized by the user with {@link #initInputStream()}
*
- *
- * See DDMWriter.writeScalarStream
+ * @see DDMWriter#writeScalarStream
+ * @see #initInputStream()
*
* @param rs
* result set from which to retrieve the lob
@@ -96,61 +92,25 @@
* @throws SQLException
*/
public static EXTDTAInputStream getEXTDTAStream(ResultSet rs, int column, int drdaType)
- throws SQLException {
- try{
+ {
+
int ndrdaType = drdaType | 1; //nullable drdaType
return new EXTDTAInputStream(rs,
column,
ndrdaType);
- }catch(IOException e){
- throw new SQLException(e.getMessage());
- }
-
}
- /**
- * Get the length of the InputStream
- * This method is currently not used because there seems to be no way to
- * reset the she stream.
- *
- * @param binaryInputStream
- * an InputStream whose length needs to be calclulated
- * @return length of stream
- */
- private static long getInputStreamLength(InputStream binaryInputStream)
- throws SQLException {
- long length = 0;
- if (binaryInputStream == null)
- return length;
-
- try {
- for (;;) {
- int avail = binaryInputStream.available();
- binaryInputStream.skip(avail);
- if (avail == 0)
- break;
- length += avail;
-
- }
- //binaryInputStream.close();
- } catch (IOException ioe) {
- throw Util.javaException(ioe);
- }
-
- return length;
-
- }
-
/**
- *
+ * Requires {@link #initInputStream()} be called before we can read from the stream
*
* @see java.io.InputStream#read()
*/
public int read() throws IOException {
+
return binaryInputStream.read();
}
@@ -170,17 +130,9 @@
*/
public void close() throws IOException {
- try{
if (binaryInputStream != null)
binaryInputStream.close();
binaryInputStream = null;
-
- }finally{
-
- blob = null;
- clob = null;
- dataResultSet = null;
- }
}
@@ -257,60 +209,51 @@
}
- protected boolean isEmptyStream(){
- return isEmptyStream;
- }
+ protected boolean isEmptyStream() throws SQLException{
+ return (rs.getLength(columnNumber) == 0);
+
+ }
/**
* This method takes information of ResultSet and
- * initialize binaryInputStream variable of this object with not empty stream and return true.
- * If the stream was empty, this method remain binaryInputStream null and return false.
- *
- * @param rs ResultSet object to get stream from.
- * @param column index number of column in ResultSet to get stream.
- * @param ndrdaType describe type column to get stream.
+ * initializes the binaryInputStream variable of this object with not empty stream
+ * by calling getBinaryStream or getCharacterStream() as appropriate.
+ * The Reader returned from getCharacterStream() will be encoded in binarystream.
*
- * @return true if the stream was not empty, false if the stream was empty.
*
*/
- private boolean initInputStream(ResultSet rs,
- int column,
- int ndrdaType)
- throws SQLException,
- IOException
+ public void initInputStream()
+ throws SQLException
{
InputStream is = null;
- try{
- // BLOBS
- if (ndrdaType == DRDAConstants.DRDA_TYPE_NLOBBYTES)
- {
- blob = rs.getBlob(column);
- if(blob == null){
- return false;
- }
-
- is = blob.getBinaryStream();
-
- }
+ Reader r = null;
+ // BLOBS
+ if (ndrdaType == DRDAConstants.DRDA_TYPE_NLOBBYTES)
+ {
+ is = this.rs.getBinaryStream(this.columnNumber);
+ if (is == null)
+ return;
+ }
// CLOBS
- else if (ndrdaType == DRDAConstants.DRDA_TYPE_NLOBCMIXED)
- {
- try {
- clob = rs.getClob(column);
-
- if(clob == null){
- return false;
- }
+ else if (ndrdaType == DRDAConstants.DRDA_TYPE_NLOBCMIXED)
+ {
+ try {
+
+ r = this.rs.getCharacterStream(this.columnNumber);
+
+ if(r == null){
+ return;
+ }
- is = new ReEncodedInputStream(clob.getCharacterStream());
+ is = new ReEncodedInputStream(r);
}catch (java.io.UnsupportedEncodingException e) {
- throw new SQLException (e.getMessage());
+ throw Util.javaException(e);
}catch (IOException e){
- throw new SQLException (e.getMessage());
+ throw Util.javaException(e);
}
@@ -323,74 +266,29 @@
" not valid EXTDTA object type");
}
}
-
- boolean exist = is.read() > -1;
-
- is.close();
- is = null;
-
- if(exist){
- openInputStreamAgain();
- }
-
- return exist;
-
- }catch(IllegalStateException e){
- throw Util.javaException(e);
-
- }finally{
- if(is != null)
- is.close();
-
- }
-
- }
-
-
- /**
- *
- * This method is called from initInputStream and
- * opens inputstream again to stream actually.
- *
- */
- private void openInputStreamAgain() throws IllegalStateException,SQLException {
-
- if(this.binaryInputStream != null){
- return;
- }
-
- InputStream is = null;
- try{
-
- if(SanityManager.DEBUG){
- SanityManager.ASSERT( ( blob != null && clob == null ) ||
- ( clob != null && blob == null ),
- "One of blob or clob must be non-null.");
- }
-
- if(blob != null){
- is = blob.getBinaryStream();
-
- }else if(clob != null){
- is = new ReEncodedInputStream(clob.getCharacterStream());
+ if (! is.markSupported()) {
+ is = new BufferedInputStream(is);
}
- }catch(IOException e){
- throw new IllegalStateException(e.getMessage());
- }
-
- if(! is.markSupported() ){
- is = new BufferedInputStream(is);
- }
-
- this.binaryInputStream = is;
-
+ this.binaryInputStream=is;
}
-
+
protected void finalize() throws Throwable{
close();
}
-
+ /**
+ * Is the value null? Null status is obtained from the underlying
+ * EngineResultSet, so that it can be determined before the stream
+ * is retrieved.
+ *
+ * @return true if this value is null
+ *
+ */
+ public boolean isNull() throws SQLException
+ {
+ return this.rs.isNull(columnNumber);
+
+ }
}
Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/iapi/jdbc/EngineResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/iapi/jdbc/EngineResultSet.java?view=diff&rev=556914&r1=556913&r2=556914
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/iapi/jdbc/EngineResultSet.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/iapi/jdbc/EngineResultSet.java Tue Jul 17 05:56:22 2007
@@ -21,6 +21,9 @@
package org.apache.derby.iapi.jdbc;
import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.apache.derby.iapi.error.StandardException;
/**
* Additional methods the embedded engine exposes on its ResultSet object
* implementations. An internal api only, mainly for the network
@@ -32,4 +35,26 @@
* Is this result set from a select for update statement?
*/
public boolean isForUpdate();
+
+ /**
+ * Is the designated columnIndex a null data value?
+ * This is used by EXTDTAInputStream to get the null value without
+ * retrieving the underlying data value.
+ * @param columnIndex
+ * @return true if the data value at columnIndex for the current row is null
+ * @throws SQLException
+ */
+ public boolean isNull(int columnIndex) throws SQLException;
+
+ /**
+ * Return the length of the designated columnIndex data value.
+ * Implementation is type dependent.
+ *
+ * @param columnIndex column to access
+ * @return length of data value
+ * @throws SQLException
+ * @see org.apache.derby.iapi.types.DataValueDescriptor#getLength()
+ */
+ public int getLength(int columnIndex) throws SQLException;
+
}
Modified: db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java?view=diff&rev=556914&r1=556913&r2=556914
==============================================================================
--- db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java (original)
+++ db/derby/code/branches/10.2/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java Tue Jul 17 05:56:22 2007
@@ -5100,4 +5100,26 @@
checkIfClosed("updateClob");
updateClob(findColumnName(columnName), x);
}
+
+ /*
+ * @see org.apache.derby.iapi.jdbc.EngineResultSet#isNull(int)
+ */
+ public boolean isNull(int columnIndex) throws SQLException{
+ try {
+ DataValueDescriptor dvd = getColumn(columnIndex);
+ return dvd.isNull();
+ } catch (StandardException t) {
+ throw noStateChangeException(t);
+ }
+ }
+
+ public int getLength(int columnIndex) throws SQLException {
+ try {
+ DataValueDescriptor dvd = getColumn(columnIndex);
+ return dvd.getLength();
+ } catch (StandardException t) {
+ throw noStateChangeException(t);
+ }
+ }
+
}
Modified: db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/blobclob4BLOB.out
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/blobclob4BLOB.out?view=diff&rev=556914&r1=556913&r2=556914
==============================================================================
--- db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/blobclob4BLOB.out (original)
+++ db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/blobclob4BLOB.out Tue Jul 17 05:56:22 2007
@@ -556,8 +556,7 @@
row 9 is null, skipped
clobTest91 finished
START: clobTest92
-FAIL -- unexpected exception ****************
-SQLSTATE(40XL1): A lock could not be obtained within the time requested
+clobTest92 finished
START: clobTest93
clobTest92 finished
START: clobTest94
Modified: db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/blobclob4BLOB.out
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/blobclob4BLOB.out?view=diff&rev=556914&r1=556913&r2=556914
==============================================================================
--- db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/blobclob4BLOB.out (original)
+++ db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/blobclob4BLOB.out Tue Jul 17 05:56:22 2007
@@ -560,8 +560,7 @@
row 9 is null, skipped
clobTest91 finished
START: clobTest92
-FAIL -- unexpected exception ****************
-SQLSTATE(40XL1): A lock could not be obtained within the time requested
+clobTest92 finished
START: clobTest93
clobTest92 finished
START: clobTest94
Modified: db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall?view=diff&rev=556914&r1=556913&r2=556914
==============================================================================
--- db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall (original)
+++ db/derby/code/branches/10.2/java/testing/org/apache/derbyTesting/functionTests/suites/jdbcapi.runall Tue Jul 17 05:56:22 2007
@@ -11,6 +11,7 @@
jdbcapi/secureUsers.sql
jdbcapi/secureUsers1.sql
jdbcapi/maxfieldsize.java
+jdbcapi/LargeDataLocks.java
jdbcapi/LOBTest.java
jdbcapi/blobclob4BLOB.java
jdbcapi/parameterMapping.java