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 21:21:24 UTC
svn commit: r557032 - in /db/derby/code/trunk/java:
drda/org/apache/derby/impl/drda/ engine/org/apache/derby/iapi/jdbc/
engine/org/apache/derby/impl/jdbc/
Author: kmarsden
Date: Tue Jul 17 12:21:22 2007
New Revision: 557032
URL: http://svn.apache.org/viewvc?view=rev&rev=557032
Log:
DERBY-2941 With 10.2, Closing a resultset after retrieving a large > 32665 bytes value with Network Server does not release locks
Port to 10.4. Verified with 10.2 client running LargeDataLocksTest
Modified:
db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/EXTDTAInputStream.java
db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/EngineResultSet.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java
Modified: db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/DRDAConnThread.java?view=diff&rev=557032&r1=557031&r2=557032
==============================================================================
--- 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 Tue Jul 17 12:21:22 2007
@@ -6656,7 +6656,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:
@@ -6664,7 +6664,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);
@@ -7946,7 +7946,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/trunk/java/drda/org/apache/derby/impl/drda/EXTDTAInputStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/EXTDTAInputStream.java?view=diff&rev=557032&r1=557031&r2=557032
==============================================================================
--- db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/EXTDTAInputStream.java (original)
+++ db/derby/code/trunk/java/drda/org/apache/derby/impl/drda/EXTDTAInputStream.java Tue Jul 17 12:21:22 2007
@@ -23,11 +23,13 @@
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 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;
@@ -45,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
@@ -92,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();
}
@@ -166,17 +130,9 @@
*/
public void close() throws IOException {
- try{
if (binaryInputStream != null)
binaryInputStream.close();
binaryInputStream = null;
-
- }finally{
-
- blob = null;
- clob = null;
- dataResultSet = null;
- }
}
@@ -256,60 +212,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);
}
@@ -322,74 +269,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/trunk/java/engine/org/apache/derby/iapi/jdbc/EngineResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/EngineResultSet.java?view=diff&rev=557032&r1=557031&r2=557032
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/EngineResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/jdbc/EngineResultSet.java Tue Jul 17 12:21: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/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java?view=diff&rev=557032&r1=557031&r2=557032
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java Tue Jul 17 12:21:22 2007
@@ -5051,4 +5051,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);
+ }
+ }
+
}