db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From krist...@apache.org
Subject svn commit: r791398 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/services/io/LimitInputStream.java engine/org/apache/derby/iapi/types/SQLClob.java testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java
Date Mon, 06 Jul 2009 07:24:53 GMT
Author: kristwaa
Date: Mon Jul  6 07:24:52 2009
New Revision: 791398

URL: http://svn.apache.org/viewvc?rev=791398&view=rev
Log:
DERBY-4245: Sorting a table containing a CLOB fails after upgrade to 10.5.
Changed the mechanisms used to "unread" surplus bytes from the source stream.
The order is now:
 1) Use InputStream.mark/reset if available.
 2) Create a PushbackInputStream and associate it with the source stream if the
    the source stream is a FormatIdInputStream.
 3) Try using the Resetable interface.
Note that as part of this fix, mark/reset was disabled for LimitInputStream.

Reading too many bytes will only happen in 10.5 (and later) when an old-style
Clob representation is processed. Note that since the header format of existing
Clob values isn't changed as part of the upgrade logic, the situation may arise
in later versions as well if the database has been upgraded from 10.4 or
earlier versions.

Patch file: derby-4245-3a-unread_bytes_fix.diff


Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/LimitInputStream.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLClob.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/LimitInputStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/LimitInputStream.java?rev=791398&r1=791397&r2=791398&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/LimitInputStream.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/io/LimitInputStream.java
Mon Jul  6 07:24:52 2009
@@ -144,4 +144,18 @@
 	public void setInput(InputStream in) {
 		this.in = in;
 	}
+
+    /**
+     * This stream doesn't support mark/reset, independent of whether the
+     * underlying stream does so or not.
+     * <p>
+     * The reason for not supporting mark/reset, is that it is hard to combine
+     * with the limit functionality without always keeping track of the number
+     * of bytes read.
+     *
+     * @return {@code false}
+     */
+    public boolean markSupported() {
+        return false;
+    }
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLClob.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLClob.java?rev=791398&r1=791397&r2=791398&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLClob.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLClob.java Mon Jul  6 07:24:52
2009
@@ -26,6 +26,7 @@
 import org.apache.derby.iapi.jdbc.CharacterStreamDescriptor;
 
 import org.apache.derby.iapi.services.io.ArrayInputStream;
+import org.apache.derby.iapi.services.io.FormatIdInputStream;
 import org.apache.derby.iapi.services.io.InputStreamUtil;
 import org.apache.derby.iapi.services.io.StoredFormatIds;
 
@@ -38,6 +39,7 @@
 import java.io.InputStream;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
+import java.io.PushbackInputStream;
 import java.sql.Clob;
 import java.sql.Date;
 import java.sql.SQLException;
@@ -707,17 +709,30 @@
             }
             hdrInfo = investigateHeader(header, read);
             if (read > hdrInfo.headerLength()) {
-                // We read too much data, reset and position on the first byte
-                // of the user data.
-                // First see if we set a mark on the stream and can reset it.
-                // If not, try using the Resetable interface.
+                // We read too much data. To "unread" the bytes, the following
+                // mechanisms will be attempted:
+                //  1) See if we set a mark on the stream, if so reset it.
+                //  2) If we have a FormatIdInputStream, use a
+                //     PushBackInputStream and use it as the source.
+                //  3) Try using the Resetable interface.
+                // To avoid silent data truncation / data corruption, we fail
+                // in step three if the stream isn't resetable.
                 if (markSet) {
-                    // Stream is not a store Resetable one, use mark/reset
-                    // functionality instead.
+                    // 1) Reset the stream to the previously set mark.
                     srcIn.reset();
                     InputStreamUtil.skipFully(srcIn, hdrInfo.headerLength());
-                } else if (in instanceof Resetable) {
-                    // We have a store stream.
+                } else if (in instanceof FormatIdInputStream) {
+                    // 2) Add a push back stream on top of the underlying
+                    // source, and unread the surplus bytes we read. Set the
+                    // push back stream to be the source of the data input obj.
+                    final int surplus = read - hdrInfo.headerLength();
+                    FormatIdInputStream formatIn = (FormatIdInputStream)in;
+                    PushbackInputStream pushbackIn = new PushbackInputStream(
+                            formatIn.getInputStream(), surplus);
+                    pushbackIn.unread(header, hdrInfo.headerLength(), surplus);
+                    formatIn.setInput(pushbackIn);
+                } else {
+                    // 3) Assume we have a store stream.
                     rewindStream(srcIn, hdrInfo.headerLength());
                 }
             }

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java?rev=791398&r1=791397&r2=791398&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbc4/_Suite.java
Mon Jul  6 07:24:52 2009
@@ -70,6 +70,7 @@
 		suite.addTest(ConnectionMethodsTest.suite());
         suite.addTest(VerifySignatures.suite());
         suite.addTest (LobStreamTest.suite());
+        suite.addTest(LobSortTest.suite());
         suite.addTest (BlobSetMethodsTest.suite());
         suite.addTest (JDBC4FromJDBC3DataSourceTest.suite());
 		



Mime
View raw message