db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From krist...@apache.org
Subject svn commit: r742357 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/types/SQLChar.java testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/CharacterStreamsTest.java
Date Mon, 09 Feb 2009 09:41:07 GMT
Author: kristwaa
Date: Mon Feb  9 09:41:06 2009
New Revision: 742357

URL: http://svn.apache.org/viewvc?rev=742357&view=rev
Log:
DERBY-4040: SQLChar.getLength returns wrong length for some data values.
When asked to return the character length of a SQLChar or SQLVarchar and
the value is represented as a stream, skip the two header bytes and then
decode the whole stream. The cause of the bug being fixed, was that the
byte length was used as the character length.
Patch file: derby-4040-1a-SQLChar_length_and_test.diff


Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLChar.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/CharacterStreamsTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLChar.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLChar.java?rev=742357&r1=742356&r2=742357&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLChar.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLChar.java Mon Feb  9 09:41:06
2009
@@ -44,6 +44,7 @@
 
 import org.apache.derby.iapi.services.cache.ClassSize;
 import org.apache.derby.iapi.services.io.ArrayInputStream;
+import org.apache.derby.iapi.services.io.InputStreamUtil;
 import org.apache.derby.iapi.util.StringUtil;
 import org.apache.derby.iapi.util.UTF8Util;
 import org.apache.derby.iapi.services.i18n.LocaleFinder;
