From: Date: October 3 2007 8:53pm Subject: Connector/J commit: r6611 - in branches/branch_5_1/connector-j: . src/com/mysql/jdbc src/testsuite/regression List-Archive: http://lists.mysql.com/commits/34854 X-Bug: 28256 Message-Id: <200710031853.l93Irua0024774@bk-internal.mysql.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modified: branches/branch_5_1/connector-j/CHANGES branches/branch_5_1/connector-j/src/com/mysql/jdbc/PreparedStatement.java branches/branch_5_1/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java branches/branch_5_1/connector-j/src/com/mysql/jdbc/StatementImpl.java branches/branch_5_1/connector-j/src/com/mysql/jdbc/StringUtils.java branches/branch_5_1/connector-j/src/testsuite/regression/StatementRegressionTest.java Log: Fixed BUG#28256 - When connection is in read-only mode, queries that are wrapped in parentheses incorrectly identified as DML. Modified: branches/branch_5_1/connector-j/CHANGES =================================================================== --- branches/branch_5_1/connector-j/CHANGES 2007-10-03 16:46:01 UTC (rev 6610) +++ branches/branch_5_1/connector-j/CHANGES 2007-10-03 18:53:55 UTC (rev 6611) @@ -7,6 +7,10 @@ queries by those that are slower than 5 * stddev of the mean query time (outside the 96% percentile). + - Fixed BUG#28256 - When connection is in read-only mode, + queries that are wrapped in parentheses incorrectly identified + as DML. + 09-07-07 - Version 5.1.3 RC - Setting "useBlobToStoreUTF8OutsideBMP" to "true" tells the Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/PreparedStatement.java =================================================================== --- branches/branch_5_1/connector-j/src/com/mysql/jdbc/PreparedStatement.java 2007-10-03 16:46:01 UTC (rev 6610) +++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/PreparedStatement.java 2007-10-03 18:53:55 UTC (rev 6611) @@ -236,7 +236,7 @@ for (i = statementStartPos; i < this.statementLength; ++i) { char c = sql.charAt(i); - if ((this.firstStmtChar == 0) && !Character.isWhitespace(c)) { + if ((this.firstStmtChar == 0) && Character.isLetter(c)) { // Determine what kind of statement we're doing (_S_elect, // _I_nsert, etc.) this.firstStmtChar = Character.toUpperCase(c); Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java =================================================================== --- branches/branch_5_1/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java 2007-10-03 16:46:01 UTC (rev 6610) +++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/ServerPreparedStatement.java 2007-10-03 18:53:55 UTC (rev 6611) @@ -349,9 +349,12 @@ checkNullOrEmptyQuery(sql); - this.isSelectQuery = StringUtils.startsWithIgnoreCaseAndWs(sql, - "SELECT"); //$NON-NLS-1$ + int startOfStatement = findStartOfStatement(sql); + this.firstCharOfStmt = StringUtils.firstAlphaCharUc(sql, startOfStatement); + + this.isSelectQuery = 'S' == this.firstCharOfStmt; + if (this.connection.versionMeetsMinimum(5, 0, 0)) { this.serverNeedsResetBeforeEachExecution = !this.connection.versionMeetsMinimum(5, 0, 3); @@ -363,7 +366,7 @@ this.useAutoSlowLog = this.connection.getAutoSlowLog(); this.useTrueBoolean = this.connection.versionMeetsMinimum(3, 21, 23); this.hasLimitClause = (StringUtils.indexOfIgnoreCase(sql, "LIMIT") != -1); //$NON-NLS-1$ - this.firstCharOfStmt = StringUtils.firstNonWsCharUc(sql); + String statementComment = this.connection.getStatementComment(); this.originalSql = (statementComment == null) ? sql : "/* " Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/StatementImpl.java =================================================================== --- branches/branch_5_1/connector-j/src/com/mysql/jdbc/StatementImpl.java 2007-10-03 16:46:01 UTC (rev 6610) +++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/StatementImpl.java 2007-10-03 18:53:55 UTC (rev 6611) @@ -595,7 +595,7 @@ checkClosed(); - char firstNonWsChar = StringUtils.firstNonWsCharUc(sql); + char firstNonWsChar = StringUtils.firstAlphaCharUc(sql, findStartOfStatement(sql)); boolean isSelect = true; @@ -643,14 +643,14 @@ } } - if (firstNonWsChar == '/') { + if (sql.charAt(0) == '/') { if (sql.startsWith(PING_MARKER)) { doPingInstead(); return true; } } - + CachedResultSetMetaData cachedMetaData = null; ResultSetInternalMethods rs = null; @@ -1491,7 +1491,7 @@ ConnectionImpl locallyScopedConn = this.connection; - char firstStatementChar = StringUtils.firstNonWsCharUc(sql, + char firstStatementChar = StringUtils.firstAlphaCharUc(sql, findStartOfStatement(sql)); ResultSetInternalMethods rs = null; Modified: branches/branch_5_1/connector-j/src/com/mysql/jdbc/StringUtils.java =================================================================== --- branches/branch_5_1/connector-j/src/com/mysql/jdbc/StringUtils.java 2007-10-03 16:46:01 UTC (rev 6610) +++ branches/branch_5_1/connector-j/src/com/mysql/jdbc/StringUtils.java 2007-10-03 18:53:55 UTC (rev 6611) @@ -341,6 +341,24 @@ return 0; } + public static char firstAlphaCharUc(String searchIn, int startAt) { + if (searchIn == null) { + return 0; + } + + int length = searchIn.length(); + + for (int i = startAt; i < length; i++) { + char c = searchIn.charAt(i); + + if (Character.isLetter(c)) { + return Character.toUpperCase(c); + } + } + + return 0; + } + /** * Adds '+' to decimal numbers that are positive (MySQL doesn't understand * them otherwise Modified: branches/branch_5_1/connector-j/src/testsuite/regression/StatementRegressionTest.java =================================================================== --- branches/branch_5_1/connector-j/src/testsuite/regression/StatementRegressionTest.java 2007-10-03 16:46:01 UTC (rev 6610) +++ branches/branch_5_1/connector-j/src/testsuite/regression/StatementRegressionTest.java 2007-10-03 18:53:55 UTC (rev 6611) @@ -3887,6 +3887,24 @@ } /** + * Tests fix for BUG#28256 - When connection is in read-only + * mode, queries that are parentheized incorrectly identified + * as DML. + * + * @throws Exception + */ + public void testBug28256() throws Exception { + try { + this.conn.setReadOnly(true); + this.stmt.execute("(SELECT 1) UNION (SELECT 2)"); + this.conn.prepareStatement("(SELECT 1) UNION (SELECT 2)").execute(); + ((com.mysql.jdbc.Connection) this.conn).serverPrepareStatement("(SELECT 1) UNION (SELECT 2)").execute(); + } finally { + this.conn.setReadOnly(false); + } + } + + /** * Tests fix for BUG#28469 - PreparedStatement.getMetaData() * for statements containing leading one-line comments * is not returned correctly.