758 mark@stripped 2008-12-01
Fixed BUG#41161 - PreparedStatement.addBatch() doesn't check for all parameters
being set, which leads to a NullPointerException when calling executeBatch() and
rewriting batched statements into multi-value or multi-statement statements.
modified:
CHANGES
src/com/mysql/jdbc/PreparedStatement.java
src/testsuite/regression/StatementRegressionTest.java
757 mark@stripped 2008-12-01
Cleaner implementation of indexOfIgnoreCase().
modified:
src/com/mysql/jdbc/StringUtils.java
756 mark@stripped 2008-11-11
Disable nanos/micros for now
modified:
src/com/mysql/jdbc/PreparedStatement.java
=== modified file 'CHANGES'
--- a/CHANGES 2008-10-20 21:28:59 +0000
+++ b/CHANGES 2008-12-01 21:38:32 +0000
@@ -1,6 +1,10 @@
# Changelog
# $Id$
-
+nn-nn-08 - Version 5.1.8
+ - Fixed BUG#41161 - PreparedStatement.addBatch() doesn't check for all parameters
+ being set, which leads to a NullPointerException when calling executeBatch() and
+ rewriting batched statements into multi-value or multi-statement statements.
+
10-22-08 - Version 5.1.7
- Fixed BUG#33861 - Added global blacklist for LoadBalancingConnectionProxy and
implemented in RandomBalanceStrategy and BestResponseTimeBalanceStrategy.
=== modified file 'src/com/mysql/jdbc/PreparedStatement.java'
--- a/src/com/mysql/jdbc/PreparedStatement.java 2008-11-11 07:03:11 +0000
+++ b/src/com/mysql/jdbc/PreparedStatement.java 2008-12-01 21:38:32 +0000
@@ -692,6 +692,11 @@ public class PreparedStatement extends c
this.batchedArgs = new ArrayList();
}
+ for (int i = 0; i < this.parameterValues.length; i++) {
+ checkAllParametersSet(this.parameterValues[i],
+ this.parameterStreams[i], i);
+ }
+
this.batchedArgs.add(new BatchParams(this.parameterValues,
this.parameterStreams, this.isStream, this.streamLengths,
this.isNull));
@@ -2209,12 +2214,8 @@ public class PreparedStatement extends c
}
for (int i = 0; i < batchedParameterStrings.length; i++) {
- if ((batchedParameterStrings[i] == null)
- && (batchedParameterStreams[i] == null)) {
- throw SQLError.createSQLException(Messages
- .getString("PreparedStatement.40") //$NON-NLS-1$
- + (i + 1), SQLError.SQL_STATE_WRONG_NO_OF_PARAMETERS, getExceptionInterceptor());
- }
+ checkAllParametersSet(batchedParameterStrings[i],
+ batchedParameterStreams[i], i);
sendPacket.writeBytesNoNull(this.staticSqlStrings[i]);
@@ -2232,6 +2233,16 @@ public class PreparedStatement extends c
return sendPacket;
}
+ private void checkAllParametersSet(byte[] parameterString,
+ InputStream parameterStream, int columnIndex) throws SQLException {
+ if ((parameterString == null)
+ && parameterStream == null) {
+ throw SQLError.createSQLException(Messages
+ .getString("PreparedStatement.40") //$NON-NLS-1$
+ + (columnIndex + 1), SQLError.SQL_STATE_WRONG_NO_OF_PARAMETERS, getExceptionInterceptor());
+ }
+ }
+
private String generateBatchedInsertSQL(String valuesClause, int numBatches) {
StringBuffer newStatementSql = new StringBuffer(this.originalSql
.length()
=== modified file 'src/com/mysql/jdbc/StringUtils.java'
--- a/src/com/mysql/jdbc/StringUtils.java 2008-11-11 06:19:59 +0000
+++ b/src/com/mysql/jdbc/StringUtils.java 2008-12-01 20:40:15 +0000
@@ -929,8 +929,6 @@ public class StringUtils {
int stringLength = searchIn.length();
int stopSearchingAt = stringLength - patternLength;
- int i = startingPosition;
-
if (patternLength == 0) {
return -1;
}
@@ -940,49 +938,38 @@ public class StringUtils {
char firstCharOfPatternUc = Character.toUpperCase(searchFor.charAt(0));
char firstCharOfPatternLc = Character.toLowerCase(searchFor.charAt(0));
- lookForFirstChar: while (true) {
- while ((i < stopSearchingAt)
- && (Character.toUpperCase(searchIn.charAt(i)) != firstCharOfPatternUc)
- && Character.toLowerCase(searchIn.charAt(i)) != firstCharOfPatternLc) {
- i++;
- }
-
- if (i > stopSearchingAt) {
- return -1;
- }
-
- int j = i + 1;
- int end = (j + patternLength) - 1;
-
- int k = 1; // start at second char of pattern
-
- while (j < end) {
- int searchInPos = j++;
- int searchForPos = k++;
-
- if (Character.toUpperCase(searchIn.charAt(searchInPos)) != Character
- .toUpperCase(searchFor.charAt(searchForPos))) {
- i++;
-
- // start over
- continue lookForFirstChar;
- }
-
- // Georgian and Turkish locales don't have same convention, so
- // need to check lowercase
- // too!
- if (Character.toLowerCase(searchIn.charAt(searchInPos)) != Character
- .toLowerCase(searchFor.charAt(searchForPos))) {
- i++;
-
- // start over
- continue lookForFirstChar;
- }
- }
-
- return i; // found entire pattern
- }
+ // note, this also catches the case where patternLength > stringLength
+ for (int i = startingPosition; i <= stopSearchingAt; i++) {
+ if (isNotEqualIgnoreCharCase(searchIn, firstCharOfPatternUc,
+ firstCharOfPatternLc, i)) {
+ // find the first occurrence of the first character of searchFor in searchIn
+ while (++i <= stopSearchingAt && (isNotEqualIgnoreCharCase(searchIn, firstCharOfPatternUc,
+ firstCharOfPatternLc, i)));
+ }
+
+ if (i <= stopSearchingAt /* searchFor might be one character long! */) {
+ // walk searchIn and searchFor in lock-step starting just past the first match,bail out if not
+ // a match, or we've hit the end of searchFor...
+ int j = i + 1;
+ int end = j + patternLength - 1;
+ for (int k = 1; j < end && (Character.toLowerCase(searchIn.charAt(j)) ==
+ Character.toLowerCase(searchFor.charAt(k)) || Character.toUpperCase(searchIn.charAt(j)) ==
+ Character.toUpperCase(searchFor.charAt(k))); j++, k++);
+
+ if (j == end) {
+ return i;
+ }
+ }
+ }
+
+ return -1;
+ }
+
+ private final static boolean isNotEqualIgnoreCharCase(String searchIn,
+ char firstCharOfPatternUc, char firstCharOfPatternLc, int i) {
+ return Character.toLowerCase(searchIn.charAt(i)) != firstCharOfPatternLc && Character.toUpperCase(searchIn.charAt(i)) != firstCharOfPatternUc;
}
+
/**
* DOCUMENT ME!
=== modified file 'src/testsuite/regression/StatementRegressionTest.java'
--- a/src/testsuite/regression/StatementRegressionTest.java 2008-11-11 06:19:18 +0000
+++ b/src/testsuite/regression/StatementRegressionTest.java 2008-12-01 21:38:32 +0000
@@ -5659,4 +5659,29 @@ public class StatementRegressionTest ext
closeMemberJDBCResources();
}
}
+
+ public void testBug41161() throws Exception {
+ createTable("testBug41161", "(a int, b int)");
+
+ Connection rewriteConn = getConnectionWithProps("rewriteBatchedStatements=true");
+
+ try {
+ this.pstmt = rewriteConn.prepareStatement("INSERT INTO testBug41161 (a, b) VALUES (?, ?, ?)");
+ this.pstmt.setInt(1, 1);
+ this.pstmt.setInt(2, 1);
+
+ try {
+ this.pstmt.addBatch();
+ fail("Should have thrown an exception");
+ } catch (SQLException sqlEx) {
+ assertEquals("07001", sqlEx.getSQLState());
+ }
+
+ this.pstmt.executeBatch(); // NPE when this bug exists
+ } finally {
+ closeMemberJDBCResources();
+
+ rewriteConn.close();
+ }
+ }
}
\ No newline at end of file
| Thread |
|---|
| • bzr push into connector-j/branches/branch_5_1 branch (mark:756 to 758)Bug#41161 | mark | 1 Dec |