diff --git a/README.md b/README.md index 94873f96d..45b09ec62 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ or maven : org.mariadb.jdbc mariadb-java-client - 1.4.5 + 1.4.6 ``` diff --git a/documentation/Changelog.md b/documentation/Changelog.md index 74fb5f541..a21bd2ad9 100644 --- a/documentation/Changelog.md +++ b/documentation/Changelog.md @@ -1,4 +1,5 @@ # Changelog +* [1.4.6](#1.4.6) Released on 13 june 2016 * [1.4.5](#1.4.5) Released on 18 mai 2016 * [1.4.4](#1.4.4) Released on 04 mai 2016 * [1.4.3](#1.4.3) Released on 22 april 2016 @@ -7,6 +8,13 @@ * [1.4.0](#1.4.0) Released on 31 march 2016 --- + +## 1.4.6 +* [CONJ-293] Permit named pipe connection without host +* [CONJ-309] Possible NPE on aurora when failover occur during connection initialisation +* [CONJ-312] NPE while loading a null from TIMESTAMP field using binary protocol +* [misc] batch with one parameter correction (using rewriteBatchedStatements option) + ## 1.4.5 * [CONJ-297] Useless memory consumption when using Statement.setQueryTimeout * [CONJ-294] PrepareStatement on master reconnection after a failover diff --git a/pom.xml b/pom.xml index d4a9f52dc..4768203cb 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ mariadb-java-client jar mariadb-java-client - 1.4.6-SNAPSHOT + 1.4.6 JDBC driver for MariaDB and MySQL https://mariadb.com/kb/en/mariadb/about-mariadb-connector-j/ diff --git a/src/main/java/org/mariadb/jdbc/internal/failover/impl/AuroraListener.java b/src/main/java/org/mariadb/jdbc/internal/failover/impl/AuroraListener.java index c65b0ad8d..ef806b176 100644 --- a/src/main/java/org/mariadb/jdbc/internal/failover/impl/AuroraListener.java +++ b/src/main/java/org/mariadb/jdbc/internal/failover/impl/AuroraListener.java @@ -191,7 +191,7 @@ public HostAddress searchByStartName(Protocol secondaryProtocol, List>>>>>> 89657fcb71e399da4510bd3f21f4a133795f5aea import org.mariadb.jdbc.internal.util.buffer.Buffer; import org.mariadb.jdbc.internal.util.constant.HaMode; import org.mariadb.jdbc.internal.util.constant.ParameterConstant; @@ -692,6 +699,19 @@ public void connectWithoutProxy() throws QueryException { List addrs = urlParser.getHostAddresses(); List hosts = new LinkedList<>(addrs); + //CONJ-293 : handle name-pipe without host + if (hosts.isEmpty() && options.pipe != null) { + try { + connect(null, 0); + return; + } catch (IOException e) { + if (hosts.isEmpty()) { + throw new QueryException("Could not connect to named pipe '" + options.pipe + "' : " + + e.getMessage(), -1, ExceptionMapper.SqlStates.CONNECTION_EXCEPTION.getSqlState(), e); + } + } + } + // There could be several addresses given in the URL spec, try all of them, and throw exception if all hosts // fail. while (!hosts.isEmpty()) { diff --git a/src/main/java/org/mariadb/jdbc/internal/queryresults/resultset/MariaSelectResultSet.java b/src/main/java/org/mariadb/jdbc/internal/queryresults/resultset/MariaSelectResultSet.java index 66d4f19e5..9f187da84 100644 --- a/src/main/java/org/mariadb/jdbc/internal/queryresults/resultset/MariaSelectResultSet.java +++ b/src/main/java/org/mariadb/jdbc/internal/queryresults/resultset/MariaSelectResultSet.java @@ -878,7 +878,7 @@ private String getString(byte[] rawBytes, ColumnInformation columnInfo, Calendar if (isBinaryEncoded) { try { Date date = getDate(rawBytes, columnInfo, cal); - return date == null ? null : date.toString(); + return (date == null) ? null : date.toString(); } catch (ParseException e) { } } @@ -886,7 +886,8 @@ private String getString(byte[] rawBytes, ColumnInformation columnInfo, Calendar case YEAR: if (options.yearIsDateType) { try { - return getDate(rawBytes, columnInfo, cal).toString(); + Date date = getDate(rawBytes, columnInfo, cal); + return (date == null) ? null : date.toString(); } catch (ParseException e) { //eat exception } @@ -898,18 +899,19 @@ private String getString(byte[] rawBytes, ColumnInformation columnInfo, Calendar case TIMESTAMP: case DATETIME: try { - return getTimestamp(rawBytes, columnInfo, cal).toString(); + Timestamp timestamp = getTimestamp(rawBytes, columnInfo, cal); + return (timestamp == null) ? null : timestamp.toString(); } catch (ParseException e) { } break; case DECIMAL: - return getBigDecimal(rawBytes, columnInfo).toString(); + case OLDDECIMAL: + BigDecimal bigDecimal = getBigDecimal(rawBytes, columnInfo); + return (bigDecimal == null ) ? null : bigDecimal.toString(); case GEOMETRY: return new String(rawBytes); case NULL: return null; - case OLDDECIMAL: - return getBigDecimal(rawBytes, columnInfo).toString(); default: return new String(rawBytes, StandardCharsets.UTF_8); } @@ -3257,7 +3259,8 @@ private Date binaryDate(byte[] rawBytes, ColumnInformation columnInfo, Calendar switch (columnInfo.getType()) { case TIMESTAMP: case DATETIME: - return new Date(getTimestamp(rawBytes, columnInfo, cal).getTime()); + Timestamp timestamp = getTimestamp(rawBytes, columnInfo, cal); + return (timestamp == null) ? null : new Date(timestamp.getTime()); default: if (rawBytes.length == 0) { return null; @@ -3305,7 +3308,7 @@ private Time binaryTime(byte[] rawBytes, ColumnInformation columnInfo, Calendar case TIMESTAMP: case DATETIME: Timestamp ts = binaryTimestamp(rawBytes, columnInfo, cal); - return new Time(ts.getTime()); + return (ts == null) ? null : new Time(ts.getTime()); case DATE: Calendar tmpCalendar = Calendar.getInstance(); tmpCalendar.clear(); 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 fcbf2842d..ad7200efd 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 @@ -51,10 +51,10 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS package org.mariadb.jdbc.internal.util.constant; public final class Version { - public static final String version = "1.4.6-SNAPSHOT"; + public static final String version = "1.4.6"; public static final int majorVersion = 1; public static final int minorVersion = 4; public static final int patchVersion = 6; - public static final String qualifier = "SNAPSHOT"; + public static final String qualifier = ""; } \ No newline at end of file diff --git a/src/test/java/org/mariadb/jdbc/DateTest.java b/src/test/java/org/mariadb/jdbc/DateTest.java index 513661d26..04de67e72 100644 --- a/src/test/java/org/mariadb/jdbc/DateTest.java +++ b/src/test/java/org/mariadb/jdbc/DateTest.java @@ -535,4 +535,35 @@ public void nullDateString() throws Throwable { } } + /** + * Conj-317 : null pointer exception on getDate on null timestamp. + */ + @Test + public void nullDateFromTimestamp() throws Throwable { + + createTable("nulltimestamp", "ts timestamp(6) NULL "); + Statement stmt = sharedConnection.createStatement(); + try { + stmt.execute("INSERT INTO nulltimestamp (ts) VALUES ('0000-00-00'), (null)"); + + PreparedStatement pst = sharedConnection.prepareStatement("SELECT * FROM nulltimestamp WHERE 1 = ?"); + pst.setInt(1, 1); + ResultSet rs = pst.executeQuery(); + Assert.assertTrue(rs.next()); + Assert.assertNull(rs.getString(1)); + Assert.assertNull(rs.getDate(1)); + Assert.assertNull(rs.getTimestamp(1)); + Assert.assertNull(rs.getTime(1)); + + Assert.assertTrue(rs.next()); + Assert.assertNull(rs.getString(1)); + Assert.assertNull(rs.getDate(1)); + Assert.assertNull(rs.getTimestamp(1)); + Assert.assertNull(rs.getTime(1)); + + } catch (SQLDataException sqldataException) { + //'0000-00-00' doesn't work anymore on mysql 5.7. + } + } + } diff --git a/src/test/java/org/mariadb/jdbc/DriverTest.java b/src/test/java/org/mariadb/jdbc/DriverTest.java index 51e850ccb..b411d0e08 100644 --- a/src/test/java/org/mariadb/jdbc/DriverTest.java +++ b/src/test/java/org/mariadb/jdbc/DriverTest.java @@ -1088,33 +1088,50 @@ public void conj25() throws Exception { } @Test - public void namedpipe() throws Exception { - String namedPipeName = null; + public void namedPipe() throws Exception { try { ResultSet rs = sharedConnection.createStatement().executeQuery("select @@named_pipe,@@socket"); rs.next(); if (rs.getBoolean(1)) { - namedPipeName = rs.getString(2); - } else { - System.out.println("test 'namedpipe' skipped"); + String namedPipeName = rs.getString(2); + //skip test if no namedPipeName was obtained because then we do not use a socket connection + Assume.assumeTrue(namedPipeName != null); + try (Connection connection = setConnection("&pipe=" + namedPipeName)) { + Statement stmt = connection.createStatement(); + rs = stmt.executeQuery("SELECT 1"); + assertTrue(rs.next()); + rs.close(); + } } } catch (SQLException e) { - //named pipe not found, - System.out.println("test 'namedpipe' skipped"); + //not on windows } + } - //skip test if no namedPipeName was obtained because then we do not use a socket connection - Assume.assumeTrue(namedPipeName != null); - - Connection connection = null; + /** + * CONJ-293 : permit connection to named pipe when no host is defined. + * + * @throws Exception mustn't occur. + */ + @Test + public void namedPipeWithoutHost() throws Exception { try { - connection = setConnection("&pipe=" + namedPipeName); - Statement stmt = connection.createStatement(); - ResultSet rs = stmt.executeQuery("SELECT 1"); - assertTrue(rs.next()); - rs.close(); - } finally { - connection.close(); + ResultSet rs = sharedConnection.createStatement().executeQuery("select @@named_pipe,@@socket"); + rs.next(); + if (rs.getBoolean(1)) { + String namedPipeName = rs.getString(2); + //skip test if no namedPipeName was obtained because then we do not use a socket connection + Assume.assumeTrue(namedPipeName != null); + try (Connection connection = DriverManager.getConnection("jdbc:mariadb://localhost/testj?user=" + + username + "&pipe=" + namedPipeName)) { + Statement stmt = connection.createStatement(); + rs = stmt.executeQuery("SELECT 1"); + assertTrue(rs.next()); + rs.close(); + } + } + } catch (SQLException e) { + //not on windows } }