Skip to content

Commit 4b43864

Browse files
committed
Merge remote-tracking branch 'upstream/dev' into ICREnableFeature
2 parents f9d975f + a338b31 commit 4b43864

19 files changed

+183
-83
lines changed

CHANGELOG.md

+15
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,21 @@ All notable changes to this project will be documented in this file.
33

44
The format is based on [Keep a Changelog](http://keepachangelog.com/)
55

6+
## [7.1.3] Preview Release
7+
### Added
8+
- Added a new SQLServerMetaData constructor for string values of length greater than 4000 [#876](https://github.com/Microsoft/mssql-jdbc/pull/876)
9+
10+
### Fixed Issues
11+
- Fixed an issue with Geography.point() having coordinates reversed [#853](https://github.com/Microsoft/mssql-jdbc/pull/853)
12+
- Fixed intermittent test failures [#854](https://github.com/Microsoft/mssql-jdbc/pull/854) [#862](https://github.com/Microsoft/mssql-jdbc/pull/862) [#888](https://github.com/Microsoft/mssql-jdbc/pull/888)
13+
- Fixed an issue with setAutoCommit() leaving a transaction open when running against Azure SQL Data Warehouse [#881](https://github.com/Microsoft/mssql-jdbc/pull/881)
14+
15+
### Changed
16+
- Changed query timeout logic to use a single thread [#842](https://github.com/Microsoft/mssql-jdbc/pull/842)
17+
- Code cleanup [#857](https://github.com/Microsoft/mssql-jdbc/pull/857) [#873](https://github.com/Microsoft/mssql-jdbc/pull/873)
18+
- Removed populating Lobs when calling ResultSet.wasNull() [#875](https://github.com/Microsoft/mssql-jdbc/pull/875)
19+
- Improved retry logic for intermittent TLS1.2 issue when establishing a connection [#882](https://github.com/Microsoft/mssql-jdbc/pull/882)
20+
621
## [7.1.2] Preview Release
722
### Added
823
- Added support for JDK 11 [#824](https://github.com/Microsoft/mssql-jdbc/pull/824) [#837](https://github.com/Microsoft/mssql-jdbc/pull/837) [#807](https://github.com/Microsoft/mssql-jdbc/pull/807)

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ To get the latest preview version of the driver, add the following to your POM f
9090
<dependency>
9191
<groupId>com.microsoft.sqlserver</groupId>
9292
<artifactId>mssql-jdbc</artifactId>
93-
<version>7.1.2.jre11-preview</version>
93+
<version>7.1.3.jre11-preview</version>
9494
</dependency>
9595
```
9696

@@ -123,7 +123,7 @@ Projects that require either of the two features need to explicitly declare the
123123
<dependency>
124124
<groupId>com.microsoft.sqlserver</groupId>
125125
<artifactId>mssql-jdbc</artifactId>
126-
<version>7.1.2.jre11-preview</version>
126+
<version>7.1.3.jre11-preview</version>
127127
<scope>compile</scope>
128128
</dependency>
129129

@@ -140,7 +140,7 @@ Projects that require either of the two features need to explicitly declare the
140140
<dependency>
141141
<groupId>com.microsoft.sqlserver</groupId>
142142
<artifactId>mssql-jdbc</artifactId>
143-
<version>7.1.2.jre11-preview</version>
143+
<version>7.1.3.jre11-preview</version>
144144
<scope>compile</scope>
145145
</dependency>
146146

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
apply plugin: 'java'
1212

13-
version = '7.1.3-SNAPSHOT'
13+
version = '7.1.3'
1414
def jreVersion = ""
1515
def testOutputDir = file("build/classes/java/test")
1616
def archivesBaseName = 'mssql-jdbc'

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.microsoft.sqlserver</groupId>
88
<artifactId>mssql-jdbc</artifactId>
9-
<version>7.1.3-SNAPSHOT</version>
9+
<version>7.1.3</version>
1010
<packaging>jar</packaging>
1111

1212
<name>Microsoft JDBC Driver for SQL Server</name>

src/main/java/com/microsoft/sqlserver/jdbc/DDC.java

+6
Original file line numberDiff line numberDiff line change
@@ -596,8 +596,14 @@ static final Object convertStreamToObject(BaseInputStream stream, TypeInfo typeI
596596
if (JDBCType.GUID == jdbcType) {
597597
return Util.readGUID(byteValue);
598598
} else if (JDBCType.GEOMETRY == jdbcType) {
599+
if (!typeInfo.getSSTypeName().equalsIgnoreCase(jdbcType.toString())) {
600+
DataTypes.throwConversionError(typeInfo.getSSTypeName().toUpperCase(), jdbcType.toString());
601+
}
599602
return Geometry.STGeomFromWKB(byteValue);
600603
} else if (JDBCType.GEOGRAPHY == jdbcType) {
604+
if (!typeInfo.getSSTypeName().equalsIgnoreCase(jdbcType.toString())) {
605+
DataTypes.throwConversionError(typeInfo.getSSTypeName().toUpperCase(), jdbcType.toString());
606+
}
601607
return Geography.STGeomFromWKB(byteValue);
602608
} else {
603609
String hexString = Util.bytesToHexString(byteValue, byteValue.length);

src/main/java/com/microsoft/sqlserver/jdbc/Geography.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public static Geography parse(String wkt) throws SQLServerException {
140140
* if an exception occurs
141141
*/
142142
public static Geography point(double lat, double lon, int srid) throws SQLServerException {
143-
return new Geography("POINT (" + lat + " " + lon + ")", srid);
143+
return new Geography("POINT (" + lon + " " + lat + ")", srid);
144144
}
145145

146146
/**
@@ -212,8 +212,8 @@ public boolean hasZ() {
212212
* @return double value that represents the latitude.
213213
*/
214214
public Double getLatitude() {
215-
if (null != internalType && internalType == InternalSpatialDatatype.POINT && xValues.length == 1) {
216-
return xValues[0];
215+
if (null != internalType && internalType == InternalSpatialDatatype.POINT && yValues.length == 1) {
216+
return yValues[0];
217217
}
218218
return null;
219219
}
@@ -224,8 +224,8 @@ public Double getLatitude() {
224224
* @return double value that represents the longitude.
225225
*/
226226
public Double getLongitude() {
227-
if (null != internalType && internalType == InternalSpatialDatatype.POINT && yValues.length == 1) {
228-
return yValues[0];
227+
if (null != internalType && internalType == InternalSpatialDatatype.POINT && xValues.length == 1) {
228+
return xValues[0];
229229
}
230230
return null;
231231
}

src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java

+27-18
Original file line numberDiff line numberDiff line change
@@ -1826,31 +1826,40 @@ else if (con.getTrustManagerClass() != null) {
18261826
+ tmfDefaultAlgorithm + "\n") : "")
18271827
+ ((null != ksProvider) ? ("KeyStore provider info: " + ksProvider.getInfo() + "\n") : "")
18281828
+ "java.ext.dirs: " + System.getProperty("java.ext.dirs"));
1829+
// Retrieve the localized error message if possible.
1830+
String localizedMessage = e.getLocalizedMessage();
1831+
String errMsg = (localizedMessage != null) ? localizedMessage : e.getMessage();
1832+
/*
1833+
* Retrieve the error message of the cause too because actual error message can be wrapped into a different
1834+
* message when re-thrown from underlying InputStream.
1835+
*/
1836+
String causeErrMsg = null;
1837+
Throwable cause = e.getCause();
1838+
if (cause != null) {
1839+
String causeLocalizedMessage = cause.getLocalizedMessage();
1840+
causeErrMsg = (causeLocalizedMessage != null) ? causeLocalizedMessage : cause.getMessage();
1841+
}
18291842

18301843
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_sslFailed"));
1831-
Object[] msgArgs = {e.getMessage()};
1832-
1833-
// It is important to get the localized message here, otherwise error messages won't match for different
1834-
// locales.
1835-
String errMsg = e.getLocalizedMessage();
1836-
// If the message is null replace it with the non-localized message or a dummy string. This can happen if a
1837-
// custom
1838-
// TrustManager implementation is specified that does not provide localized messages.
1839-
if (errMsg == null) {
1840-
errMsg = e.getMessage();
1841-
}
1842-
if (errMsg == null) {
1843-
errMsg = "";
1844-
}
1845-
// The error message may have a connection id appended to it. Extract the message only for comparison.
1846-
// This client connection id is appended in method checkAndAppendClientConnId().
1847-
if (errMsg.contains(SQLServerException.LOG_CLIENT_CONNECTION_ID_PREFIX)) {
1844+
Object[] msgArgs = {errMsg};
1845+
1846+
/*
1847+
* The error message may have a connection id appended to it. Extract the message only for comparison. This
1848+
* client connection id is appended in method checkAndAppendClientConnId().
1849+
*/
1850+
if (errMsg != null && errMsg.contains(SQLServerException.LOG_CLIENT_CONNECTION_ID_PREFIX)) {
18481851
errMsg = errMsg.substring(0, errMsg.indexOf(SQLServerException.LOG_CLIENT_CONNECTION_ID_PREFIX));
18491852
}
18501853

1854+
if (causeErrMsg != null && causeErrMsg.contains(SQLServerException.LOG_CLIENT_CONNECTION_ID_PREFIX)) {
1855+
causeErrMsg = causeErrMsg.substring(0,
1856+
causeErrMsg.indexOf(SQLServerException.LOG_CLIENT_CONNECTION_ID_PREFIX));
1857+
}
1858+
18511859
// Isolate the TLS1.2 intermittent connection error.
18521860
if (e instanceof IOException && (SSLHandhsakeState.SSL_HANDHSAKE_STARTED == handshakeState)
1853-
&& (errMsg.equals(SQLServerException.getErrString("R_truncatedServerResponse")))) {
1861+
&& (SQLServerException.getErrString("R_truncatedServerResponse").equals(errMsg)
1862+
|| SQLServerException.getErrString("R_truncatedServerResponse").equals(causeErrMsg))) {
18541863
con.terminate(SQLServerException.DRIVER_ERROR_INTERMITTENT_TLS_FAILED, form.format(msgArgs), e);
18551864
} else {
18561865
con.terminate(SQLServerException.DRIVER_ERROR_SSL_FAILED, form.format(msgArgs), e);

src/main/java/com/microsoft/sqlserver/jdbc/SQLServerMetaData.java

+17
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,23 @@ public SQLServerMetaData(String columnName, int sqlType, int precision, int scal
6060
this.scale = scale;
6161
}
6262

63+
/**
64+
* Constructs a SQLServerMetaData with the column name, SQL type, and length (for String data).
65+
* The length is used to differentiate large strings from strings with length less than 4000 characters.
66+
*
67+
* @param columnName
68+
* the name of the column
69+
* @param sqlType
70+
* the SQL type of the column
71+
* @param length
72+
* the length of the string type
73+
*/
74+
public SQLServerMetaData(String columnName, int sqlType, int length) {
75+
this.columnName = columnName;
76+
this.javaSqlType = sqlType;
77+
this.precision = length;
78+
}
79+
6380
/**
6481
* Constructs a SQLServerMetaData.
6582
*

src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java

-1
Original file line numberDiff line numberDiff line change
@@ -1076,7 +1076,6 @@ public boolean next() throws SQLServerException {
10761076
public boolean wasNull() throws SQLServerException {
10771077
loggerExternal.entering(getClassNameLogging(), "wasNull");
10781078
checkClosed();
1079-
fillLOBs();
10801079
loggerExternal.exiting(getClassNameLogging(), "wasNull", lastValueWasNull);
10811080
return lastValueWasNull;
10821081
}

src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyColumnMappingTest.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package com.microsoft.sqlserver.jdbc.bulkCopy;
66

77
import static org.junit.jupiter.api.Assertions.fail;
8+
import static org.junit.jupiter.api.Assertions.assertTrue;
89

910
import java.sql.ResultSet;
1011
import java.sql.ResultSetMetaData;
@@ -21,6 +22,7 @@
2122

2223
import com.microsoft.sqlserver.jdbc.ComparisonUtil;
2324
import com.microsoft.sqlserver.jdbc.TestResource;
25+
import com.microsoft.sqlserver.jdbc.TestUtils;
2426
import com.microsoft.sqlserver.testframework.DBConnection;
2527
import com.microsoft.sqlserver.testframework.DBResultSet;
2628
import com.microsoft.sqlserver.testframework.DBStatement;
@@ -385,10 +387,10 @@ private void validateValuesRepetitiveCM(DBConnection con, DBTable sourceTable,
385387
int totalColumns = sourceMeta.getColumnCount();
386388

387389
// verify data from sourceType and resultSet
390+
int numRows = 0;
388391
while (srcResultSet.next() && dstResultSet.next()) {
392+
numRows++;
389393
for (int i = 1; i <= totalColumns; i++) {
390-
// TODO: check row and column count in both the tables
391-
392394
Object srcValue, dstValue;
393395
srcValue = srcResultSet.getObject(i);
394396
dstValue = dstResultSet.getObject(i);
@@ -403,6 +405,11 @@ private void validateValuesRepetitiveCM(DBConnection con, DBTable sourceTable,
403405
}
404406
}
405407
}
408+
409+
// verify number of rows and columns
410+
assertTrue(((ResultSet) dstResultSet.product()).getMetaData().getColumnCount() == totalColumns + 1);
411+
assertTrue(sourceTable.getTotalRows() == numRows);
412+
assertTrue(destinationTable.getTotalRows() == numRows);
406413
}
407414
}
408415

src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyResultSetCursorTest.java

+16-17
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ private void serverCursorsTest(int resultSetType, int resultSetConcurrency) thro
7070

7171
try (Statement stmt2 = conn.createStatement(resultSetType, resultSetConcurrency);
7272
ResultSet rs = stmt2
73-
.executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(srcTable));
73+
.executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(srcTable) + " ORDER BY id ASC");
7474
SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(conn)) {
7575
bulkCopy.setDestinationTableName(AbstractSQLGenerator.escapeIdentifier(desTable));
7676
bulkCopy.writeToServer(rs);
@@ -96,7 +96,7 @@ public void testSelectMethodSetToCursor() throws SQLException {
9696
createTables(stmt);
9797
populateSourceTable();
9898

99-
try (ResultSet rs = stmt.executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(srcTable));
99+
try (ResultSet rs = stmt.executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(srcTable) + " ORDER BY id ASC");
100100
SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(conn)) {
101101

102102
bulkCopy.setDestinationTableName(AbstractSQLGenerator.escapeIdentifier(desTable));
@@ -122,7 +122,7 @@ public void testMultiplePreparedStatementAndResultSet() throws SQLException {
122122

123123
try (Statement stmt1 = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
124124
ResultSet rs = stmt1
125-
.executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(srcTable))) {
125+
.executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(srcTable) + " ORDER BY id ASC")) {
126126
try (SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(conn)) {
127127
bulkCopy.setDestinationTableName(AbstractSQLGenerator.escapeIdentifier(desTable));
128128
bulkCopy.writeToServer(rs);
@@ -158,7 +158,7 @@ public void testMultiplePreparedStatementAndResultSet() throws SQLException {
158158
try (Statement stmt2 = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
159159
ResultSet.CONCUR_UPDATABLE);
160160
ResultSet rs2 = stmt2
161-
.executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(srcTable));
161+
.executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(srcTable) + " ORDER BY id ASC");
162162
SQLServerBulkCopy bulkCopy3 = new SQLServerBulkCopy(conn)) {
163163
bulkCopy3.setDestinationTableName(AbstractSQLGenerator.escapeIdentifier(desTable));
164164
bulkCopy3.writeToServer(rs2);
@@ -170,20 +170,20 @@ public void testMultiplePreparedStatementAndResultSet() throws SQLException {
170170

171171
private static void verifyDestinationTableData(int expectedNumberOfRows) throws SQLException {
172172
try (Connection conn = DriverManager.getConnection(connectionString); ResultSet rs = conn.createStatement()
173-
.executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(desTable))) {
173+
.executeQuery("select * from " + AbstractSQLGenerator.escapeIdentifier(desTable) + " ORDER BY id ASC")) {
174174

175175
int expectedArrayLength = expectedBigDecimals.length;
176176

177177
int i = 0;
178178
while (rs.next()) {
179-
assertTrue(rs.getString(1).equals(expectedBigDecimalStrings[i % expectedArrayLength]), "Expected Value:"
180-
+ expectedBigDecimalStrings[i % expectedArrayLength] + ", Actual Value: " + rs.getString(1));
181-
assertTrue(rs.getString(2).trim().equals(expectedStrings[i % expectedArrayLength]), "Expected Value:"
182-
+ expectedStrings[i % expectedArrayLength] + ", Actual Value: " + rs.getString(2));
183-
assertTrue(rs.getString(3).equals(expectedTimestampStrings[i % expectedArrayLength]), "Expected Value:"
184-
+ expectedTimestampStrings[i % expectedArrayLength] + ", Actual Value: " + rs.getString(3));
185-
assertTrue(rs.getString(4).trim().equals(expectedStrings[i % expectedArrayLength]), "Expected Value:"
186-
+ expectedStrings[i % expectedArrayLength] + ", Actual Value: " + rs.getString(4));
179+
assertTrue(rs.getString(2).equals(expectedBigDecimalStrings[i % expectedArrayLength]), "Expected Value:"
180+
+ expectedBigDecimalStrings[i % expectedArrayLength] + ", Actual Value: " + rs.getString(2));
181+
assertTrue(rs.getString(3).trim().equals(expectedStrings[i % expectedArrayLength]), "Expected Value:"
182+
+ expectedStrings[i % expectedArrayLength] + ", Actual Value: " + rs.getString(3));
183+
assertTrue(rs.getString(4).equals(expectedTimestampStrings[i % expectedArrayLength]), "Expected Value:"
184+
+ expectedTimestampStrings[i % expectedArrayLength] + ", Actual Value: " + rs.getString(4));
185+
assertTrue(rs.getString(5).trim().equals(expectedStrings[i % expectedArrayLength]), "Expected Value:"
186+
+ expectedStrings[i % expectedArrayLength] + ", Actual Value: " + rs.getString(5));
187187
i++;
188188
}
189189

@@ -196,8 +196,7 @@ private static void populateSourceTable() throws SQLException {
196196
Calendar calGMT = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
197197

198198
try (Connection conn = DriverManager.getConnection(connectionString);
199-
SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) conn.prepareStatement(sql)) {
200-
199+
SQLServerPreparedStatement pstmt = (SQLServerPreparedStatement) conn.prepareStatement(sql)) {
201200
for (int i = 0; i < expectedBigDecimals.length; i++) {
202201
pstmt.setBigDecimal(1, expectedBigDecimals[i]);
203202
pstmt.setString(2, expectedStrings[i]);
@@ -219,10 +218,10 @@ private static void dropTables(Statement stmt) throws SQLException {
219218

220219
private static void createTables(Statement stmt) throws SQLException {
221220
String sql = "create table " + AbstractSQLGenerator.escapeIdentifier(srcTable)
222-
+ " (c1 decimal(10,5) null, c2 nchar(50) null, c3 datetime2(7) null, c4 char(7000));";
221+
+ " (id INT NOT NULL IDENTITY PRIMARY KEY, c1 decimal(10,5) null, c2 nchar(50) null, c3 datetime2(7) null, c4 char(7000));";
223222
stmt.execute(sql);
224223
sql = "create table " + AbstractSQLGenerator.escapeIdentifier(desTable)
225-
+ " (c1 decimal(10,5) null, c2 nchar(50) null, c3 datetime2(7) null, c4 char(7000));";
224+
+ " (id INT NOT NULL IDENTITY PRIMARY KEY, c1 decimal(10,5) null, c2 nchar(50) null, c3 datetime2(7) null, c4 char(7000));";
226225
stmt.execute(sql);
227226
}
228227

0 commit comments

Comments
 (0)