From 03dedd74a0c575d2bf0e88a43f7766f41ef5391d Mon Sep 17 00:00:00 2001 From: Axyoan Marcelo Date: Thu, 12 Sep 2024 13:53:28 -0600 Subject: [PATCH] Fix for Bug#96623 (Bug#30221117), batch update with rewriteBatchedStatements&useServerPrepStmts send fail request. Change-Id: I938dde221f3a246906f10c367c28be1bb02301b8 --- CHANGES | 2 + .../com/mysql/cj/jdbc/ConnectionImpl.java | 3 +- .../cj/jdbc/ServerPreparedStatement.java | 2 +- .../regression/StatementRegressionTest.java | 58 +++++++++++++++++++ 4 files changed, 63 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 18ea0487a..ed9e35e57 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,8 @@ Version 9.1.0 + - Fix for Bug#96623 (Bug#30221117), batch update with rewriteBatchedStatements&useServerPrepStmts send fail request. + - Fix for Bug#114705 (Bug#36539680), Contribution: make trustStorePassword be null if this.trustStoreSettings.keyStorePassword is null. Thanks to Jesper Blomquist for his contribution. diff --git a/src/main/user-impl/java/com/mysql/cj/jdbc/ConnectionImpl.java b/src/main/user-impl/java/com/mysql/cj/jdbc/ConnectionImpl.java index 248b64884..dff113b10 100644 --- a/src/main/user-impl/java/com/mysql/cj/jdbc/ConnectionImpl.java +++ b/src/main/user-impl/java/com/mysql/cj/jdbc/ConnectionImpl.java @@ -495,7 +495,8 @@ private boolean canHandleAsServerPreparedStatement(String sql) throws SQLExcepti return false; } - boolean allowMultiQueries = this.propertySet.getBooleanProperty(PropertyKey.allowMultiQueries).getValue(); + boolean allowMultiQueries = this.propertySet.getBooleanProperty(PropertyKey.allowMultiQueries).getValue() + || this.propertySet.getBooleanProperty(PropertyKey.rewriteBatchedStatements).getValue(); if (this.cachePrepStmts.getValue()) { this.serverSideStatementCheckCacheLock.lock(); diff --git a/src/main/user-impl/java/com/mysql/cj/jdbc/ServerPreparedStatement.java b/src/main/user-impl/java/com/mysql/cj/jdbc/ServerPreparedStatement.java index 18a2f6bae..704a7263d 100644 --- a/src/main/user-impl/java/com/mysql/cj/jdbc/ServerPreparedStatement.java +++ b/src/main/user-impl/java/com/mysql/cj/jdbc/ServerPreparedStatement.java @@ -625,7 +625,7 @@ protected void serverPrepare(String sql) throws SQLException { t = SQLError.createCommunicationsException(this.connection, this.session.getProtocol().getPacketSentTimeHolder(), this.session.getProtocol().getPacketReceivedTimeHolder(), ioEx, this.exceptionInterceptor); } catch (CJException sqlEx) { - SQLException ex = SQLExceptionsMapping.translateException(sqlEx); + SQLException ex = SQLExceptionsMapping.translateException(sqlEx, this.exceptionInterceptor); if (this.dumpQueriesOnException.getValue()) { StringBuilder messageBuf = new StringBuilder(((PreparedQuery) this.query).getOriginalSql().length() + 32); diff --git a/src/test/java/testsuite/regression/StatementRegressionTest.java b/src/test/java/testsuite/regression/StatementRegressionTest.java index d7d074770..f4b0ca2d0 100644 --- a/src/test/java/testsuite/regression/StatementRegressionTest.java +++ b/src/test/java/testsuite/regression/StatementRegressionTest.java @@ -123,6 +123,7 @@ import com.mysql.cj.conf.PropertySet; import com.mysql.cj.exceptions.CJCommunicationsException; import com.mysql.cj.exceptions.ExceptionFactory; +import com.mysql.cj.exceptions.ExceptionInterceptor; import com.mysql.cj.exceptions.MysqlErrorNumbers; import com.mysql.cj.exceptions.WrongArgumentException; import com.mysql.cj.interceptors.QueryInterceptor; @@ -13929,4 +13930,61 @@ public T preProcess(Supplier sql, Query intercepte } + /** + * Tests fix for Bug#96623 (Bug#30221117), batch update with rewriteBatchedStatements&useServerPrepStmts send fail request. + * + * @throws Exception + */ + @Test + public void testBug96623() throws Exception { + boolean allowMQ = false; + boolean rwBS = false; + boolean useSPS = false; + boolean cachePS = false; + + createTable("testBug96623", "(c0 int)"); + do { + Properties props = new Properties(); + props.setProperty(PropertyKey.allowMultiQueries.getKeyName(), Boolean.toString(allowMQ)); + props.setProperty(PropertyKey.rewriteBatchedStatements.getKeyName(), Boolean.toString(rwBS)); + props.setProperty(PropertyKey.useServerPrepStmts.getKeyName(), Boolean.toString(useSPS)); + props.setProperty(PropertyKey.cachePrepStmts.getKeyName(), Boolean.toString(cachePS)); + props.setProperty(PropertyKey.emulateUnsupportedPstmts.getKeyName(), "true"); + props.setProperty(PropertyKey.exceptionInterceptors.getKeyName(), TestBug96623ExceptionInterceptor.class.getName()); + + TestBug96623ExceptionInterceptor.testCase = String.format("Case [allowMQ: %s, rwBS: %s, useSPS: %s, cachePS: %s]", allowMQ ? "Y" : "N", + rwBS ? "Y" : "N", useSPS ? "Y" : "N", cachePS ? "Y" : "N"); + + try (Connection testConn = getConnectionWithProps(props); PreparedStatement ps = testConn.prepareStatement("UPDATE testBug96623 SET c0=?")) { + for (int i = 0; i < 4; i++) { + ps.setInt(1, i); + ps.addBatch(); + } + + ps.executeBatch(); + } + } while ((allowMQ = !allowMQ) || (rwBS = !rwBS) || (useSPS = !useSPS) || (cachePS = !cachePS)); + } + + public static class TestBug96623ExceptionInterceptor implements ExceptionInterceptor { + + static String testCase = null; + + @Override + public ExceptionInterceptor init(Properties props, Log log) { + return this; + } + + @Override + public void destroy() { + } + + @Override + public SQLException interceptException(Exception sqlEx) { + assertFalse(sqlEx instanceof SQLSyntaxErrorException, testCase); + return null; + } + + } + } \ No newline at end of file