From 75efddb48ad8e4d5cb2c5aa2715576ed0a778cd1 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Mon, 20 Nov 2017 21:34:31 +0100 Subject: [PATCH 01/18] ADD: Testcase to show broken java.sql.Time support --- .../jdbc/datatypes/DateAndTimeTypeTest.java | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 src/test/java/com/microsoft/sqlserver/jdbc/datatypes/DateAndTimeTypeTest.java diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/DateAndTimeTypeTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/DateAndTimeTypeTest.java new file mode 100644 index 000000000..b5f00a530 --- /dev/null +++ b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/DateAndTimeTypeTest.java @@ -0,0 +1,138 @@ +/* + * Microsoft JDBC Driver for SQL Server + * + * Copyright(c) Microsoft Corporation All rights reserved. + * + * This program is made available under the terms of the MIT License. See the LICENSE file in the project root for more information. + */ +package com.microsoft.sqlserver.jdbc.datatypes; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +import java.sql.Connection; +import java.sql.Date; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Time; +import java.sql.Timestamp; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; +import org.opentest4j.TestAbortedException; + +import com.microsoft.sqlserver.jdbc.SQLServerStatement; +import com.microsoft.sqlserver.testframework.AbstractTest; +import com.microsoft.sqlserver.testframework.DBConnection; +import com.microsoft.sqlserver.testframework.Utils; + +@RunWith(JUnitPlatform.class) +public class DateAndTimeTypeTest extends AbstractTest { + + private static final Date DATE_TO_TEST = new java.sql.Date(2017, 20, 11); + private static final Time TIME_TO_TEST = new java.sql.Time(12, 34, 56); + private static final Timestamp TIMESTAMP_TO_TEST = new java.sql.Timestamp(2017, 20, 11, 12, 34, 56, 0); + + static Statement stmt = null; + static Connection connection = null; + static PreparedStatement pstmt = null; + static ResultSet rs = null; + + /** + * Test query with date + */ + @Test + public void testQueryDate() throws SQLException { + String sPrepStmt = "select * from dateandtime where my_date = ?"; + pstmt = connection.prepareStatement(sPrepStmt); + pstmt.setDate(1, DATE_TO_TEST); + + rs = pstmt.executeQuery(); + rs.next(); + assertTrue(rs.getInt(1) == 42, "did not find correct timestamp"); + rs.close(); + pstmt.close(); + + } + + /** + * Test query with timestamp + */ + @Test + public void testQueryTimestamp() throws SQLException { + String sPrepStmt = "select * from dateandtime where my_timestamp = ?"; + pstmt = connection.prepareStatement(sPrepStmt); + pstmt.setTimestamp(1, TIMESTAMP_TO_TEST); + + rs = pstmt.executeQuery(); + rs.next(); + assertTrue(rs.getInt(1) == 42, "did not find correct timestamp"); + rs.close(); + pstmt.close(); + } + + /** + * Test query with time + */ + @Test + public void testQueryTime() throws SQLException { + String sPrepStmt = "select * from dateandtime where my_time = ?"; + pstmt = connection.prepareStatement(sPrepStmt); + pstmt.setTime(1, TIME_TO_TEST); + + rs = pstmt.executeQuery(); + rs.next(); + assertTrue(rs.getInt(1) == 42, "did not find correct timestamp"); + rs.close(); + pstmt.close(); + } + + @BeforeEach + public void testSetup() throws TestAbortedException, Exception { + assumeTrue(13 <= new DBConnection(connectionString).getServerVersion(), + "Aborting test case as SQL Server version is not compatible with Always encrypted "); + + connection = DriverManager.getConnection(connectionString); + SQLServerStatement stmt = (SQLServerStatement) connection.createStatement(); + Utils.dropTableIfExists("dateandtime", stmt); + String sql1 = "create table dateandtime (id integer not null, my_date date, my_time time, my_timestamp datetime2 constraint pk_esimple primary key (id))"; + stmt.execute(sql1); + stmt.close(); + + // add one sample data + String sPrepStmt = "insert into dateandtime (id, my_date, my_time, my_timestamp) values (?, ?, ?, ?)"; + pstmt = connection.prepareStatement(sPrepStmt); + pstmt.setInt(1, 42); + pstmt.setDate(2, DATE_TO_TEST); + pstmt.setTime(3, TIME_TO_TEST); + pstmt.setTimestamp(4, TIMESTAMP_TO_TEST); + pstmt.execute(); + pstmt.close(); + } + + @AfterAll + public static void terminateVariation() throws SQLException { + + SQLServerStatement stmt = (SQLServerStatement) connection.createStatement(); + Utils.dropTableIfExists("dateandtime", stmt); + + if (null != connection) { + connection.close(); + } + if (null != pstmt) { + pstmt.close(); + } + if (null != stmt) { + stmt.close(); + } + if (null != rs) { + rs.close(); + } + } +} \ No newline at end of file From 7581d8500f529873410e290001308681a7b92918 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Tue, 21 Nov 2017 09:47:55 +0100 Subject: [PATCH 02/18] added tests for TVP and date/time objects --- .../jdbc/datatypes/DateAndTimeTypeTest.java | 71 ++++++++++++++++++- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/DateAndTimeTypeTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/DateAndTimeTypeTest.java index b5f00a530..043245ed7 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/DateAndTimeTypeTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/DateAndTimeTypeTest.java @@ -27,6 +27,8 @@ import org.junit.runner.RunWith; import org.opentest4j.TestAbortedException; +import com.microsoft.sqlserver.jdbc.SQLServerDataTable; +import com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement; import com.microsoft.sqlserver.jdbc.SQLServerStatement; import com.microsoft.sqlserver.testframework.AbstractTest; import com.microsoft.sqlserver.testframework.DBConnection; @@ -93,17 +95,78 @@ public void testQueryTime() throws SQLException { pstmt.close(); } + /** + * Test query with date TVP + */ + @Test + public void testQueryDateTVP() throws SQLException { + SQLServerDataTable tvp = new SQLServerDataTable(); + tvp.addColumnMetadata("c1", java.sql.Types.DATE); + tvp.addRow(DATE_TO_TEST); + String sPrepStmt = "select * from dateandtime where my_date IN (select * from ?)"; + pstmt = connection.prepareStatement(sPrepStmt); + ((SQLServerPreparedStatement)pstmt).setStructured(1, "dateTVP", tvp); + + rs = pstmt.executeQuery(); + rs.next(); + assertTrue(rs.getInt(1) == 42, "did not find correct timestamp"); + rs.close(); + pstmt.close(); + } + + /** + * Test query with date TVP + */ + @Test + public void testQueryTimestampTVP() throws SQLException { + SQLServerDataTable tvp = new SQLServerDataTable(); + tvp.addColumnMetadata("c1", java.sql.Types.TIMESTAMP); + tvp.addRow(TIMESTAMP_TO_TEST); + String sPrepStmt = "select * from dateandtime where my_timestamp IN (select * from ?)"; + pstmt = connection.prepareStatement(sPrepStmt); + ((SQLServerPreparedStatement)pstmt).setStructured(1, "timestampTVP", tvp); + + rs = pstmt.executeQuery(); + rs.next(); + assertTrue(rs.getInt(1) == 42, "did not find correct timestamp"); + rs.close(); + pstmt.close(); + } + + /** + * Test query with date TVP + */ + @Test + public void testQueryTimeTVP() throws SQLException { + SQLServerDataTable tvp = new SQLServerDataTable(); + tvp.addColumnMetadata("c1", java.sql.Types.TIME); + tvp.addRow(TIME_TO_TEST); + String sPrepStmt = "select * from dateandtime where my_time IN (select * from ?)"; + pstmt = connection.prepareStatement(sPrepStmt); + ((SQLServerPreparedStatement)pstmt).setStructured(1, "timeTVP", tvp); + + rs = pstmt.executeQuery(); + rs.next(); + assertTrue(rs.getInt(1) == 42, "did not find correct timestamp"); + rs.close(); + pstmt.close(); + } + private void createTVPs(String tvpName, String tvpType) throws SQLException { + stmt.executeUpdate("IF EXISTS (SELECT * FROM sys.types WHERE is_table_type = 1 AND name = '" + tvpName + "') " + " drop type " + tvpName); + String TVPCreateCmd = "CREATE TYPE " + tvpName + " as table (c1 " + tvpType + " null)"; + stmt.executeUpdate(TVPCreateCmd); + } + @BeforeEach public void testSetup() throws TestAbortedException, Exception { assumeTrue(13 <= new DBConnection(connectionString).getServerVersion(), "Aborting test case as SQL Server version is not compatible with Always encrypted "); connection = DriverManager.getConnection(connectionString); - SQLServerStatement stmt = (SQLServerStatement) connection.createStatement(); + stmt = (SQLServerStatement) connection.createStatement(); Utils.dropTableIfExists("dateandtime", stmt); String sql1 = "create table dateandtime (id integer not null, my_date date, my_time time, my_timestamp datetime2 constraint pk_esimple primary key (id))"; stmt.execute(sql1); - stmt.close(); // add one sample data String sPrepStmt = "insert into dateandtime (id, my_date, my_time, my_timestamp) values (?, ?, ?, ?)"; @@ -114,12 +177,14 @@ public void testSetup() throws TestAbortedException, Exception { pstmt.setTimestamp(4, TIMESTAMP_TO_TEST); pstmt.execute(); pstmt.close(); + createTVPs("dateTVP", "date"); + createTVPs("timeTVP", "time"); + createTVPs("timestampTVP", "datetime2"); } @AfterAll public static void terminateVariation() throws SQLException { - SQLServerStatement stmt = (SQLServerStatement) connection.createStatement(); Utils.dropTableIfExists("dateandtime", stmt); if (null != connection) { From f894dab115acc8acbe5d1afbb344294874957828 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Tue, 21 Nov 2017 11:27:55 +0100 Subject: [PATCH 03/18] updated connection string --- .../sqlserver/jdbc/datatypes/DateAndTimeTypeTest.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/DateAndTimeTypeTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/DateAndTimeTypeTest.java index 043245ed7..d7b5e5701 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/DateAndTimeTypeTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/DateAndTimeTypeTest.java @@ -159,10 +159,11 @@ private void createTVPs(String tvpName, String tvpType) throws SQLException { @BeforeEach public void testSetup() throws TestAbortedException, Exception { - assumeTrue(13 <= new DBConnection(connectionString).getServerVersion(), - "Aborting test case as SQL Server version is not compatible with Always encrypted "); - - connection = DriverManager.getConnection(connectionString); + assumeTrue(9 <= new DBConnection(connectionString).getServerVersion(), + "Aborting test case as SQL Server version does not support TIME"); + // To get TIME & setTime working on Servers >= 2008, we must add 'sendTimeAsDatetime=false' + // by default to the connection. See issue https://github.com/Microsoft/mssql-jdbc/issues/559 + connection = DriverManager.getConnection(connectionString + ";sendTimeAsDatetime=false"); stmt = (SQLServerStatement) connection.createStatement(); Utils.dropTableIfExists("dateandtime", stmt); String sql1 = "create table dateandtime (id integer not null, my_date date, my_time time, my_timestamp datetime2 constraint pk_esimple primary key (id))"; From 16c6aa9d810a70f5429bd1924341d7050da5bdb0 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Fri, 9 Mar 2018 14:20:51 -0800 Subject: [PATCH 04/18] update pom file for 6.5.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f63e32330..4e1180877 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.microsoft.sqlserver mssql-jdbc - 6.5.0.${jreVersion}-preview + 6.5.1-SNAPSHOT.${jreVersion}-preview jar Microsoft JDBC Driver for SQL Server From 95d888de79d5bc72f4e71e668a852cd14c857b36 Mon Sep 17 00:00:00 2001 From: Peter Bae Date: Fri, 9 Mar 2018 16:41:11 -0800 Subject: [PATCH 05/18] Removing unused imports --- .../com/microsoft/sqlserver/jdbc/SQLServerSpatialDatatype.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerSpatialDatatype.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerSpatialDatatype.java index f290959f3..a5256aa10 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerSpatialDatatype.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerSpatialDatatype.java @@ -10,13 +10,10 @@ import java.math.BigDecimal; import java.nio.ByteBuffer; -import java.nio.ByteOrder; import java.util.ArrayList; import java.util.List; import java.util.Locale; -import com.sun.mail.imap.protocol.INTERNALDATE; - abstract class SQLServerSpatialDatatype { /**WKT = Well-Known-Text, WKB = Well-Knwon-Binary */ From 4a995028a75193be6ffa147d867466b2c63d5795 Mon Sep 17 00:00:00 2001 From: ulvii Date: Mon, 12 Mar 2018 09:40:15 -0700 Subject: [PATCH 06/18] Removing AKV from pom description (#653) --- pom.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pom.xml b/pom.xml index 4e1180877..2eeec042b 100644 --- a/pom.xml +++ b/pom.xml @@ -11,8 +11,6 @@ Microsoft JDBC Driver for SQL Server Microsoft JDBC Driver for SQL Server. - The Azure Key Vault feature in Microsoft JDBC Driver for SQL Server depends on - Azure SDK for JAVA and Azure Active Directory Library For Java. https://github.com/Microsoft/mssql-jdbc From 2d740b796d99a6e7c5df7706fa3f5fcf23fb42e7 Mon Sep 17 00:00:00 2001 From: Peter Bae Date: Mon, 12 Mar 2018 11:38:08 -0700 Subject: [PATCH 07/18] Replace deprecated methods and clean up the connection --- .../jdbc/datatypes/DateAndTimeTypeTest.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/DateAndTimeTypeTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/DateAndTimeTypeTest.java index d7b5e5701..44a7c0b87 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/DateAndTimeTypeTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/DateAndTimeTypeTest.java @@ -37,9 +37,9 @@ @RunWith(JUnitPlatform.class) public class DateAndTimeTypeTest extends AbstractTest { - private static final Date DATE_TO_TEST = new java.sql.Date(2017, 20, 11); - private static final Time TIME_TO_TEST = new java.sql.Time(12, 34, 56); - private static final Timestamp TIMESTAMP_TO_TEST = new java.sql.Timestamp(2017, 20, 11, 12, 34, 56, 0); + private static final Date DATE_TO_TEST = new java.sql.Date(61494793200000L); + private static final Time TIME_TO_TEST = new java.sql.Time(74096000L); + private static final Timestamp TIMESTAMP_TO_TEST = new java.sql.Timestamp(61494838496000L); static Statement stmt = null; static Connection connection = null; @@ -159,8 +159,10 @@ private void createTVPs(String tvpName, String tvpType) throws SQLException { @BeforeEach public void testSetup() throws TestAbortedException, Exception { - assumeTrue(9 <= new DBConnection(connectionString).getServerVersion(), - "Aborting test case as SQL Server version does not support TIME"); + try (DBConnection dbc = new DBConnection(connectionString)) { + assumeTrue(9 <= dbc.getServerVersion(), + "Aborting test case as SQL Server version does not support TIME"); + } // To get TIME & setTime working on Servers >= 2008, we must add 'sendTimeAsDatetime=false' // by default to the connection. See issue https://github.com/Microsoft/mssql-jdbc/issues/559 connection = DriverManager.getConnection(connectionString + ";sendTimeAsDatetime=false"); From b97baa16311b18fdb615c59a469776e705549811 Mon Sep 17 00:00:00 2001 From: Peter Bae Date: Tue, 13 Mar 2018 10:13:14 -0700 Subject: [PATCH 08/18] SQLServerResultSetMetaData::getColumnType for spatial datatypes should return their own type code, not VARBYTE. also removing unused imports. --- .../microsoft/sqlserver/jdbc/Geography.java | 1 - .../microsoft/sqlserver/jdbc/Geometry.java | 1 - .../jdbc/SQLServerResultSetMetaData.java | 8 ++++ .../SQLServerSpatialDatatypeTest.java | 39 +++++++++++++++++++ 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/Geography.java b/src/main/java/com/microsoft/sqlserver/jdbc/Geography.java index 7c9fcaf8a..0790a0691 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/Geography.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/Geography.java @@ -10,7 +10,6 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; -import java.util.Locale; public class Geography extends SQLServerSpatialDatatype { diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/Geometry.java b/src/main/java/com/microsoft/sqlserver/jdbc/Geometry.java index 5966d5fe9..90f4427a5 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/Geometry.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/Geometry.java @@ -10,7 +10,6 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; -import java.util.Locale; public class Geometry extends SQLServerSpatialDatatype { diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSetMetaData.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSetMetaData.java index 93de065ee..0e18ce616 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSetMetaData.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSetMetaData.java @@ -125,6 +125,14 @@ public int getColumnType(int column) throws SQLServerException { if ( SSType.SQL_VARIANT == typeInfo.getSSType()){ jdbcType = JDBCType.SQL_VARIANT; } + if (SSType.UDT == typeInfo.getSSType()) { + if (typeInfo.getSSTypeName().equalsIgnoreCase("geometry")) { + jdbcType = JDBCType.GEOMETRY; + } + if (typeInfo.getSSTypeName().equalsIgnoreCase("geography")) { + jdbcType = JDBCType.GEOGRAPHY; + } + } int r = jdbcType.asJavaSqlType(); if (con.isKatmaiOrLater()) { SSType sqlType = typeInfo.getSSType(); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/SQLServerSpatialDatatypeTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/SQLServerSpatialDatatypeTest.java index 28bd072db..3226e6652 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/SQLServerSpatialDatatypeTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/SQLServerSpatialDatatypeTest.java @@ -11,6 +11,8 @@ import java.io.IOException; import java.sql.DriverManager; +import java.sql.ParameterMetaData; +import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; @@ -817,6 +819,43 @@ public void testSTAsBinary() throws SQLException { assertEquals(geomWKB, geomWKB2); assertEquals(geogWKB, geogWKB2); } + + public void testCheckGeomMetaData() throws SQLException { + beforeEachSetup(); + + pstmt = (SQLServerPreparedStatement) connection.prepareStatement("INSERT INTO " + geomTableName +" VALUES (?)"); + ParameterMetaData paramMetaData = pstmt.getParameterMetaData(); + Geometry g = Geometry.STGeomFromText("POINT (1 2 3 4)", 0); + pstmt.setGeometry(1, g); + pstmt.execute(); + + int sqlType = paramMetaData.getParameterType(1); + String sqlTypeName = paramMetaData.getParameterTypeName(1); + assertEquals(sqlType, -157); + assertEquals(sqlTypeName, "geometry"); + SQLServerResultSet rs = (SQLServerResultSet) stmt.executeQuery("select * from " + geomTableName); + ResultSetMetaData rsmd = rs.getMetaData(); + assertEquals(rsmd.getColumnType(1), -157); + } + + @Test + public void testCheckGeogMetaData() throws SQLException { + beforeEachSetup(); + + pstmt = (SQLServerPreparedStatement) connection.prepareStatement("INSERT INTO " + geogTableName +" VALUES (?)"); + ParameterMetaData paramMetaData = pstmt.getParameterMetaData(); + Geography g = Geography.STGeomFromText("POINT (1 2 3 4)", 4326); + pstmt.setGeography(1, g); + pstmt.execute(); + + int sqlType = paramMetaData.getParameterType(1); + String sqlTypeName = paramMetaData.getParameterTypeName(1); + assertEquals(sqlType, -158); + assertEquals(sqlTypeName, "geography"); + SQLServerResultSet rs = (SQLServerResultSet) stmt.executeQuery("select * from " + geogTableName); + ResultSetMetaData rsmd = rs.getMetaData(); + assertEquals(rsmd.getColumnType(1), -158); + } private void beforeEachSetup() throws SQLException { Utils.dropTableIfExists(geomTableName, stmt); From e0fbbddbd3db6bf2046329d8972683eeae7ebb5e Mon Sep 17 00:00:00 2001 From: Peter Bae Date: Tue, 13 Mar 2018 11:47:15 -0700 Subject: [PATCH 09/18] explicitly give column name to work around sql server 2008 problem --- .../jdbc/datatypes/SQLServerSpatialDatatypeTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/SQLServerSpatialDatatypeTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/SQLServerSpatialDatatypeTest.java index 3226e6652..71c2b68e3 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/SQLServerSpatialDatatypeTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/datatypes/SQLServerSpatialDatatypeTest.java @@ -823,7 +823,7 @@ public void testSTAsBinary() throws SQLException { public void testCheckGeomMetaData() throws SQLException { beforeEachSetup(); - pstmt = (SQLServerPreparedStatement) connection.prepareStatement("INSERT INTO " + geomTableName +" VALUES (?)"); + pstmt = (SQLServerPreparedStatement) connection.prepareStatement("INSERT INTO " + geomTableName +" (c1) VALUES (?)"); ParameterMetaData paramMetaData = pstmt.getParameterMetaData(); Geometry g = Geometry.STGeomFromText("POINT (1 2 3 4)", 0); pstmt.setGeometry(1, g); @@ -842,7 +842,7 @@ public void testCheckGeomMetaData() throws SQLException { public void testCheckGeogMetaData() throws SQLException { beforeEachSetup(); - pstmt = (SQLServerPreparedStatement) connection.prepareStatement("INSERT INTO " + geogTableName +" VALUES (?)"); + pstmt = (SQLServerPreparedStatement) connection.prepareStatement("INSERT INTO " + geogTableName +" (c1) VALUES (?)"); ParameterMetaData paramMetaData = pstmt.getParameterMetaData(); Geography g = Geography.STGeomFromText("POINT (1 2 3 4)", 4326); pstmt.setGeography(1, g); From f826fa71cb1b99d77d2ef6d59d43536848598200 Mon Sep 17 00:00:00 2001 From: David Engel Date: Fri, 16 Mar 2018 12:16:51 -0700 Subject: [PATCH 10/18] Adding release roadmap and standards info Also updating a couple of old MSDN links. --- README.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 788d8bf28..9395e17bc 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ What's coming next? We will look into adding a more comprehensive set of tests, * An instance of SQL Server or Azure SQL Database that you can connect to. ### Build the JAR files -Maven builds automatically trigger a set of verification tests to run. For these tests to pass, you will first need to add an environment variable in your system called `mssql_jdbc_test_connection_properties` to provide the [correct connection properties](https://msdn.microsoft.com/en-us/library/ms378428(v=sql.110).aspx) for your SQL Server or Azure SQL Database instance. +Maven builds automatically trigger a set of verification tests to run. For these tests to pass, you will first need to add an environment variable in your system called `mssql_jdbc_test_connection_properties` to provide the [correct connection properties](https://docs.microsoft.com/en-us/sql/connect/jdbc/building-the-connection-url) for your SQL Server or Azure SQL Database instance. To build the jar files, you must use Java 9 with Maven. You can choose to build a JDBC 4.3 compliant jar file (for use with JRE 9) and/or a JDBC 4.2 compliant jar file (for use with JRE 8). @@ -64,13 +64,13 @@ To build the jar files, you must use Java 9 with Maven. You can choose to build ### Documentation API reference documentation is available in [Javadocs](https://aka.ms/jdbcjavadocs). -This driver is documented on [Microsoft's Documentation web site](https://msdn.microsoft.com/en-us/library/mt720657). +This driver is documented on [Microsoft's Documentation web site](https://docs.microsoft.com/en-us/sql/connect/jdbc/getting-started-with-the-jdbc-driver). ### Sample Code For samples, please see the src\sample directory. ### Download the DLLs -For some features (e.g. Integrated Authentication and Distributed Transactions), you may need to use the `sqljdbc_xa` and `sqljdbc_auth` DLLs. They can be downloaded from the [Microsoft Download Center](https://go.microsoft.com/fwlink/?linkid=852460) +For some features (e.g. Integrated Authentication and Distributed Transactions), you may need to use the `sqljdbc_xa` and `sqljdbc_auth` DLLs. They can be downloaded from the [Microsoft Download Center](https://go.microsoft.com/fwlink/?linkid=868287) ### Download the driver Don't want to compile anything? @@ -83,7 +83,7 @@ We're now on the Maven Central Repository. Add the following to your POM file to 6.4.0.jre9 ``` -The driver can be downloaded from the [Microsoft Download Center](https://go.microsoft.com/fwlink/?linkid=852460). +The driver can be downloaded from the [Microsoft Download Center](https://go.microsoft.com/fwlink/?linkid=868287). To get the latest preview version of the driver, add the following to your POM file: ```xml @@ -176,6 +176,16 @@ Thank you! ### Reporting security issues and security bugs Security issues and bugs should be reported privately, via email, to the Microsoft Security Response Center (MSRC) [secure@microsoft.com](mailto:secure@microsoft.com). You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Further information, including the MSRC PGP key, can be found in the [Security TechCenter](https://technet.microsoft.com/en-us/security/ff852094.aspx). +## Release roadmap and standards +Our goal is to release regular updates which improve the driver and bring new features to users. Stable, production quality releases happen twice a year, targeting the first and third quarters of the calendar year. They are tested against a comprehensive matrix of supported operating systems, Java versions, and SQL Server versions. Stable releases are accompanied by additional localized packages, which are available on the Microsoft website. + +Preview releases happen approximately monthly between stable releases. This gives users an opportunity to try out new features and provide feedback on them before they go into stable releases. Preview releases also include frequent bug fixes for customers to verify without having to wait for a stable release. Preview releases are only available in English. While they are tested, preview releases do not necessarily go through the same rigorous, full test matrix as stable releases. + +You can see what is going into a future release by monitoring [Milestones](https://github.com/Microsoft/mssql-jdbc/milestones) in the repository. + +### Versioning convention +Starting with 6.0, stable versions have an even minor version. For example, 6.0, 6.2, 6.4. Preview versions have an odd minor version. For example, 6.1, 6.3, 6.5. + ## Contributors Special thanks to everyone who has contributed to the project. From 2039522c510a81958f2f9434b56c3966e91a6dbe Mon Sep 17 00:00:00 2001 From: David Engel Date: Thu, 22 Mar 2018 14:56:21 -0700 Subject: [PATCH 11/18] Small tweak to the README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9395e17bc..57ec2aa8d 100644 --- a/README.md +++ b/README.md @@ -179,7 +179,7 @@ Security issues and bugs should be reported privately, via email, to the Microso ## Release roadmap and standards Our goal is to release regular updates which improve the driver and bring new features to users. Stable, production quality releases happen twice a year, targeting the first and third quarters of the calendar year. They are tested against a comprehensive matrix of supported operating systems, Java versions, and SQL Server versions. Stable releases are accompanied by additional localized packages, which are available on the Microsoft website. -Preview releases happen approximately monthly between stable releases. This gives users an opportunity to try out new features and provide feedback on them before they go into stable releases. Preview releases also include frequent bug fixes for customers to verify without having to wait for a stable release. Preview releases are only available in English. While they are tested, preview releases do not necessarily go through the same rigorous, full test matrix as stable releases. +Preview releases happen approximately monthly between stable releases. This gives users an opportunity to try out new features and provide feedback on them before they go into stable releases. Preview releases also include frequent bug fixes for customers to verify without having to wait for a stable release. Preview releases are only available in English. While they are tested, preview releases do not necessarily go through the same rigorous, full test matrix and review process as stable releases. You can see what is going into a future release by monitoring [Milestones](https://github.com/Microsoft/mssql-jdbc/milestones) in the repository. From 5310f0364b619ad1a258949d44963c5e0505c8df Mon Sep 17 00:00:00 2001 From: Peter Bae Date: Fri, 23 Mar 2018 11:21:19 -0700 Subject: [PATCH 12/18] create a constant for typeInfo.getSSType --- .../sqlserver/jdbc/SQLServerResultSetMetaData.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSetMetaData.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSetMetaData.java index 0e18ce616..42cb9fcda 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSetMetaData.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSetMetaData.java @@ -121,11 +121,12 @@ public int getColumnType(int column) throws SQLServerException { } JDBCType jdbcType = typeInfo.getSSType().getJDBCType(); + SSType sqlType = typeInfo.getSSType(); // in bulkcopy for instance, we need to return the real jdbc type which is sql variant and not the default Char one. - if ( SSType.SQL_VARIANT == typeInfo.getSSType()){ + if ( SSType.SQL_VARIANT == sqlType){ jdbcType = JDBCType.SQL_VARIANT; } - if (SSType.UDT == typeInfo.getSSType()) { + if (SSType.UDT == sqlType) { if (typeInfo.getSSTypeName().equalsIgnoreCase("geometry")) { jdbcType = JDBCType.GEOMETRY; } @@ -135,8 +136,6 @@ public int getColumnType(int column) throws SQLServerException { } int r = jdbcType.asJavaSqlType(); if (con.isKatmaiOrLater()) { - SSType sqlType = typeInfo.getSSType(); - switch (sqlType) { case VARCHARMAX: r = SSType.VARCHAR.getJDBCType().asJavaSqlType(); From 017a09df9f980dcd5ea9bc65c9e90b44702afb3d Mon Sep 17 00:00:00 2001 From: Peter Bae Date: Fri, 23 Mar 2018 11:50:21 -0700 Subject: [PATCH 13/18] use existing string instead of creating a new string --- .../microsoft/sqlserver/jdbc/SQLServerResultSetMetaData.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSetMetaData.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSetMetaData.java index 42cb9fcda..66e801a23 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSetMetaData.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSetMetaData.java @@ -127,10 +127,10 @@ public int getColumnType(int column) throws SQLServerException { jdbcType = JDBCType.SQL_VARIANT; } if (SSType.UDT == sqlType) { - if (typeInfo.getSSTypeName().equalsIgnoreCase("geometry")) { + if (typeInfo.getSSTypeName().equalsIgnoreCase(SSType.GEOMETRY.name())) { jdbcType = JDBCType.GEOMETRY; } - if (typeInfo.getSSTypeName().equalsIgnoreCase("geography")) { + if (typeInfo.getSSTypeName().equalsIgnoreCase(SSType.GEOGRAPHY.name())) { jdbcType = JDBCType.GEOGRAPHY; } } From 92af82909128749b3939f816bdc3dcb1d30a1168 Mon Sep 17 00:00:00 2001 From: ulvii Date: Wed, 4 Apr 2018 17:16:49 -0700 Subject: [PATCH 14/18] Fix for the issue when using setMaxRows() with SHOWPLAN ON (#666) * Dont throw exception for colmetadata token * Adding a comment * Update comment * Adding a warning message * remove ignoreLengthPrefixedToken --- src/main/java/com/microsoft/sqlserver/jdbc/tdsparser.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/tdsparser.java b/src/main/java/com/microsoft/sqlserver/jdbc/tdsparser.java index 3e6a60785..df34c8e6d 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/tdsparser.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/tdsparser.java @@ -160,6 +160,9 @@ class TDSTokenHandler { private StreamError databaseError; + /** TDS protocol diagnostics logger */ + private static Logger logger = Logger.getLogger("com.microsoft.sqlserver.jdbc.internals.TDS.TOKEN"); + final StreamError getDatabaseError() { return databaseError; } @@ -227,7 +230,10 @@ boolean onOrder(TDSReader tdsReader) throws SQLServerException { } boolean onColMetaData(TDSReader tdsReader) throws SQLServerException { - TDSParser.throwUnexpectedTokenException(tdsReader, logContext); + //SHOWPLAN might be ON, instead of throwing an exception, ignore the column meta data + if (logger.isLoggable(Level.SEVERE)) + logger.severe(tdsReader.toString() + ": " + logContext + ": Encountered " + + TDS.getTokenName(tdsReader.peekTokenType()) + ". SHOWPLAN is ON, ignoring."); return false; } From 4ca55d9304aeda24ad9eb3a431e7918bf0a31e71 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Wed, 4 Apr 2018 17:21:36 -0700 Subject: [PATCH 15/18] Fix for uncaught/unhandled exception (#664) * Added more information to error messages To help debug an irreproducable/random mismatch error if it occurs in the future. * Revert "Added information to error message" This reverts commit 25301e6fa042661d4ee1c9dbc8d9cd23ebff8eb7. * Fix for #659 Added error handling logic for special cases. * Read message length Read the message length instead of reading until terminating character * Unsigned byte update Message length is an unsigned byte, converting before using. * Removed clunky hex conversions convert the byte straight to an int and use existing constants instead of making new ones * Narrowed trigger conditions fixed an issue where column names who had the hex token 'AA' would cause an error to be thrown. * Spacing fixes * Added test case * spacing adjustment * Edited test drop procedures Changed IF EXISTS DROP commands to be compatible with sql server 2008 * github spacing misalignment fixes * Changed test condition now only runs on compatible database or higher * Removed error check Removed a previous implementation in favor of one that changes the TDS parser * tdsreader change * removing test for now * enabled tests * github spacing fix * removed array import * removed "arrays" instead of "array" * spacing changes --- .../sqlserver/jdbc/SQLServerResultSet.java | 13 +++- .../jdbc/exception/ExceptionTest.java | 59 ++++++++++++++++++- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index b993a6d3c..0a81edf90 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -6334,9 +6334,20 @@ boolean onNBCRow(TDSReader tdsReader) throws SQLServerException { boolean onDone(TDSReader tdsReader) throws SQLServerException { ensureStartMark(); - // Consume the done token + int token = tdsReader.peekTokenType(); StreamDone doneToken = new StreamDone(); doneToken.setFromTDS(tdsReader); + + int packetType = tdsReader.peekTokenType(); + if (-1 != packetType && TDS.TDS_DONEINPROC == token) { + switch (packetType) { + case TDS.TDS_ENV_CHG: + case TDS.TDS_ERR: + return true; + default: + break; + } + } // Done with all the rows in this fetch buffer and done with parsing // unless it's a server cursor, in which case there is a RETSTAT and diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java index 37dd3e6b6..69245d7ed 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java @@ -7,12 +7,16 @@ */ package com.microsoft.sqlserver.jdbc.exception; +import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.UnsupportedEncodingException; import java.net.SocketTimeoutException; +import java.sql.Connection; import java.sql.DriverManager; +import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Statement; import org.junit.jupiter.api.Test; import org.junit.platform.runner.JUnitPlatform; @@ -20,6 +24,7 @@ import com.microsoft.sqlserver.jdbc.SQLServerBulkCSVFileRecord; import com.microsoft.sqlserver.jdbc.SQLServerConnection; +import com.microsoft.sqlserver.jdbc.SQLServerDataSource; import com.microsoft.sqlserver.testframework.AbstractTest; import com.microsoft.sqlserver.testframework.Utils; @@ -93,4 +98,56 @@ private void createWaitForDelayPreocedure(SQLServerConnection conn) throws SQLEx String sql = "CREATE PROCEDURE " + waitForDelaySPName + " AS" + " BEGIN" + " WAITFOR DELAY '00:00:" + waitForDelaySeconds + "';" + " END"; conn.createStatement().execute(sql); } -} \ No newline at end of file + + @Test + public void testResultSetErrorSearch() throws Exception { + SQLServerDataSource ds = new SQLServerDataSource(); + ds.setURL(connectionString); + + String dropTable_sql = "DROP TABLE IF EXISTS TEST659;"; + String dropProc_sql = "DROP PROCEDURE IF EXISTS proc_insert_masse_TEST;"; + String createTable_sql = "CREATE TABLE TEST659 (ID INT IDENTITY NOT NULL," + + "FIELD1 VARCHAR (255) NOT NULL," + + "FIELD2 VARCHAR (255) NOT NULL);"; + String createProc_sql = "CREATE PROCEDURE proc_insert_masse_TEST @json NVARCHAR(MAX) " + + "AS " + + "BEGIN TRANSACTION " + + "BEGIN TRY " + + "SET NOCOUNT ON; " + + "MERGE INTO TEST659 AS target " + + "USING " + + "(SELECT * FROM OPENJSON(@json) " + + "WITH (FIELD1 VARCHAR(255) 'strict $.FIELD1')) " + + "AS src " + + "ON (1 = 0) " + + "WHEN NOT MATCHED THEN " + + "INSERT (FIELD1) VALUES (src.FIELD1) " + + "OUTPUT inserted.ID; " + + "COMMIT TRANSACTION; " + + "END TRY " + + "BEGIN CATCH " + + "DECLARE @errorMessage NVARCHAR(4000) = ERROR_MESSAGE(); " + + "ROLLBACK TRANSACTION; " + + "RAISERROR('Error occured during the insert: %s', 16, 1, @errorMessage); " + + "END CATCH;"; + String proc_sql = "EXECUTE [dbo].proc_insert_masse_TEST N'[{\"FIELD1\" : \"TEST\"}]';"; + + Connection conn = ds.getConnection(); + if (conn.getMetaData().getDatabaseMajorVersion() >= 13) + { + Statement stmt = conn.createStatement(); + stmt.execute(dropTable_sql); + stmt.execute(createTable_sql); + stmt.execute(dropProc_sql); + stmt.execute(createProc_sql); + stmt.execute(proc_sql); + ResultSet rs = stmt.getResultSet(); + try { + rs.next(); + fail("No exceptions caught."); + } catch (SQLException e) { + assertTrue(e.getMessage().contains("Error occured during the insert:"), "Unexpected Error Message: " + e.getMessage()); + } + } + } +} From 07e391ee8d7381b7da4e16516a7d1fda7000e416 Mon Sep 17 00:00:00 2001 From: ulvii Date: Wed, 4 Apr 2018 17:31:16 -0700 Subject: [PATCH 16/18] Use Socket instead of SocketChannel when multiSubnetFailover=true (#662) --- .../microsoft/sqlserver/jdbc/IOBuffer.java | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java b/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java index 82513ea17..8813ef622 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java @@ -2337,8 +2337,8 @@ else if (!useTnir) { findSocketUsingJavaNIO(inetAddrs, portNumber, timeoutInMilliSeconds); } else { - LinkedList inet4Addrs = new LinkedList<>(); - LinkedList inet6Addrs = new LinkedList<>(); + LinkedList inet4Addrs = new LinkedList<>(); + LinkedList inet6Addrs = new LinkedList<>(); for (InetAddress inetAddr : inetAddrs) { if (inetAddr instanceof Inet4Address) { @@ -2360,11 +2360,10 @@ else if (!useTnir) { if (!inet4Addrs.isEmpty()) { if (logger.isLoggable(Level.FINER)) { - logger.finer(this.toString() + "Using Java NIO with timeout:" + timeoutForEachIPAddressType); + logger.finer(this.toString() + "Using Java Threading with timeout:" + timeoutForEachIPAddressType); } - // inet4Addrs.toArray(new InetAddress[0]) is java style of converting a linked list to an array of reqd size - findSocketUsingJavaNIO(inet4Addrs.toArray(new InetAddress[0]), portNumber, timeoutForEachIPAddressType); + findSocketUsingThreading(inet4Addrs, portNumber, timeoutForEachIPAddressType); } if (!result.equals(Result.SUCCESS)) { @@ -2590,16 +2589,12 @@ private void findSocketUsingJavaNIO(InetAddress[] inetAddrs, // if a channel was selected, make the necessary updates if (selectedChannel != null) { - // the selectedChannel has the address that is connected successfully - // convert it to a java.net.Socket object with the address - SocketAddress iadd = selectedChannel.getRemoteAddress(); - selectedSocket = new Socket(); - selectedSocket.connect(iadd); + // Note that this must be done after selector is closed. Otherwise, + // we would get an illegalBlockingMode exception at run time. + selectedChannel.configureBlocking(true); + selectedSocket = selectedChannel.socket(); result = Result.SUCCESS; - - // close the channel since it is not used anymore - selectedChannel.close(); } } @@ -2638,7 +2633,7 @@ private Socket getConnectedSocket(InetSocketAddress addr, return selectedSocket; } - private void findSocketUsingThreading(LinkedList inetAddrs, + private void findSocketUsingThreading(LinkedList inetAddrs, int portNumber, int timeoutInMilliSeconds) throws IOException, InterruptedException { assert timeoutInMilliSeconds != 0 : "The timeout cannot be zero"; @@ -2722,6 +2717,10 @@ private void findSocketUsingThreading(LinkedList inetAddrs, } } } + + if (selectedSocket != null) { + result = Result.SUCCESS; + } } /** From 501f2b850f511410621f0d8ad43668ff0a6d93c8 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Fri, 6 Apr 2018 11:00:19 -0700 Subject: [PATCH 17/18] Removed Exception Test (#669) * Added more information to error messages To help debug an irreproducable/random mismatch error if it occurs in the future. * Fix for the issue when using setMaxRows() with SHOWPLAN ON (#666) * Dont throw exception for colmetadata token * Adding a comment * Update comment * Adding a warning message * remove ignoreLengthPrefixedToken * Fix for uncaught/unhandled exception (#664) * Added more information to error messages To help debug an irreproducable/random mismatch error if it occurs in the future. * Revert "Added information to error message" This reverts commit 25301e6fa042661d4ee1c9dbc8d9cd23ebff8eb7. * Fix for #659 Added error handling logic for special cases. * Read message length Read the message length instead of reading until terminating character * Unsigned byte update Message length is an unsigned byte, converting before using. * Removed clunky hex conversions convert the byte straight to an int and use existing constants instead of making new ones * Narrowed trigger conditions fixed an issue where column names who had the hex token 'AA' would cause an error to be thrown. * Spacing fixes * Added test case * spacing adjustment * Edited test drop procedures Changed IF EXISTS DROP commands to be compatible with sql server 2008 * github spacing misalignment fixes * Changed test condition now only runs on compatible database or higher * Removed error check Removed a previous implementation in favor of one that changes the TDS parser * tdsreader change * removing test for now * enabled tests * github spacing fix * removed array import * removed "arrays" instead of "array" * spacing changes * Use Socket instead of SocketChannel when multiSubnetFailover=true (#662) * Upped SQL Server requirement to 2017 * Removing Exception Test Implement a more generic and compatible test in the future * Removed imports Used in removed test --- .../jdbc/exception/ExceptionTest.java | 57 ------------------- 1 file changed, 57 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java index 69245d7ed..422a30d25 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java @@ -7,16 +7,12 @@ */ package com.microsoft.sqlserver.jdbc.exception; -import static org.junit.Assert.fail; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.UnsupportedEncodingException; import java.net.SocketTimeoutException; -import java.sql.Connection; import java.sql.DriverManager; -import java.sql.ResultSet; import java.sql.SQLException; -import java.sql.Statement; import org.junit.jupiter.api.Test; import org.junit.platform.runner.JUnitPlatform; @@ -24,7 +20,6 @@ import com.microsoft.sqlserver.jdbc.SQLServerBulkCSVFileRecord; import com.microsoft.sqlserver.jdbc.SQLServerConnection; -import com.microsoft.sqlserver.jdbc.SQLServerDataSource; import com.microsoft.sqlserver.testframework.AbstractTest; import com.microsoft.sqlserver.testframework.Utils; @@ -98,56 +93,4 @@ private void createWaitForDelayPreocedure(SQLServerConnection conn) throws SQLEx String sql = "CREATE PROCEDURE " + waitForDelaySPName + " AS" + " BEGIN" + " WAITFOR DELAY '00:00:" + waitForDelaySeconds + "';" + " END"; conn.createStatement().execute(sql); } - - @Test - public void testResultSetErrorSearch() throws Exception { - SQLServerDataSource ds = new SQLServerDataSource(); - ds.setURL(connectionString); - - String dropTable_sql = "DROP TABLE IF EXISTS TEST659;"; - String dropProc_sql = "DROP PROCEDURE IF EXISTS proc_insert_masse_TEST;"; - String createTable_sql = "CREATE TABLE TEST659 (ID INT IDENTITY NOT NULL," + - "FIELD1 VARCHAR (255) NOT NULL," + - "FIELD2 VARCHAR (255) NOT NULL);"; - String createProc_sql = "CREATE PROCEDURE proc_insert_masse_TEST @json NVARCHAR(MAX) " - + "AS " - + "BEGIN TRANSACTION " - + "BEGIN TRY " - + "SET NOCOUNT ON; " - + "MERGE INTO TEST659 AS target " - + "USING " - + "(SELECT * FROM OPENJSON(@json) " - + "WITH (FIELD1 VARCHAR(255) 'strict $.FIELD1')) " - + "AS src " - + "ON (1 = 0) " - + "WHEN NOT MATCHED THEN " - + "INSERT (FIELD1) VALUES (src.FIELD1) " - + "OUTPUT inserted.ID; " - + "COMMIT TRANSACTION; " - + "END TRY " - + "BEGIN CATCH " - + "DECLARE @errorMessage NVARCHAR(4000) = ERROR_MESSAGE(); " - + "ROLLBACK TRANSACTION; " - + "RAISERROR('Error occured during the insert: %s', 16, 1, @errorMessage); " - + "END CATCH;"; - String proc_sql = "EXECUTE [dbo].proc_insert_masse_TEST N'[{\"FIELD1\" : \"TEST\"}]';"; - - Connection conn = ds.getConnection(); - if (conn.getMetaData().getDatabaseMajorVersion() >= 13) - { - Statement stmt = conn.createStatement(); - stmt.execute(dropTable_sql); - stmt.execute(createTable_sql); - stmt.execute(dropProc_sql); - stmt.execute(createProc_sql); - stmt.execute(proc_sql); - ResultSet rs = stmt.getResultSet(); - try { - rs.next(); - fail("No exceptions caught."); - } catch (SQLException e) { - assertTrue(e.getMessage().contains("Error occured during the insert:"), "Unexpected Error Message: " + e.getMessage()); - } - } - } } From 03c6617c7fd08fe620fd701bbf2a40db91499e82 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Fri, 6 Apr 2018 15:56:22 -0700 Subject: [PATCH 18/18] Changes in preparation for 6.5.1 preview release (#670) * Added more information to error messages To help debug an irreproducable/random mismatch error if it occurs in the future. * Fix for the issue when using setMaxRows() with SHOWPLAN ON (#666) * Dont throw exception for colmetadata token * Adding a comment * Update comment * Adding a warning message * remove ignoreLengthPrefixedToken * Fix for uncaught/unhandled exception (#664) * Added more information to error messages To help debug an irreproducable/random mismatch error if it occurs in the future. * Revert "Added information to error message" This reverts commit 25301e6fa042661d4ee1c9dbc8d9cd23ebff8eb7. * Fix for #659 Added error handling logic for special cases. * Read message length Read the message length instead of reading until terminating character * Unsigned byte update Message length is an unsigned byte, converting before using. * Removed clunky hex conversions convert the byte straight to an int and use existing constants instead of making new ones * Narrowed trigger conditions fixed an issue where column names who had the hex token 'AA' would cause an error to be thrown. * Spacing fixes * Added test case * spacing adjustment * Edited test drop procedures Changed IF EXISTS DROP commands to be compatible with sql server 2008 * github spacing misalignment fixes * Changed test condition now only runs on compatible database or higher * Removed error check Removed a previous implementation in favor of one that changes the TDS parser * tdsreader change * removing test for now * enabled tests * github spacing fix * removed array import * removed "arrays" instead of "array" * spacing changes * Use Socket instead of SocketChannel when multiSubnetFailover=true (#662) * Upped SQL Server requirement to 2017 * Removing Exception Test Implement a more generic and compatible test in the future * Removed imports Used in removed test * Change in preperation for 6.5.1 preview release * Removed SNAPSHOT from POM * Added missing link * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md --- CHANGELOG.md | 13 +++++++++++++ README.md | 6 +++--- pom.xml | 2 +- .../microsoft/sqlserver/jdbc/SQLJdbcVersion.java | 2 +- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cdf308f6..0e5ed71e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) +## [6.5.1] Preview Release +### Added +- Test cases for Date, Time, and Datetime2 data types. [#558](https://github.com/Microsoft/mssql-jdbc/pull/558) + +### Fixed Issues +- Fixed an issue where ResultSetMetadata returned incorrect columnType for Geometry and Geography data types [#657](https://github.com/Microsoft/mssql-jdbc/pull/657) +- Fixed server side CPU Affinity problems caused by uneven connection distribution across NUMA Nodes when multiSubnetFailover is true [#662](https://github.com/Microsoft/mssql-jdbc/pull/662) +- Fixed an issue where Driver wasn't parsing TDS Packets completely to capture exceptions raised inside executed stored procedures [#664](https://github.com/Microsoft/mssql-jdbc/pull/664) +- Fixed an issue where driver throws exception when using setMaxRows() followed by query execution when SHOWPLAN_TEXT is ON [#666](https://github.com/Microsoft/mssql-jdbc/pull/666) + +### Changed +- Removed unused imports which forced users to import the ADAL4J library [#652](https://github.com/Microsoft/mssql-jdbc/pull/652) + ## [6.5.0] Preview Release ### Added - Support for spatial datatypes [#642](https://github.com/Microsoft/mssql-jdbc/pull/642) diff --git a/README.md b/README.md index 57ec2aa8d..ac50054b5 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ To get the latest preview version of the driver, add the following to your POM f com.microsoft.sqlserver mssql-jdbc - 6.5.0.jre9-preview + 6.5.1.jre9-preview ``` @@ -120,7 +120,7 @@ Projects that require either of the two features need to explicitly declare the com.microsoft.sqlserver mssql-jdbc - 6.5.0.jre9-preview + 6.5.1.jre9-preview compile @@ -136,7 +136,7 @@ Projects that require either of the two features need to explicitly declare the com.microsoft.sqlserver mssql-jdbc - 6.5.0.jre9-preview + 6.5.1.jre9-preview compile diff --git a/pom.xml b/pom.xml index 2eeec042b..cbaf68e49 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.microsoft.sqlserver mssql-jdbc - 6.5.1-SNAPSHOT.${jreVersion}-preview + 6.5.1.${jreVersion}-preview jar Microsoft JDBC Driver for SQL Server diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLJdbcVersion.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLJdbcVersion.java index eee5f7aa6..c27ee70de 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLJdbcVersion.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLJdbcVersion.java @@ -11,6 +11,6 @@ final class SQLJdbcVersion { static final int major = 6; static final int minor = 5; - static final int patch = 0; + static final int patch = 1; static final int build = 0; }