diff --git a/.travis.yml b/.travis.yml index 5c259a3ab..fcfa3446d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ cache: directories: - $HOME/.m2 jdk: - - oraclejdk9 +# - oraclejdk9 temporary disabled, because travis issue https://github.com/travis-ci/travis-ci/issues/7944 - oraclejdk8 env: - AURORA=true diff --git a/.travis/script.sh b/.travis/script.sh index 0846afbea..91d4f0e01 100644 --- a/.travis/script.sh +++ b/.travis/script.sh @@ -5,31 +5,31 @@ set -e case "$TYPE" in "MAXSCALE" ) - urlString=-DdbUrl='jdbc:mariadb://localhost:4006/testj?user=root&killFetchStmtOnClose=false' + urlString=-DdbUrl='jdbc:mariadb://localhost:4006/testj?user=root&killFetchStmtOnClose=false&enablePacketDebug=true' ;; "REWRITE" ) - urlString=-DdbUrl='jdbc:mariadb://localhost:3306/testj?user=root&rewriteBatchedStatements=true' + urlString=-DdbUrl='jdbc:mariadb://localhost:3306/testj?user=root&rewriteBatchedStatements=true&enablePacketDebug=true' ;; "PREPARE" ) - urlString=-DdbUrl='jdbc:mariadb://localhost:3306/testj?user=root&useServerPrepStmts=true' + urlString=-DdbUrl='jdbc:mariadb://localhost:3306/testj?user=root&useServerPrepStmts=true&enablePacketDebug=true' ;; "MULTI" ) - urlString=-DdbUrl='jdbc:mariadb://localhost:3306/testj?user=root&allowMultiQueries=true' + urlString=-DdbUrl='jdbc:mariadb://localhost:3306/testj?user=root&allowMultiQueries=true&enablePacketDebug=true' ;; "BULK_SERVER" ) - urlString=-DdbUrl='jdbc:mariadb://localhost:3306/testj?user=root&useBatchMultiSend=true&useServerPrepStmts=true' + urlString=-DdbUrl='jdbc:mariadb://localhost:3306/testj?user=root&useBatchMultiSend=true&useServerPrepStmts=true&enablePacketDebug=true' ;; "NO_BULK_CLIENT" ) - urlString=-DdbUrl='jdbc:mariadb://localhost:3306/testj?user=root&useBatchMultiSend=false' + urlString=-DdbUrl='jdbc:mariadb://localhost:3306/testj?user=root&useBatchMultiSend=false&enablePacketDebug=true' ;; "NO_BULK_SERVER" ) - urlString=-DdbUrl='jdbc:mariadb://localhost:3306/testj?user=root&useBatchMultiSend=false&useServerPrepStmts=true' + urlString=-DdbUrl='jdbc:mariadb://localhost:3306/testj?user=root&useBatchMultiSend=false&useServerPrepStmts=true&enablePacketDebug=true' ;; "COMPRESSION" ) - urlString=-DdbUrl='jdbc:mariadb://localhost:3306/testj?user=root&useCompression=true' + urlString=-DdbUrl='jdbc:mariadb://localhost:3306/testj?user=root&useCompression=true&enablePacketDebug=true' ;; *) - urlString=-DdbUrl='jdbc:mariadb://localhost:3306/testj?user=root' + urlString=-DdbUrl='jdbc:mariadb://localhost:3306/testj?user=root&enablePacketDebug=true' ;; esac; diff --git a/README.md b/README.md index 50375b72e..7e13fa08e 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,8 @@ Tracker link https://ji | Java version | driver compatible version | |:------------:|:-------------------------:| -| 6 | up to 1.1.10 | -| 7 | up to 1.6.1 | +| 6 | < 2.0 version | +| 7 | < 2.0 version | | 8 | all version | The driver (jar) can be downloaded from [mariadb connector download](https://mariadb.com/products/connectors-plugins) @@ -31,7 +31,7 @@ or maven : org.mariadb.jdbc mariadb-java-client - 2.0.2 + 2.0.3 ``` diff --git a/documentation/changelog.creole b/documentation/changelog.creole index 5710f3713..6b7a25f80 100644 --- a/documentation/changelog.creole +++ b/documentation/changelog.creole @@ -1,4 +1,5 @@ = Changelog +* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#203|2.0.3]] Released on 27 Jun. 2017 * [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#202|2.0.2]] Released on 05 Jun. 2017 * [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#161|1.6.1]] Released on 05 Jun. 2017 * [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#201|2.0.1]] Released on 10 May 2017 @@ -23,6 +24,13 @@ * [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#140|1.4.0]] Released on 31 march 2016 --- + +== 2.0.3 +Bug +*[CONJ-473] when useServerPrepStmts is not set, the PREPARE statement must not be cached. +*[CONJ-494] Handle PrepareStatement.getParameterMetaData() if query cannot be PREPAREd +*[CONJ-497] escape string correction for big query + == 1.6.1 report of 2.0.2 corrections for jre 1.7 compatible version. diff --git a/mariadb-java-client.iml b/mariadb-java-client.iml index 8061e129b..1eaf12748 100644 --- a/mariadb-java-client.iml +++ b/mariadb-java-client.iml @@ -1,6 +1,6 @@ - + @@ -12,19 +12,23 @@ + + + + + + - - - - - + + + diff --git a/pom.xml b/pom.xml index f82161674..4e963760f 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ mariadb-java-client jar mariadb-java-client - 2.0.2 + 2.0.3 JDBC driver for MariaDB and MySQL https://mariadb.com/kb/en/mariadb/about-mariadb-connector-j/ @@ -71,7 +71,7 @@ 2.16 2 0 - 2 + 3 diff --git a/src/main/java/org/mariadb/jdbc/CallableProcedureStatement.java b/src/main/java/org/mariadb/jdbc/CallableProcedureStatement.java index d5d2e8b7e..960f88d93 100644 --- a/src/main/java/org/mariadb/jdbc/CallableProcedureStatement.java +++ b/src/main/java/org/mariadb/jdbc/CallableProcedureStatement.java @@ -101,6 +101,8 @@ public CallableProcedureStatement clone(MariaDbConnection connection) throws Clo CallableProcedureStatement clone = (CallableProcedureStatement) super.clone(connection); clone.params = params; clone.parameterMetadata = parameterMetadata; + clone.hasInOutParameters = hasInOutParameters; + clone.outputParameterMapper = outputParameterMapper; return clone; } diff --git a/src/main/java/org/mariadb/jdbc/MariaDbParameterMetaData.java b/src/main/java/org/mariadb/jdbc/MariaDbParameterMetaData.java index 7f858c862..e20f11ec2 100644 --- a/src/main/java/org/mariadb/jdbc/MariaDbParameterMetaData.java +++ b/src/main/java/org/mariadb/jdbc/MariaDbParameterMetaData.java @@ -70,7 +70,7 @@ public MariaDbParameterMetaData(ColumnInformation[] parametersInformation) { } private void checkAvailable() throws SQLException { - if(this.parametersInformation == null) { + if (this.parametersInformation == null) { throw new SQLException("Parameter metadata not available for these statement", "S1C00"); } } diff --git a/src/main/java/org/mariadb/jdbc/internal/io/output/AbstractPacketOutputStream.java b/src/main/java/org/mariadb/jdbc/internal/io/output/AbstractPacketOutputStream.java index 0d2622f8a..ae6fcb15f 100644 --- a/src/main/java/org/mariadb/jdbc/internal/io/output/AbstractPacketOutputStream.java +++ b/src/main/java/org/mariadb/jdbc/internal/io/output/AbstractPacketOutputStream.java @@ -639,9 +639,12 @@ public void write(Reader reader, long length, boolean escape, boolean noBackslas public void writeBytesEscaped(byte[] bytes, int len, boolean noBackslashEscapes) throws IOException { if (len * 2 > buf.length - pos) { + + //makes buffer bigger (up to 16M) if (buf.length != getMaxPacketLength()) growBuffer(len * 2); - //max buffer size + //data may be bigger than buffer. + //must flush buffer when full (and reset position to 0) if (len * 2 > buf.length - pos) { if (noBackslashEscapes) { for (int i = 0; i < len; i++) { @@ -658,7 +661,6 @@ public void writeBytesEscaped(byte[] bytes, int len, boolean noBackslashEscapes) || bytes[i] == SLASH || bytes[i] == DBL_QUOTE || bytes[i] == ZERO_BYTE) { - len -= 1; buf[pos++] = '\\'; if (buf.length <= pos) flushBuffer(false); } @@ -670,7 +672,7 @@ public void writeBytesEscaped(byte[] bytes, int len, boolean noBackslashEscapes) } } - //sure to have enough place + //sure to have enough place filling buffer directly if (noBackslashEscapes) { for (int i = 0; i < len; i++) { if (QUOTE == bytes[i]) buf[pos++] = QUOTE; diff --git a/src/main/java/org/mariadb/jdbc/internal/protocol/AbstractConnectProtocol.java b/src/main/java/org/mariadb/jdbc/internal/protocol/AbstractConnectProtocol.java index 247f79498..ae7993c3e 100644 --- a/src/main/java/org/mariadb/jdbc/internal/protocol/AbstractConnectProtocol.java +++ b/src/main/java/org/mariadb/jdbc/internal/protocol/AbstractConnectProtocol.java @@ -146,7 +146,7 @@ public abstract class AbstractConnectProtocol implements Protocol { private int patchVersion; private Map serverData; private TimeZone timeZone; - private LruTraceCache traceCache; + private LruTraceCache traceCache = new LruTraceCache(); /** * Get a protocol instance. @@ -220,8 +220,7 @@ public void close() { } if (options.enablePacketDebug) { - if (traceCache != null) traceCache.clearMemory(); - traceCache = null; + traceCache.clearMemory(); } } @@ -368,7 +367,8 @@ public void connect() throws SQLException { } catch (SQLException sqle) { throw sqle; } catch (IOException e) { - throw new SQLException("Could not connect to " + currentHost + ". " + e.getMessage(), CONNECTION_EXCEPTION.getSqlState(), e); + throw new SQLException("Could not connect to " + currentHost + ". " + e.getMessage() + getTraces(), + CONNECTION_EXCEPTION.getSqlState(), e); } } @@ -411,6 +411,10 @@ private void connect(String host, int port) throws SQLException, IOException { if (options.useCompression) { writer = new CompressPacketOutputStream(writer.getOutputStream(), options.maxQuerySizeToLog); reader = new DecompressPacketInputStream(((StandardPacketInputStream) reader).getBufferedInputStream(), options.maxQuerySizeToLog); + if (options.enablePacketDebug) { + writer.setTraceCache(traceCache); + reader.setTraceCache(traceCache); + } } if (options.usePipelineAuth && !options.createDatabaseIfNotExist) { @@ -432,12 +436,6 @@ private void connect(String host, int port) throws SQLException, IOException { // Extract socketTimeout URL parameter if (options.socketTimeout != null) socket.setSoTimeout(options.socketTimeout); - if (options.enablePacketDebug) { - traceCache = new LruTraceCache(); - writer.setTraceCache(traceCache); - reader.setTraceCache(traceCache); - } - reader.setServerThreadId(this.serverThreadId, isMasterConnection()); writer.setServerThreadId(this.serverThreadId, isMasterConnection()); @@ -485,8 +483,8 @@ private void sendSessionInfos() throws IOException { sessionOption.append(", sql_mode = concat(@@sql_mode,',STRICT_TRANS_TABLES')"); } - if (options.sessionVariables != null) { - sessionOption.append("," + options.sessionVariables); + if (options.sessionVariables != null && !options.sessionVariables.isEmpty()) { + sessionOption.append("," + Utils.parseSessionVariables(options.sessionVariables)); } writer.startPacket(0); @@ -654,6 +652,11 @@ private void handleConnectionPhases() throws SQLException { reader = new StandardPacketInputStream(socket.getInputStream(), options.maxQuerySizeToLog); writer = new StandardPacketOutputStream(socket.getOutputStream(), options.maxQuerySizeToLog); + if (options.enablePacketDebug) { + writer.setTraceCache(traceCache); + reader.setTraceCache(traceCache); + } + final ReadInitialHandShakePacket greetingPacket = new ReadInitialHandShakePacket(reader); this.serverThreadId = greetingPacket.getServerThreadId(); reader.setServerThreadId(this.serverThreadId, null); @@ -686,6 +689,10 @@ private void handleConnectionPhases() throws SQLException { writer = new StandardPacketOutputStream(socket.getOutputStream(), options.maxQuerySizeToLog); reader = new StandardPacketInputStream(socket.getInputStream(), options.maxQuerySizeToLog); + if (options.enablePacketDebug) { + writer.setTraceCache(traceCache); + reader.setTraceCache(traceCache); + } packetSeq++; } else if (options.useSsl) { throw new SQLException("Trying to connect with ssl, but ssl not enabled in the server"); @@ -1003,7 +1010,7 @@ public void connectWithoutProxy() throws SQLException { } catch (IOException e) { if (hosts.isEmpty()) { throw new SQLException("Could not connect to named pipe '" + options.pipe + "' : " - + e.getMessage(), CONNECTION_EXCEPTION.getSqlState(), e); + + e.getMessage() + getTraces(), CONNECTION_EXCEPTION.getSqlState(), e); } } } @@ -1025,7 +1032,7 @@ public void connectWithoutProxy() throws SQLException { throw sqle; } catch (IOException e) { if (hosts.isEmpty()) { - throw new SQLException("Could not connect to " + HostAddress.toString(addrs) + " : " + e.getMessage(), + throw new SQLException("Could not connect to " + HostAddress.toString(addrs) + " : " + e.getMessage() + getTraces(), CONNECTION_EXCEPTION.getSqlState(), e); } } diff --git a/src/main/java/org/mariadb/jdbc/internal/protocol/AbstractQueryProtocol.java b/src/main/java/org/mariadb/jdbc/internal/protocol/AbstractQueryProtocol.java index 8d062507a..1cfa4a817 100644 --- a/src/main/java/org/mariadb/jdbc/internal/protocol/AbstractQueryProtocol.java +++ b/src/main/java/org/mariadb/jdbc/internal/protocol/AbstractQueryProtocol.java @@ -1303,8 +1303,9 @@ public void readResultSet(Buffer buffer, Results results) throws SQLException { // - after a callable resultSet, a OK packet is send, but mysql does send the a bad "more result flag" Buffer bufferEof = reader.getPacket(true); if (bufferEof.readByte() != EOF) { - throw new SQLException("Packets out of order when reading field packets, expected was EOF stream. " - + "Packet contents (hex) = " + Utils.hexdump(options.maxQuerySizeToLog, 0, bufferEof.position, bufferEof.buf)); + throw new SQLException("Packets out of order when reading field packets, expected was EOF stream." + + ((options.enablePacketDebug) ? getTraces() : "Packet contents (hex) = " + + Utils.hexdump(options.maxQuerySizeToLog, 0, bufferEof.position, bufferEof.buf))); } bufferEof.skipBytes(2); //Skip warningCount callableResult = (bufferEof.readShort() & ServerStatus.PS_OUT_PARAMETERS) != 0; diff --git a/src/main/java/org/mariadb/jdbc/internal/util/DefaultOptions.java b/src/main/java/org/mariadb/jdbc/internal/util/DefaultOptions.java index 2c9c20d24..be1ee49fc 100644 --- a/src/main/java/org/mariadb/jdbc/internal/util/DefaultOptions.java +++ b/src/main/java/org/mariadb/jdbc/internal/util/DefaultOptions.java @@ -647,6 +647,9 @@ private static Options parse(HaMode haMode, Properties properties, Options optio //disable use server prepare id using client rewrite if (options.rewriteBatchedStatements) { options.useServerPrepStmts = false; + } + + if (!options.useServerPrepStmts) { options.cachePrepStmts = false; } diff --git a/src/main/java/org/mariadb/jdbc/internal/util/Utils.java b/src/main/java/org/mariadb/jdbc/internal/util/Utils.java index 40d1fd802..bf0eae194 100644 --- a/src/main/java/org/mariadb/jdbc/internal/util/Utils.java +++ b/src/main/java/org/mariadb/jdbc/internal/util/Utils.java @@ -718,5 +718,116 @@ protected static String getHex(final byte[] raw) { public static String byteArrayToHexString(final byte[] bytes) { return (bytes != null) ? getHex(bytes) : ""; - } + } + + + private enum Parse { + Normal, + Parenthesis, /* inside parenthesis */ + String, /* inside string */ + Quote, + Escape /* found backslash */ + } + + /** + * Parse the option "sessionVariable" to ensure having no injection. + * semi-column not in string will be replaced by comma. + * + * @param sessionVariable option value + * @return parsed String + */ + public static String parseSessionVariables(String sessionVariable) { + StringBuilder out = new StringBuilder(); + StringBuilder sb = new StringBuilder(); + Parse state = Parse.Normal; + boolean iskey = true; + boolean singleQuotes = true; + boolean first = true; + String key = null; + + char[] chars = sessionVariable.toCharArray(); + int length = chars.length; + + for (int i = 0; i < length; i++) { + + if (state == Parse.Escape) { + sb.append(chars[i]); + state = singleQuotes ? Parse.Quote : Parse.String; + continue; + } + + char car = chars[i]; + switch (car) { + case '"': + if (state == Parse.Normal) { + state = Parse.String; + singleQuotes = false; + } else if (state == Parse.String && !singleQuotes) { + state = Parse.Normal; + } + break; + + case '\'': + if (state == Parse.Normal) { + state = Parse.String; + singleQuotes = true; + } else if (state == Parse.String && singleQuotes) { + state = Parse.Normal; + } + break; + + case '\\': + if (state == Parse.String) state = Parse.Escape; + break; + + case ';': + case ',': + if (state == Parse.Normal) { + if (!iskey) { + if (!first) out.append(","); + out.append(key); + out.append(sb.toString()); + first = false; + } else { + key = sb.toString().trim(); + if (!key.isEmpty()) { + if (!first) out.append(","); + out.append(key); + first = false; + } + } + iskey = true; + key = null; + sb = new StringBuilder(); + continue; + } + break; + + case '=': + if (state == Parse.Normal && iskey) { + key = sb.toString().trim(); + iskey = false; + sb = new StringBuilder(); + } + break; + + default: + //nothing + } + + sb.append(car); + } + + if (!iskey) { + if (!first) out.append(","); + out.append(key); + out.append(sb.toString()); + } else { + String tmpkey = sb.toString().trim(); + if (!tmpkey.isEmpty() && !first) out.append(","); + out.append(tmpkey); + } + return out.toString(); + } + } diff --git a/src/main/java/org/mariadb/jdbc/internal/util/constant/Version.java b/src/main/java/org/mariadb/jdbc/internal/util/constant/Version.java index 794f03de6..1d29b3c75 100644 --- a/src/main/java/org/mariadb/jdbc/internal/util/constant/Version.java +++ b/src/main/java/org/mariadb/jdbc/internal/util/constant/Version.java @@ -53,9 +53,9 @@ package org.mariadb.jdbc.internal.util.constant; public final class Version { - public static final String version = "2.0.2"; + public static final String version = "2.0.3"; public static final int majorVersion = 2; public static final int minorVersion = 0; - public static final int patchVersion = 2; + public static final int patchVersion = 3; public static final String qualifier = ""; } \ No newline at end of file diff --git a/src/test/java/org/mariadb/jdbc/DataSourceTest.java b/src/test/java/org/mariadb/jdbc/DataSourceTest.java index 8268ae139..a12df5118 100644 --- a/src/test/java/org/mariadb/jdbc/DataSourceTest.java +++ b/src/test/java/org/mariadb/jdbc/DataSourceTest.java @@ -110,6 +110,7 @@ public void testDataSourceEmpty() throws SQLException { */ @Test public void setDatabaseNameTest() throws SQLException { + Assume.assumeFalse("MAXSCALE".equals(System.getenv("TYPE"))); MariaDbDataSource ds = new MariaDbDataSource(hostname == null ? "localhost" : hostname, port, database); try (Connection connection = ds.getConnection(username, password)) { connection.createStatement().execute("CREATE DATABASE IF NOT EXISTS test2"); diff --git a/src/test/java/org/mariadb/jdbc/DriverTest.java b/src/test/java/org/mariadb/jdbc/DriverTest.java index 9ec70617c..88889e069 100644 --- a/src/test/java/org/mariadb/jdbc/DriverTest.java +++ b/src/test/java/org/mariadb/jdbc/DriverTest.java @@ -52,6 +52,7 @@ package org.mariadb.jdbc; +import com.fasterxml.jackson.annotation.JsonTypeInfo; import org.junit.Assume; import org.junit.BeforeClass; import org.junit.Test; @@ -60,10 +61,8 @@ import java.math.BigDecimal; import java.sql.*; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.GregorianCalendar; +import java.sql.Date; +import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -199,13 +198,7 @@ public void preparedTest() throws SQLException { public void parameterMetaDataNotPreparable() throws SQLException { Assume.assumeFalse(sharedUsePrepare()); Statement stmt = sharedConnection.createStatement(); - ResultSet rs = stmt.executeQuery("SHOW SESSION STATUS WHERE Variable_name in ('Prepared_stmt_count','Com_stmt_prepare', 'Com_stmt_close')"); - rs.next(); - int preparedStmtCount = rs.getInt(2); - rs.next(); - int comStmtPrepare = rs.getInt(2); - rs.next(); - int comStmtClose = rs.getInt(2); + Map initValues = loadVariables(stmt); //statement that cannot be prepared try (PreparedStatement pstmt = sharedConnection.prepareStatement( @@ -217,16 +210,43 @@ public void parameterMetaDataNotPreparable() throws SQLException { } catch (SQLException sqle) { assertEquals("S1C00", sqle.getSQLState()); } - rs = stmt.executeQuery("SHOW SESSION STATUS WHERE Variable_name in ('Prepared_stmt_count','Com_stmt_prepare', 'Com_stmt_close')"); - rs.next(); - assertEquals(preparedStmtCount, rs.getInt(2)); - rs.next(); - assertEquals(comStmtPrepare + 1, rs.getInt(2)); - rs.next(); - assertEquals(comStmtClose, rs.getInt(2)); } + Map endingValues = loadVariables(stmt); + assertEquals(initValues.get("Prepared_stmt_count"), endingValues.get("Prepared_stmt_count")); + assertEquals((Integer) (initValues.get("Com_stmt_prepare") + 1), endingValues.get("Com_stmt_prepare")); + assertEquals(initValues.get("Com_stmt_close"), endingValues.get("Com_stmt_close")); } + private Map loadVariables(Statement stmt) throws SQLException { + Map variables = new HashMap(); + ResultSet rs = stmt.executeQuery("SHOW SESSION STATUS WHERE Variable_name in ('Prepared_stmt_count','Com_stmt_prepare', 'Com_stmt_close')"); + rs.next(); + variables.put(rs.getString(1), rs.getInt(2)); + rs.next(); + variables.put(rs.getString(1), rs.getInt(2)); + rs.next(); + variables.put(rs.getString(1), rs.getInt(2)); + return variables; + } + + @Test + public void parameterMetaDataPreparable() throws SQLException { + Assume.assumeFalse(sharedUsePrepare()); + Statement stmt = sharedConnection.createStatement(); + Map initValues = loadVariables(stmt); + + //statement that cannot be prepared + try (PreparedStatement pstmt = sharedConnection.prepareStatement( + "select ?")) { + ParameterMetaData parameterMetaData = pstmt.getParameterMetaData(); + parameterMetaData.getParameterCount(); + } + Map endingValues = loadVariables(stmt); + assertEquals(initValues.get("Prepared_stmt_count"), endingValues.get("Prepared_stmt_count")); + assertEquals((Integer) (initValues.get("Com_stmt_prepare") + 1), endingValues.get("Com_stmt_prepare")); + assertEquals((Integer) (initValues.get("Com_stmt_close") + 1), endingValues.get("Com_stmt_close")); + + } @Test public void streamingResultSet() throws Exception { @@ -1293,4 +1313,37 @@ public void run() { } } + /** + * CONJ-497 - Long escapable string. + * + * @throws SQLException exception + */ + @Test + public void testLongEscapes() throws SQLException { + //40m, because escaping will double the send byte numbers + Assume.assumeTrue(checkMaxAllowedPacketMore40m("testLongEscapes")); + createTable("testLongEscapes", "t1 longtext"); + + try (PreparedStatement preparedStatement = sharedConnection.prepareStatement( + "INSERT into testLongEscapes values (?)")) { + byte[] arr = new byte[20_000_000]; + Arrays.fill(arr, (byte) '\''); + preparedStatement.setBytes(1, arr); + preparedStatement.execute(); + + Arrays.fill(arr, (byte) '\"'); + preparedStatement.setBytes(1, arr); + preparedStatement.execute(); + } + + Statement stmt = sharedConnection.createStatement(); + try (ResultSet rs = stmt.executeQuery("select length(t1) from testLongEscapes")) { + assertTrue(rs.next()); + assertEquals(20_000_000, rs.getInt(1)); + assertTrue(rs.next()); + assertEquals(20_000_000, rs.getInt(1)); + assertFalse(rs.next()); + } + } + } diff --git a/src/test/java/org/mariadb/jdbc/ServerPrepareStatementTest.java b/src/test/java/org/mariadb/jdbc/ServerPrepareStatementTest.java index c00d2e4b4..674b48f03 100644 --- a/src/test/java/org/mariadb/jdbc/ServerPrepareStatementTest.java +++ b/src/test/java/org/mariadb/jdbc/ServerPrepareStatementTest.java @@ -121,7 +121,7 @@ public void serverExecutionTest() throws SQLException { rs = statement.executeQuery("show global status like 'Prepared_stmt_count'"); assertTrue(rs.next()); - assertTrue(rs.getInt(2) == nbStatementCount + 1); + assertEquals(rs.getInt(2), nbStatementCount + 1); } } @@ -500,26 +500,6 @@ private void assertYear(ResultSet rs, int fieldNumber, int comparaison) throws S } } - @Test - public void checkReusability() throws Throwable { - Assume.assumeTrue(!sharedIsRewrite()); - setConnection("&prepStmtCacheSize=10"); - ExecutorService exec = Executors.newFixedThreadPool(2); - - //check blacklist shared - exec.execute(new CreatePrepareDouble("INSERT INTO ServerPrepareStatementCacheSize2( test) VALUES (?)", - sharedConnection, 100, 100)); - exec.execute(new CreatePrepareDouble("INSERT INTO ServerPrepareStatementCacheSize2( test) VALUES (?)", - sharedConnection, 500, 100)); - //wait for thread endings - exec.shutdown(); - try { - exec.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); - } catch (InterruptedException e) { - //eat exception - } - } - @Test public void blobTest() throws Throwable { try (Connection connection = setConnection("&prepStmtCacheSize=10")) { @@ -903,46 +883,6 @@ public void run() { } } - protected class CreatePrepareDouble implements Runnable { - private String sql; - private Connection connection; - private long firstWaitTime; - private long secondWaitTime; - - - public CreatePrepareDouble(String sql, Connection connection, long firstWaitTime, long secondWaitTime) { - this.sql = sql; - this.connection = connection; - this.firstWaitTime = firstWaitTime; - this.secondWaitTime = secondWaitTime; - } - - public void run() { - try { - Protocol protocol = getProtocolFromConnection(connection); - if (protocol.prepareStatementCache().containsKey(sql)) { - protocol.prepareStatementCache().get(sql); - } - if (protocol.prepareStatementCache().containsKey(sql)) { - protocol.prepareStatementCache().get(sql); - } - PreparedStatement ps = connection.prepareStatement(sql); - Thread.sleep(firstWaitTime); - ps.setBoolean(1, true); - ps.addBatch(); - ps.executeBatch(); - Thread.sleep(secondWaitTime); - ps.close(); - if (protocol.prepareStatementCache().containsKey(sql)) { - protocol.prepareStatementCache().get(sql); - } - } catch (Throwable e) { - e.printStackTrace(); - fail(); - } - } - } - /** * Binary state reading control. * diff --git a/src/test/java/org/mariadb/jdbc/SslTest.java b/src/test/java/org/mariadb/jdbc/SslTest.java index b0038c5e1..34c9579da 100644 --- a/src/test/java/org/mariadb/jdbc/SslTest.java +++ b/src/test/java/org/mariadb/jdbc/SslTest.java @@ -480,7 +480,7 @@ public void testTrustStoreWithPassword() throws IOException, KeyStoreException, Properties info = new Properties(); info.setProperty("useSSL", "true"); - info.setProperty("trustStore", "file://" + keystorePath); + info.setProperty("trustStore", keystorePath); info.setProperty("trustStorePassword", "mysecret"); testConnect(info, true); } finally { diff --git a/src/test/java/org/mariadb/jdbc/internal/util/UtilsTest.java b/src/test/java/org/mariadb/jdbc/internal/util/UtilsTest.java index 868ed333c..d47acfef6 100644 --- a/src/test/java/org/mariadb/jdbc/internal/util/UtilsTest.java +++ b/src/test/java/org/mariadb/jdbc/internal/util/UtilsTest.java @@ -55,6 +55,8 @@ import org.junit.Assert; import org.junit.Test; +import static org.junit.Assert.assertEquals; + public class UtilsTest { @Test @@ -78,4 +80,18 @@ public void testByteDump() { + "6E 65 2C 20 40 40 73 71 6C 5F 6D 6F 64 65 ne, @@sql_mode\n"; Assert.assertEquals(result, Utils.hexdump(bb)); } + + @Test + public void sessionVariableParsing() { + assertEquals("net_write_timeout=3600", Utils.parseSessionVariables("net_write_timeout=3600")); + assertEquals("net_write,_timeout=3600", Utils.parseSessionVariables("net_write,_timeout=3600")); + + assertEquals("net_write_timeout=3600", Utils.parseSessionVariables(",;net_write_timeout=3600,")); + assertEquals("net_write_timeout=3600,INSERT INTO USER", + Utils.parseSessionVariables("net_write_timeout=3600;INSERT INTO USER")); + assertEquals("net_write_timeout=3600,init_connect='SELECT 1;SELECT 2'", + Utils.parseSessionVariables("net_write_timeout=3600;init_connect='SELECT 1;SELECT 2'")); + + } + } diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index ec7958e81..32ad54c0e 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -59,7 +59,7 @@ - +