@@ -589,18 +590,10 @@
         if (stream != null) {
             if (stream instanceof Resetable && stream instanceof ObjectInput) {
                 try {
-                    int clobLength = 0;
-                    // If we have the stream length encoded.
-                    // just read that.
-                    int utf8len = readCharacterLength((ObjectInput) stream);
-                    if (utf8len != 0) {
-                        clobLength = utf8len;
-                        return clobLength;
-                    }
-                    // Otherwise we will have to read the whole stream.
-                    int skippedCharSize = (int) UTF8Util.skipUntilEOF(stream);
-                    clobLength = skippedCharSize;
-                    return clobLength;
+                    // Skip the encoded byte length.
+                    InputStreamUtil.skipFully(stream, 2);
+                    // Decode the whole stream to find the character length.
+                    return (int)UTF8Util.skipUntilEOF(stream);
                 } catch (IOException ioe) {
                     throwStreamingIOException(ioe);
                 } finally {

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/CharacterStreamsTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/CharacterStreamsTest.java?rev=742357&r1=742356&r2=742357&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/CharacterStreamsTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/CharacterStreamsTest.java
Mon Feb  9 09:41:06 2009
@@ -29,6 +29,8 @@
 import java.sql.SQLException;
 import java.sql.Statement;
 import junit.framework.Test;
+import org.apache.derbyTesting.functionTests.util.streams.CharAlphabet;
+import org.apache.derbyTesting.functionTests.util.streams.LoopingAlphabetReader;
 import org.apache.derbyTesting.junit.BaseJDBCTestCase;
 import org.apache.derbyTesting.junit.TestConfiguration;
 
@@ -219,14 +221,23 @@
                 "insert into charstream(c, vc, lvc, lob) " +
                 "values(?,?,?,?)");
         PreparedStatement psDel = prepareStatement("DELETE FROM charstream");
+        PreparedStatement psqSQLLength = prepareStatement(
+                "select length(c), length(vc), length(lvc), length(lob) " +
+                "from charstream");
         PreparedStatement psq2 =
                 prepareStatement("select c, vc, lvc, lob from charstream");
 
         println("setCharacterStream(LONG CHARACTER STREAMS WITH UNICODE)");
-        checkCharacterStreams(psDel, psi, psq2, 14, 93, 55, 55);
-        checkCharacterStreams(psDel, psi, psq2, 25, 19332, 18733, 18733);
-        checkCharacterStreams(psDel, psi, psq2, 1, 32433, 32673, 32673);
-        checkCharacterStreams(psDel, psi, psq2, 0, 32532, 32700, 32700);
+        checkCharacterStreams(
+                psDel, psi, psq2, psqSQLLength, 14, 93, 55, 55, 0);
+        checkCharacterStreams(
+                psDel, psi, psq2, psqSQLLength, 21, 10887, 10887, 10887, 3);
+        checkCharacterStreams(
+                psDel, psi, psq2, psqSQLLength, 25, 19332, 18733, 18733, 0);
+        checkCharacterStreams(
+                psDel, psi, psq2, psqSQLLength, 1, 32433, 32673, 32673, 0);
+        checkCharacterStreams(
+                psDel, psi, psq2, psqSQLLength, 0, 32532, 32700, 32700, 0);
 
         psi.close();
         psDel.close();
@@ -555,34 +566,64 @@
         rs.close();
     }
 
+    private Reader getSourceStream(int length, int bytesPerChar) {
+        switch (bytesPerChar) {
+            case 0:
+                return new c3Reader(length);
+            case 1:
+                return new LoopingAlphabetReader(length,
+                        CharAlphabet.modernLatinLowercase());
+            case 2:
+                return new LoopingAlphabetReader(length,
+                        CharAlphabet.tamil());
+            case 3:
+                return new LoopingAlphabetReader(length,
+                        CharAlphabet.cjkSubset());
+            default:
+                fail("Illegal value of bytesPerChar: " + bytesPerChar);
+                return null;
+        }
+    }
+
     private void checkCharacterStreams(
             PreparedStatement psDel,
             PreparedStatement psi,
             PreparedStatement psq2,
-            int cl, int vcl, int lvcl, int lob)
+            PreparedStatement psqSQLLength,
+            int cl, int vcl, int lvcl, int lob,
+            int bytesPerChar)
             throws SQLException, IOException {
         psDel.executeUpdate();
 
-        psi.setCharacterStream(1, new c3Reader(cl), cl);
-        psi.setCharacterStream(2, new c3Reader(vcl), vcl);
-        psi.setCharacterStream(3, new c3Reader(lvcl), lvcl);
-        psi.setCharacterStream(4, new c3Reader(lob), lob);
+        psi.setCharacterStream(1, getSourceStream(cl, bytesPerChar), cl);
+        psi.setCharacterStream(2, getSourceStream(vcl, bytesPerChar), vcl);
+        psi.setCharacterStream(3, getSourceStream(lvcl, bytesPerChar), lvcl);
+        psi.setCharacterStream(4, getSourceStream(lob, bytesPerChar), lob);
         psi.executeUpdate();
 
+        ResultSet rsLength = psqSQLLength.executeQuery();
+        assertTrue(rsLength.next());
+        assertEquals(25, rsLength.getInt(1));   // CHAR
+        assertEquals(vcl, rsLength.getInt(2));  // VARCHAR
+        assertEquals(lvcl, rsLength.getInt(3)); // LONG VARCHAR
+        assertEquals(lob, rsLength.getInt(4));  //CLOB
+        assertFalse(rsLength.next());
+        rsLength.close();
+
         ResultSet rs = psq2.executeQuery();
         rs.next();
 
         InputStream is = rs.getAsciiStream(1);
-        checkCharStream(is, cl, 25);
+        checkCharStream(is, cl, 25, bytesPerChar);
 
         is = rs.getAsciiStream(2);
-        checkCharStream(is, vcl, -1);
+        checkCharStream(is, vcl, -1, bytesPerChar);
 
         is = rs.getAsciiStream(3);
-        checkCharStream(is, lvcl, -1);
+        checkCharStream(is, lvcl, -1, bytesPerChar);
 
         is = rs.getAsciiStream(4);
-        checkCharStream(is, lob, -1);
+        checkCharStream(is, lob, -1, bytesPerChar);
 
         rs.close();
 
@@ -590,16 +631,16 @@
         rs.next();
 
         Reader r = rs.getCharacterStream(1);
-        checkCharStream(r, cl, 25);
+        checkCharStream(r, cl, 25, bytesPerChar);
 
         r = rs.getCharacterStream(2);
-        checkCharStream(r, vcl, -1);
+        checkCharStream(r, vcl, -1, bytesPerChar);
 
         r = rs.getCharacterStream(3);
-        checkCharStream(r, lvcl, -1);
+        checkCharStream(r, lvcl, -1, bytesPerChar);
 
         r = rs.getCharacterStream(4);
-        checkCharStream(r, lob, -1);
+        checkCharStream(r, lob, -1, bytesPerChar);
 
         rs.close();
 
@@ -609,19 +650,19 @@
 
         String suv = rs.getString(1);
         r = new StringReader(suv);
-        checkCharStream(r, cl, 25);
+        checkCharStream(r, cl, 25, bytesPerChar);
 
         suv = rs.getString(2);
         r = new StringReader(suv);
-        checkCharStream(r, vcl, -1);
+        checkCharStream(r, vcl, -1, bytesPerChar);
 
         suv = rs.getString(3);
         r = new StringReader(suv);
-        checkCharStream(r, lvcl, -1);
+        checkCharStream(r, lvcl, -1, bytesPerChar);
 
         suv = rs.getString(4);
         r = new StringReader(suv);
-        checkCharStream(r, lob, -1);
+        checkCharStream(r, lob, -1, bytesPerChar);
 
         rs.close();
 
@@ -703,11 +744,12 @@
         r.close();
     }
 
-    private void checkCharStream(InputStream is, int length, int fixedLen)
+    private void checkCharStream(InputStream is, int length, int fixedLen,
+                                 int bytesPerChar)
             throws IOException
     {
 
-        Reader orig = new c3Reader(length);
+        Reader orig = getSourceStream(length, bytesPerChar);
 
         int count = 0;
         for (;;) {
@@ -748,11 +790,12 @@
         is.close();
     }
 
-    private void checkCharStream(Reader r, int length, int fixedLen)
+    private void checkCharStream(Reader r, int length, int fixedLen,
+                                 int bytesPerChar)
             throws IOException
     {
 
-        Reader orig = new c3Reader(length);
+        Reader orig = getSourceStream(length, bytesPerChar);
 
         int count = 0;
         for (;;) {



Mime
View raw message