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 ma...@apache.org on 2013/06/03 22:56:35 UTC
svn commit: r1489169 - in
/db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests:
tests/jdbcapi/ParameterMappingTest.java util/streams/CharAlphabet.java
Author: mamta
Date: Mon Jun 3 20:56:35 2013
New Revision: 1489169
URL: http://svn.apache.org/r1489169
Log:
DERBY-6237(PreparedStatement.execute() fails starting 10.2 when multiple rows are updated and PreparedStatement.setCharacterStream(int, Reader, int) is used)
This commit tests setCharacterStream on CLOB and VARCHAR columns as 2 separate tests. This way failure of one data type will not mask the behavior of the other data type.
I found through these tests that in 10.8,
1)setCharacterStream on VARCHAR columns work fine(just like 10.1 through 10.7 releases) for both one row and multi-row update through prepared statement.
2)But setCharacterStream on CLOB column when update touches more than one row(both for embedded and network server) fails in 10.8 release.
Modified:
db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ParameterMappingTest.java
db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/util/streams/CharAlphabet.java
Modified: db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ParameterMappingTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ParameterMappingTest.java?rev=1489169&r1=1489168&r2=1489169&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ParameterMappingTest.java (original)
+++ db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ParameterMappingTest.java Mon Jun 3 20:56:35 2013
@@ -21,6 +21,8 @@
package org.apache.derbyTesting.functionTests.tests.jdbcapi;
import java.io.IOException;
+
+import java.io.CharArrayReader;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
@@ -38,6 +40,7 @@ import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
+import java.util.Arrays;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -51,6 +54,9 @@ import org.apache.derbyTesting.junit.Uti
import org.apache.derby.iapi.types.HarmonySerialBlob;
import org.apache.derby.iapi.types.HarmonySerialClob;
+import org.apache.derbyTesting.functionTests.util.streams.CharAlphabet;
+import org.apache.derbyTesting.functionTests.util.streams.LoopingAlphabetReader;
+
/**
*
*/
@@ -4253,6 +4259,196 @@ public class ParameterMappingTest extend
assertCompileError( sqlState, query );
}
+
+ private static boolean compareClobReader2CharArray
+ (char[] cArray, Reader charReader) throws Exception {
+ char[] clobChars = new char[cArray.length];
+
+ int readChars = 0;
+ int totalCharsRead = 0;
+
+ do {
+ readChars = charReader.read(clobChars, totalCharsRead, cArray.length - totalCharsRead);
+ if (readChars != -1)
+ totalCharsRead += readChars;
+ } while (readChars != -1 && totalCharsRead < cArray.length);
+ charReader.close();
+ if (!java.util.Arrays.equals(cArray, clobChars)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * DERBY-6237(PreparedStatement.execute() fails starting 10.2 when
+ * multiple rows are updated and
+ * PreparedStatement.setCharacterStream(int, Reader, int) is used)
+ * Test setCharacterStream on CLOB column
+ */
+ public void testUpdateSetCharacterStreamClob() throws Exception
+ {
+ helperTestClobOrVarchar(true);
+ }
+
+ /**
+ * DERBY-6237(PreparedStatement.execute() fails starting 10.2 when
+ * multiple rows are updated and
+ * PreparedStatement.setCharacterStream(int, Reader, int) is used)
+ * Test setCharacterStream on VARCHAR column
+ */
+ public void testUpdateSetCharacterStreamVarchar() throws Exception
+ {
+ helperTestClobOrVarchar(false);
+ }
+
+ /**
+ * DERBY-6237(PreparedStatement.execute() fails starting 10.2 when
+ * multiple rows are updated and
+ * PreparedStatement.setCharacterStream(int, Reader, int) is used)
+ * In 10.1, setCharacterStream to update CLOB and varchar columns
+ * work even when update is going to update more than one row
+ *
+ * @param conn - Connection object
+ * @param testCLOB - true means test setCharacterStream on CLOB
+ * - false means test setCharacterStream on VARCHAR
+ * @throws Exception
+ */
+ private void helperTestClobOrVarchar(
+ boolean testCLOB) throws Exception
+ {
+ Statement s = createStatement();
+ dropTable("TESTUPDATECHARSTREAM");
+ s.executeUpdate("CREATE TABLE TestUpdateCharStream ("+
+ "c1 VARCHAR(64) NOT NULL, " +
+ "c2 INTEGER, " +
+ "c3 CLOB, " +
+ "c4 VARCHAR(32000))");
+ s.executeUpdate("INSERT INTO TestUpdateCharStream (c1, c2) " +
+ "VALUES ('AAAAA', 1)");
+ s.executeUpdate("INSERT INTO TestUpdateCharStream (c1, c2) " +
+ "VALUES ('EEEEE', 1)");
+
+ //update only one row and use short data
+ helperTestDerby6237(1,1, testCLOB);
+ //update only one row and use large data
+ helperTestDerby6237(1,2, testCLOB);
+ //update two rows and use short data
+ //Once DERBY-6237 is fixed, we should remove following if condition
+ // Following if condition will skip the test for 2 row update when
+ // testing CLOB columns in both embedded and network server with
+ // short data. This results in failure in 10.6
+ if ((!testCLOB))
+ helperTestDerby6237(2,1, testCLOB);
+ //update two rows and use large data
+ //Once DERBY-6237 is fixed, we should remove following if condition
+ // Following if condition will skip the test for 2 row update when
+ // testing CLOB columns in both embedded and network server with
+ // large data. This results in failure in 10.6
+ if (!(testCLOB))
+ helperTestDerby6237(2,2, testCLOB);
+
+ dropTable("TESTUPDATECHARSTREAM");
+ s.close();
+ }
+
+ //numberOfRowsToUpdate - value 1 or 2
+ //testVariation - if 1 then update CLOB/VARCHAR with short data
+ // if 2 then update CLOB/VARCHAR with large data
+ //testCLOB - true means test setCharacterStream on CLOB
+ // - false means test setCharacterStream on VARCHAR
+ private void helperTestDerby6237(int numberOfRowsToUpdate,
+ int testVariation,
+ boolean testCLOB) throws Exception
+ {
+ CharAlphabet a1 = CharAlphabet.singleChar('a');
+
+ //Following will update one or 2 rows depending on the 1st param
+ //Following will update CLOB column or VARCHAR column with short
+ // or large data depending on param 2
+ //Following will update CLOB column or VARCHAR column depending
+ // on 3rd param
+ PreparedStatement ps = prepareStatement(
+ "UPDATE TestUpdateCharStream SET " +
+ (testCLOB==true ? "c3" : "c4") + " = ?, " +
+ "c2 = c2 + 1 WHERE c1 IN (?, ?)");
+ switch (testVariation) {
+ case 1 :
+ //test short data
+ ps.setCharacterStream(1,
+ new LoopingAlphabetReader(50, a1), 50);
+ break;
+ case 2 :
+ //test large data
+ if (testCLOB) {
+ //for CLOB column, use 50K data
+ ps.setCharacterStream(1,
+ new LoopingAlphabetReader(50000, a1), 50000);
+ } else {
+ //for VARCHAR column, use 32K data
+ ps.setCharacterStream(1,
+ new LoopingAlphabetReader(32000, a1), 32000);
+ }
+ break;
+ }
+
+ //First value in IN clause is getting set to 'AAAAA'
+ // Using setCharacterStream on VARCHAR to set the value
+ ps.setCharacterStream(2, new CharArrayReader("AAAAA".toCharArray()), 5);
+
+ if (numberOfRowsToUpdate == 1 ) {
+ //Second value in IN clause is also getting set to 'AAAAA', which
+ // means prepared statement will update only one row
+ ps.setObject(3, "AAAAA", Types.VARCHAR);
+ } else {
+ //Second value in IN clause is also getting set to 'EEEEE', which
+ // means prepared statement will update two rows
+ ps.setObject(3, "EEEEE", Types.VARCHAR);
+ }
+ ps.execute();
+
+ //verify updated data. Update happened to either CLOB column or VARCHAR
+ // column. It is decided by param 3
+ ResultSet rs;
+ ps = prepareStatement(
+ "select " +
+ (testCLOB==true ? "c3 " : "c4 ") +
+ "from TestUpdateCharStream " +
+ "WHERE c1 IN (?, ?)");
+ ps.setCharacterStream(1, new CharArrayReader("AAAAA".toCharArray()), 5);
+ if (numberOfRowsToUpdate == 1 ) {
+ ps.setObject(2, "AAAAA", Types.VARCHAR);
+ } else {
+ ps.setObject(2, "EEEEE", Types.VARCHAR);
+ }
+ rs = ps.executeQuery();
+ char[] c;
+ if (testVariation == 1){
+ //we are here to test short data
+ c = new char[50];
+ } else {
+ //we are here to test large data
+ if (testCLOB)
+ c = new char[50000];
+ else
+ c = new char[32000];
+ }
+ Arrays.fill(c, 'a');
+ for (int i=0;i<numberOfRowsToUpdate;i++) {
+ rs.next();
+ if (!compareClobReader2CharArray(c,rs.getCharacterStream(1))) {
+ System.out.println("FAIL: " +
+ (testCLOB ? "CLOB " : "VARCHAR ") + "data should have matched");
+ rs.close();
+ ps.close();
+ return;
+ }
+ }
+ rs.close();
+ ps.close();
+
+ }
+
}
Modified: db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/util/streams/CharAlphabet.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/util/streams/CharAlphabet.java?rev=1489169&r1=1489168&r2=1489169&view=diff
==============================================================================
--- db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/util/streams/CharAlphabet.java (original)
+++ db/derby/code/branches/10.8/java/testing/org/apache/derbyTesting/functionTests/util/streams/CharAlphabet.java Mon Jun 3 20:56:35 2013
@@ -92,6 +92,13 @@ public class CharAlphabet {
return new CharAlphabet("Tamil", CharAlphabet.TAMIL);
}
+ /**
+ * Get an alphabet consisting of a single character.
+ */
+ public static CharAlphabet singleChar(char ch) {
+ return new CharAlphabet("Single char: " + ch, new char[] { ch });
+ }
+
/** Name of the alphabet. */
private final String name;
/** Characters in the alphabet. */