Modified:
branches/branch_5_0/connector-j/CHANGES
branches/branch_5_0/connector-j/src/com/mysql/jdbc/PreparedStatement.java
branches/branch_5_0/connector-j/src/testsuite/regression/StatementRegressionTest.java
Log:
Fixed BUG#25025 - Client-side prepared statement parser gets confused by
in-line (/* ... */) comments and therefore can't rewrite batched statements
or reliably detect type of statements when they're used.
Modified: branches/branch_5_0/connector-j/CHANGES
===================================================================
--- branches/branch_5_0/connector-j/CHANGES 2007-01-04 01:03:01 UTC (rev 6253)
+++ branches/branch_5_0/connector-j/CHANGES 2007-01-04 18:22:41 UTC (rev 6254)
@@ -39,7 +39,11 @@
INFORMATION_SCHEMA didn't have references to current connections,
sometimes leading to NullPointerExceptions when intropsecting them via
ResultSetMetaData.
-
+
+ - Fixed BUG#25025 - Client-side prepared statement parser gets confused by
+ in-line (/* ... */) comments and therefore can't rewrite batched statements
+ or reliably detect type of statements when they're used.
+
10-20-06 - Version 5.0.4
- Fixed BUG#21379 - column names don't match metadata in cases
Modified: branches/branch_5_0/connector-j/src/com/mysql/jdbc/PreparedStatement.java
===================================================================
--- branches/branch_5_0/connector-j/src/com/mysql/jdbc/PreparedStatement.java 2007-01-04 01:03:01 UTC (rev 6253)
+++ branches/branch_5_0/connector-j/src/com/mysql/jdbc/PreparedStatement.java 2007-01-04 18:22:41 UTC (rev 6254)
@@ -135,6 +135,8 @@
long lastUsed = 0;
int statementLength = 0;
+
+ int statementStartPos = 0;
byte[][] staticSql = null;
@@ -177,7 +179,22 @@
boolean noBackslashEscapes = connection.isNoBackslashEscapesSet();
- for (i = 0; i < this.statementLength; ++i) {
+ // we're not trying to be real pedantic here, but we'd like to
+ // skip comments at the beginning of statements, as frameworks
+ // such as Hibernate use them to aid in debugging
+
+ if (StringUtils.startsWithIgnoreCaseAndWs(sql, "/*")) {
+ statementStartPos = sql.indexOf("*/");
+
+ if (statementStartPos == -1) {
+ statementStartPos = 0;
+ } else {
+ statementStartPos += 2;
+ }
+ }
+
+
+ for (i = statementStartPos; i < this.statementLength; ++i) {
char c = sql.charAt(i);
if ((this.firstStmtChar == 0) && !Character.isWhitespace(c)) {
@@ -401,7 +418,22 @@
private String batchedValuesClause;
+ /** Where does the statement text actually start? */
+
+ private int statementAfterCommentsPos;
+
/**
+ * have we checked whether we can rewrite this statement as a multi-value
+ * insert?
+ */
+
+ private boolean hasCheckedForRewrite = false;
+
+ /** Can we actually rewrite this statement as a multi-value insert? */
+
+ private boolean canRewrite = false;
+
+ /**
* Constructor used by server-side prepared statements
*
* @param conn
@@ -844,8 +876,9 @@
if (!this.batchHasPlainStatements
&& this.connection.getRewriteBatchedStatements()) {
- if (StringUtils.startsWithIgnoreCaseAndWs(this.originalSql,
- "INSERT")) {
+
+
+ if (canRewriteAsMultivalueInsertStatement()) {
return executeBatchedInserts();
}
}
@@ -857,6 +890,16 @@
}
}
+ public synchronized boolean canRewriteAsMultivalueInsertStatement() {
+ if (!this.hasCheckedForRewrite) {
+ this.canRewrite = StringUtils.startsWithIgnoreCaseAndWs(
+ this.originalSql, "INSERT", this.statementAfterCommentsPos);
+ this.hasCheckedForRewrite = true;
+ }
+
+ return this.canRewrite;
+ }
+
/**
* Rewrites the already prepared statement into a multi-value insert
* statement of 'statementsPerBatch' values and executes the entire batch
@@ -1450,10 +1493,12 @@
int indexOfValues = -1;
if (quoteCharStr.length() > 0) {
- indexOfValues = StringUtils.indexOfIgnoreCaseRespectQuotes(0,
+ indexOfValues = StringUtils.indexOfIgnoreCaseRespectQuotes(
+ this.statementAfterCommentsPos,
this.originalSql, "VALUES ", quoteCharStr.charAt(0), false);
} else {
- indexOfValues = StringUtils.indexOfIgnoreCase(0, this.originalSql,
+ indexOfValues = StringUtils.indexOfIgnoreCase(this.statementAfterCommentsPos,
+ this.originalSql,
"VALUES ");
}
@@ -1932,6 +1977,8 @@
for (int j = 0; j < this.parameterCount; j++) {
this.isStream[j] = false;
}
+
+ this.statementAfterCommentsPos = this.parseInfo.statementStartPos;
}
boolean isNull(int paramIndex) {
Modified: branches/branch_5_0/connector-j/src/testsuite/regression/StatementRegressionTest.java
===================================================================
--- branches/branch_5_0/connector-j/src/testsuite/regression/StatementRegressionTest.java 2007-01-04 01:03:01 UTC (rev 6253)
+++ branches/branch_5_0/connector-j/src/testsuite/regression/StatementRegressionTest.java 2007-01-04 18:22:41 UTC (rev 6254)
@@ -3689,4 +3689,49 @@
assertEquals(beforeOpenStatementCount, afterOpenStatementCount);
}
+
+ /**
+ * Tests fix for BUG#25025 - Client-side prepared statement parser gets confused by
+ * in-line (slash-star) comments and therefore can't rewrite batched statements or
+ * reliably detect type of statements when they're used.
+ *
+ * @throws Exception if the test fails.
+ */
+ public void testBug25025() throws Exception {
+
+ Connection multiConn = null;
+
+ createTable("testBug25025", "(field1 INT)");
+
+ try {
+ Properties props = new Properties();
+ props.setProperty("rewriteBatchedStatements", "true");
+ props.setProperty("useServerPrepStmts", "false");
+
+ multiConn = getConnectionWithProps(props);
+
+ this.pstmt = multiConn.prepareStatement("/* insert foo.bar.baz INSERT INTO foo VALUES (?,?,?,?) to trick parser */ INSERT into testBug25025 VALUES (?)");
+ this.pstmt.setInt(1, 1);
+ this.pstmt.addBatch();
+ this.pstmt.setInt(1, 2);
+ this.pstmt.addBatch();
+ this.pstmt.setInt(1, 3);
+ this.pstmt.addBatch();
+
+ int[] counts = this.pstmt.executeBatch();
+
+ assertEquals(3, counts.length);
+ assertEquals(1, counts[0]);
+ assertEquals(1, counts[1]);
+ assertEquals(1, counts[2]);
+ assertEquals(true,
+ ((com.mysql.jdbc.PreparedStatement)this.pstmt).canRewriteAsMultivalueInsertStatement());
+ } finally {
+ closeMemberJDBCResources();
+
+ if (multiConn != null) {
+ multiConn.close();
+ }
+ }
+ }
}
Thread |
---|
• Connector/J commit: r6254 - in branches/branch_5_0/connector-j: . src/com/mysql/jdbc src/testsuite/regression | mmatthews | 4 Jan |