From a310fd2da2dd7067926564f2c8275b714ebf35e0 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Mon, 5 Feb 2018 12:51:32 -0800 Subject: [PATCH 01/21] Added more information to error messages To help debug an irreproducable/random mismatch error if it occurs in the future. --- .../sqlserver/testframework/util/ComparisonUtil.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/testframework/util/ComparisonUtil.java b/src/test/java/com/microsoft/sqlserver/testframework/util/ComparisonUtil.java index c942f8c9ad..b297a3924b 100644 --- a/src/test/java/com/microsoft/sqlserver/testframework/util/ComparisonUtil.java +++ b/src/test/java/com/microsoft/sqlserver/testframework/util/ComparisonUtil.java @@ -92,16 +92,16 @@ public static void compareExpectedAndActual(int dataType, else switch (dataType) { case java.sql.Types.BIGINT: - assertTrue((((Long) expectedValue).longValue() == ((Long) actualValue).longValue()), "Unexpected bigint value"); + assertTrue((((Long) expectedValue).longValue() == ((Long) actualValue).longValue()), "Unexpected bigint value. Expected:" + ((Long) expectedValue).longValue() + " Actual:" + ((Long) actualValue).longValue()); break; case java.sql.Types.INTEGER: - assertTrue((((Integer) expectedValue).intValue() == ((Integer) actualValue).intValue()), "Unexpected int value"); + assertTrue((((Integer) expectedValue).intValue() == ((Integer) actualValue).intValue()), "Unexpected int value. Expected:" + ((Integer) expectedValue).intValue() + " Actual:" + ((Integer) actualValue).intValue()); break; case java.sql.Types.SMALLINT: case java.sql.Types.TINYINT: - assertTrue((((Short) expectedValue).shortValue() == ((Short) actualValue).shortValue()), "Unexpected smallint/tinyint value"); + assertTrue((((Short) expectedValue).shortValue() == ((Short) actualValue).shortValue()), "Unexpected smallint/tinyint value. Expected:" + ((Short) expectedValue).shortValue() + " Actual:" + ((Short) actualValue).shortValue()); break; case java.sql.Types.BIT: @@ -115,11 +115,11 @@ public static void compareExpectedAndActual(int dataType, break; case java.sql.Types.DOUBLE: - assertTrue((((Double) expectedValue).doubleValue() == ((Double) actualValue).doubleValue()), "Unexpected float value"); + assertTrue((((Double) expectedValue).doubleValue() == ((Double) actualValue).doubleValue()), "Unexpected double value. Expected:" + ((Double) expectedValue).doubleValue() + " Actual:" + ((Double) actualValue).doubleValue()); break; case java.sql.Types.REAL: - assertTrue((((Float) expectedValue).floatValue() == ((Float) actualValue).floatValue()), "Unexpected real value"); + assertTrue((((Float) expectedValue).floatValue() == ((Float) actualValue).floatValue()), "Unexpected real/float value. Expected:" + ((Float) expectedValue).floatValue() + " Actual:" + ((Float) actualValue).floatValue()); break; case java.sql.Types.VARCHAR: From 01133412f12f034f92c63df41bcecf6bf4d7433d Mon Sep 17 00:00:00 2001 From: rene-ye Date: Tue, 27 Feb 2018 11:11:52 -0800 Subject: [PATCH 02/21] Revert "Added information to error message" This reverts commit 25301e6fa042661d4ee1c9dbc8d9cd23ebff8eb7. --- .../sqlserver/jdbc/SQLServerConnection.java | 17 ++++++----------- .../testframework/util/ComparisonUtil.java | 10 +++++----- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java index 587ffb75ea..432aa9e32b 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java @@ -3420,24 +3420,19 @@ final boolean doExecute() throws SQLServerException { } } finally { - if (integratedSecurity) { + if (integratedSecurity) { + if (null != authentication) + authentication.ReleaseClientContext(); + authentication = null; + if (null != ImpersonatedUserCred) { try { - if (ImpersonatedUserCred.getRemainingLifetime() <= 0) { - if (null != authentication) - authentication.ReleaseClientContext(); - authentication = null; - ImpersonatedUserCred.dispose(); - } + ImpersonatedUserCred.dispose(); } catch (GSSException e) { if (connectionlogger.isLoggable(Level.FINER)) connectionlogger.finer(toString() + " Release of the credentials failed GSSException: " + e); } - } else { - if (null != authentication) - authentication.ReleaseClientContext(); - authentication = null; } } } diff --git a/src/test/java/com/microsoft/sqlserver/testframework/util/ComparisonUtil.java b/src/test/java/com/microsoft/sqlserver/testframework/util/ComparisonUtil.java index b297a3924b..c942f8c9ad 100644 --- a/src/test/java/com/microsoft/sqlserver/testframework/util/ComparisonUtil.java +++ b/src/test/java/com/microsoft/sqlserver/testframework/util/ComparisonUtil.java @@ -92,16 +92,16 @@ public static void compareExpectedAndActual(int dataType, else switch (dataType) { case java.sql.Types.BIGINT: - assertTrue((((Long) expectedValue).longValue() == ((Long) actualValue).longValue()), "Unexpected bigint value. Expected:" + ((Long) expectedValue).longValue() + " Actual:" + ((Long) actualValue).longValue()); + assertTrue((((Long) expectedValue).longValue() == ((Long) actualValue).longValue()), "Unexpected bigint value"); break; case java.sql.Types.INTEGER: - assertTrue((((Integer) expectedValue).intValue() == ((Integer) actualValue).intValue()), "Unexpected int value. Expected:" + ((Integer) expectedValue).intValue() + " Actual:" + ((Integer) actualValue).intValue()); + assertTrue((((Integer) expectedValue).intValue() == ((Integer) actualValue).intValue()), "Unexpected int value"); break; case java.sql.Types.SMALLINT: case java.sql.Types.TINYINT: - assertTrue((((Short) expectedValue).shortValue() == ((Short) actualValue).shortValue()), "Unexpected smallint/tinyint value. Expected:" + ((Short) expectedValue).shortValue() + " Actual:" + ((Short) actualValue).shortValue()); + assertTrue((((Short) expectedValue).shortValue() == ((Short) actualValue).shortValue()), "Unexpected smallint/tinyint value"); break; case java.sql.Types.BIT: @@ -115,11 +115,11 @@ public static void compareExpectedAndActual(int dataType, break; case java.sql.Types.DOUBLE: - assertTrue((((Double) expectedValue).doubleValue() == ((Double) actualValue).doubleValue()), "Unexpected double value. Expected:" + ((Double) expectedValue).doubleValue() + " Actual:" + ((Double) actualValue).doubleValue()); + assertTrue((((Double) expectedValue).doubleValue() == ((Double) actualValue).doubleValue()), "Unexpected float value"); break; case java.sql.Types.REAL: - assertTrue((((Float) expectedValue).floatValue() == ((Float) actualValue).floatValue()), "Unexpected real/float value. Expected:" + ((Float) expectedValue).floatValue() + " Actual:" + ((Float) actualValue).floatValue()); + assertTrue((((Float) expectedValue).floatValue() == ((Float) actualValue).floatValue()), "Unexpected real value"); break; case java.sql.Types.VARCHAR: From 6d1791d58526ed4c21a7e569b11dc6cc1fdca74c Mon Sep 17 00:00:00 2001 From: rene-ye Date: Wed, 21 Mar 2018 11:40:23 -0700 Subject: [PATCH 03/21] Fix for #659 Added error handling logic for special cases. --- .../sqlserver/jdbc/SQLServerResultSet.java | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index b993a6d3c3..4462a26b89 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -12,6 +12,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.Reader; +import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.sql.Array; import java.sql.Blob; @@ -170,6 +171,7 @@ final void setDeletedCurrentRow(boolean rowDeleted) { * possibly never (as is the case with DYNAMIC cursors). */ static final int UNKNOWN_ROW_COUNT = -3; + static final int ERROR_TOKEN_INDICATOR = -61; private int rowCount; /** The current row's column values */ @@ -1025,7 +1027,29 @@ public boolean next() throws SQLServerException { return true; } } - + + //We have zero rows, if an error occurred, we need to throw an exception + if (rowCount == BEFORE_FIRST_ROW) { + int packetSize = tdsReader.available(); + if (packetSize > 0) { + //There's a response available, but we have no rows. Take a look through the packet. + byte[] b = new byte[packetSize]; + tdsReader.readBytes(b, 0, packetSize); + for (int i = 0; i < packetSize; i++) { + //Parse the packet, look for a TDS 'AA' token indicating an error. + if (b[i] == ERROR_TOKEN_INDICATOR) { + try { + //Start from the byte after token for the error message + String errMsg = readErrorPacket(new String(b, "UTF-16"), i+1); + throw new SQLServerException(errMsg, SQLState.DATA_EXCEPTION_NOT_SPECIFIC, DriverError.NOT_SET, null); + } catch (UnsupportedEncodingException e) { + throw new SQLServerException(e.getMessage(), SQLState.DATA_EXCEPTION_NOT_SPECIFIC, DriverError.NOT_SET, e); + } + } + } + } + } + // Otherwise, we have reached the end of the result set if (UNKNOWN_ROW_COUNT == rowCount) rowCount = currentRow; @@ -1034,6 +1058,22 @@ public boolean next() throws SQLServerException { loggerExternal.exiting(getClassNameLogging(), "next", false); return false; } + + /* + * A function that obtains the error message from a TDS packet. + * This function should only be called after a TDS Error Token has been identified. + * + * @return a string representing the error message + */ + private String readErrorPacket(String s, int begin) { + for (int i = begin; i < s.length(); i++) { + String c = Character.toString(s.charAt(i)); + if (!c.matches("[A-Za-z0-9 _.,:;!@#$%^&*()/\"\'\t\n]")) { //there is no token separator for the err message fields, + return s.substring(begin, i); //but they're always separated by invalid UTF-16 characters + } + } + return ""; + } public boolean wasNull() throws SQLServerException { loggerExternal.entering(getClassNameLogging(), "wasNull"); From 9124dbe22769abb3f21f05e2fd775c5167036a39 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Wed, 21 Mar 2018 15:03:00 -0700 Subject: [PATCH 04/21] Read message length Read the message length instead of reading until terminating character --- .../sqlserver/jdbc/SQLServerResultSet.java | 74 +++++++++++-------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index 4462a26b89..f16d012d4a 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -171,9 +171,16 @@ final void setDeletedCurrentRow(boolean rowDeleted) { * possibly never (as is the case with DYNAMIC cursors). */ static final int UNKNOWN_ROW_COUNT = -3; - static final int ERROR_TOKEN_INDICATOR = -61; private int rowCount; - + + /* + * The number of bytes to skip when parsing an error packet. These bytes contain relevant information but we don't need it. + * + * The hex representation of the TDS ERR token "170". + */ + static final int ERROR_EXCESS_INFO = 10; + static final String ERROR_TOKEN_INDICATOR = "aa"; + /** The current row's column values */ private final Column[] columns; @@ -1030,24 +1037,7 @@ public boolean next() throws SQLServerException { //We have zero rows, if an error occurred, we need to throw an exception if (rowCount == BEFORE_FIRST_ROW) { - int packetSize = tdsReader.available(); - if (packetSize > 0) { - //There's a response available, but we have no rows. Take a look through the packet. - byte[] b = new byte[packetSize]; - tdsReader.readBytes(b, 0, packetSize); - for (int i = 0; i < packetSize; i++) { - //Parse the packet, look for a TDS 'AA' token indicating an error. - if (b[i] == ERROR_TOKEN_INDICATOR) { - try { - //Start from the byte after token for the error message - String errMsg = readErrorPacket(new String(b, "UTF-16"), i+1); - throw new SQLServerException(errMsg, SQLState.DATA_EXCEPTION_NOT_SPECIFIC, DriverError.NOT_SET, null); - } catch (UnsupportedEncodingException e) { - throw new SQLServerException(e.getMessage(), SQLState.DATA_EXCEPTION_NOT_SPECIFIC, DriverError.NOT_SET, e); - } - } - } - } + lookForErrors(); } // Otherwise, we have reached the end of the result set @@ -1060,19 +1050,43 @@ public boolean next() throws SQLServerException { } /* - * A function that obtains the error message from a TDS packet. - * This function should only be called after a TDS Error Token has been identified. + * A function that looks for an error message in the current TDS packet, and throws an SQLServerException if found. * - * @return a string representing the error message + * @throw SQLServerException + * if the packet contains an error message + * @return */ - private String readErrorPacket(String s, int begin) { - for (int i = begin; i < s.length(); i++) { - String c = Character.toString(s.charAt(i)); - if (!c.matches("[A-Za-z0-9 _.,:;!@#$%^&*()/\"\'\t\n]")) { //there is no token separator for the err message fields, - return s.substring(begin, i); //but they're always separated by invalid UTF-16 characters - } + private void lookForErrors() throws SQLServerException { + int packetSize = tdsReader.available(); + if (packetSize > 0) { + //There's a response available, but we have no rows. Take a look through the packet. + byte[] byteBuffer = new byte[packetSize]; + tdsReader.readBytes(byteBuffer, 0, packetSize); + for (int i = 0; i < byteBuffer.length; i++) { + String hexByte = ""; + hexByte += Character.forDigit((byteBuffer[i] >> 4) & 0xF, 16); + hexByte += Character.forDigit((byteBuffer[i] & 0xF), 16); + //Parse the packet, look for a TDS 'AA' token indicating an error. + if (hexByte.compareTo(ERROR_TOKEN_INDICATOR) == 0) { + try { + int truncatedSize = packetSize - i - ERROR_EXCESS_INFO; + //The fields are of varying byte sizes, this causes problems with String[byte[], "UTF-16") + //Remove as many hex values from the front as possible to avoid any possible inconsistencies + byte[] errB = new byte[truncatedSize]; + for (int j = packetSize - errB.length; j < packetSize; j++) { + errB[j - (packetSize - truncatedSize)] = byteBuffer[j]; + } + //Get the message length, represented as 1 byte in front of our message + int messageLength = ((Byte)byteBuffer[packetSize - errB.length - 1]).intValue(); + //Convert only the message to UTF-16 + String errMsg = new String(errB, "UTF-16").substring(0,messageLength); + throw new SQLServerException(errMsg, SQLState.DATA_EXCEPTION_NOT_SPECIFIC, DriverError.NOT_SET, null); + } catch (UnsupportedEncodingException e) { + throw new SQLServerException(e.getMessage(), SQLState.DATA_EXCEPTION_NOT_SPECIFIC, DriverError.NOT_SET, e); + } + } + } } - return ""; } public boolean wasNull() throws SQLServerException { From 4d408c937a8ee33104e93965b6b42b18fe049426 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Wed, 21 Mar 2018 15:23:43 -0700 Subject: [PATCH 05/21] Unsigned byte update Message length is an unsigned byte, converting before using. --- .../sqlserver/jdbc/SQLServerResultSet.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index f16d012d4a..bb6922a63d 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -1035,7 +1035,7 @@ public boolean next() throws SQLServerException { } } - //We have zero rows, if an error occurred, we need to throw an exception + // We have zero rows, if an error occurred, we need to throw an exception if (rowCount == BEFORE_FIRST_ROW) { lookForErrors(); } @@ -1059,26 +1059,27 @@ public boolean next() throws SQLServerException { private void lookForErrors() throws SQLServerException { int packetSize = tdsReader.available(); if (packetSize > 0) { - //There's a response available, but we have no rows. Take a look through the packet. + // There's a response available, but we have no rows. Take a look through the packet. byte[] byteBuffer = new byte[packetSize]; tdsReader.readBytes(byteBuffer, 0, packetSize); for (int i = 0; i < byteBuffer.length; i++) { String hexByte = ""; hexByte += Character.forDigit((byteBuffer[i] >> 4) & 0xF, 16); hexByte += Character.forDigit((byteBuffer[i] & 0xF), 16); - //Parse the packet, look for a TDS 'AA' token indicating an error. + // Parse the packet, look for a TDS 'AA' token indicating an error. if (hexByte.compareTo(ERROR_TOKEN_INDICATOR) == 0) { try { int truncatedSize = packetSize - i - ERROR_EXCESS_INFO; - //The fields are of varying byte sizes, this causes problems with String[byte[], "UTF-16") - //Remove as many hex values from the front as possible to avoid any possible inconsistencies + // The fields are of varying byte sizes, this causes problems with String[byte[], "UTF-16") + // Remove as many hex values from the front as possible to avoid any possible inconsistencies byte[] errB = new byte[truncatedSize]; for (int j = packetSize - errB.length; j < packetSize; j++) { errB[j - (packetSize - truncatedSize)] = byteBuffer[j]; } - //Get the message length, represented as 1 byte in front of our message - int messageLength = ((Byte)byteBuffer[packetSize - errB.length - 1]).intValue(); - //Convert only the message to UTF-16 + // Get the message length, represented as 1 byte in front of our message + // This byte is unsigned so we convert with '& 0xFF' + int messageLength = byteBuffer[packetSize - errB.length - 1] & 0xFF; + // Convert only the message to UTF-16 String errMsg = new String(errB, "UTF-16").substring(0,messageLength); throw new SQLServerException(errMsg, SQLState.DATA_EXCEPTION_NOT_SPECIFIC, DriverError.NOT_SET, null); } catch (UnsupportedEncodingException e) { From 145ccee5c4c1726bf6c0c838b7beef24294eaa9a Mon Sep 17 00:00:00 2001 From: rene-ye Date: Thu, 22 Mar 2018 11:43:30 -0700 Subject: [PATCH 06/21] Removed clunky hex conversions convert the byte straight to an int and use existing constants instead of making new ones --- .../sqlserver/jdbc/SQLServerResultSet.java | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index bb6922a63d..f683e742c2 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -173,13 +173,8 @@ final void setDeletedCurrentRow(boolean rowDeleted) { static final int UNKNOWN_ROW_COUNT = -3; private int rowCount; - /* - * The number of bytes to skip when parsing an error packet. These bytes contain relevant information but we don't need it. - * - * The hex representation of the TDS ERR token "170". - */ + //The number of bytes to skip from a TDS token to reach the message. Used when parsing a TDS packet. static final int ERROR_EXCESS_INFO = 10; - static final String ERROR_TOKEN_INDICATOR = "aa"; /** The current row's column values */ private final Column[] columns; @@ -1063,11 +1058,9 @@ private void lookForErrors() throws SQLServerException { byte[] byteBuffer = new byte[packetSize]; tdsReader.readBytes(byteBuffer, 0, packetSize); for (int i = 0; i < byteBuffer.length; i++) { - String hexByte = ""; - hexByte += Character.forDigit((byteBuffer[i] >> 4) & 0xF, 16); - hexByte += Character.forDigit((byteBuffer[i] & 0xF), 16); + int token = byteBuffer[i] & 0xFF; // Parse the packet, look for a TDS 'AA' token indicating an error. - if (hexByte.compareTo(ERROR_TOKEN_INDICATOR) == 0) { + if (token == TDS.TDS_ERR) { try { int truncatedSize = packetSize - i - ERROR_EXCESS_INFO; // The fields are of varying byte sizes, this causes problems with String[byte[], "UTF-16") From f7ef7b96e3a1bd5fb2c76b6b0b0bbe66212430c1 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Fri, 23 Mar 2018 09:56:16 -0700 Subject: [PATCH 07/21] Narrowed trigger conditions fixed an issue where column names who had the hex token 'AA' would cause an error to be thrown. --- .../sqlserver/jdbc/SQLServerResultSet.java | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index f683e742c2..5b43443ff6 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -27,6 +27,7 @@ import java.sql.SQLWarning; import java.sql.SQLXML; import java.text.MessageFormat; +import java.util.Arrays; import java.util.Calendar; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; @@ -1030,9 +1031,9 @@ public boolean next() throws SQLServerException { } } - // We have zero rows, if an error occurred, we need to throw an exception - if (rowCount == BEFORE_FIRST_ROW) { - lookForErrors(); + // We have no rows, if an error occurred, there should be 1 column and we need to throw an exception + if (rowCount == BEFORE_FIRST_ROW && columns.length == 1) { + lookForErrors(); } // Otherwise, we have reached the end of the result set @@ -1052,7 +1053,7 @@ public boolean next() throws SQLServerException { * @return */ private void lookForErrors() throws SQLServerException { - int packetSize = tdsReader.available(); + int packetSize = tdsReader.availableCurrentPacket(); if (packetSize > 0) { // There's a response available, but we have no rows. Take a look through the packet. byte[] byteBuffer = new byte[packetSize]; @@ -1062,20 +1063,17 @@ private void lookForErrors() throws SQLServerException { // Parse the packet, look for a TDS 'AA' token indicating an error. if (token == TDS.TDS_ERR) { try { - int truncatedSize = packetSize - i - ERROR_EXCESS_INFO; - // The fields are of varying byte sizes, this causes problems with String[byte[], "UTF-16") - // Remove as many hex values from the front as possible to avoid any possible inconsistencies - byte[] errB = new byte[truncatedSize]; - for (int j = packetSize - errB.length; j < packetSize; j++) { - errB[j - (packetSize - truncatedSize)] = byteBuffer[j]; - } + int messageOffset = i + ERROR_EXCESS_INFO; // Get the message length, represented as 1 byte in front of our message // This byte is unsigned so we convert with '& 0xFF' - int messageLength = byteBuffer[packetSize - errB.length - 1] & 0xFF; - // Convert only the message to UTF-16 - String errMsg = new String(errB, "UTF-16").substring(0,messageLength); + int messageLength = byteBuffer[messageOffset - 1] & 0xFF; + // The fields are of varying byte sizes, this causes problems with String[byte[], "UTF-16") + // Remove as many values from the front as possible to avoid any possible inconsistencies + // Also make sure not to parse anything after the message, 2 bytes for every UTF-16 character + byte[] errB = Arrays.copyOfRange(byteBuffer, messageOffset, messageOffset + (messageLength*2)); + String errMsg = new String(errB, "UTF-16"); throw new SQLServerException(errMsg, SQLState.DATA_EXCEPTION_NOT_SPECIFIC, DriverError.NOT_SET, null); - } catch (UnsupportedEncodingException e) { + } catch (UnsupportedEncodingException e) { throw new SQLServerException(e.getMessage(), SQLState.DATA_EXCEPTION_NOT_SPECIFIC, DriverError.NOT_SET, e); } } From ab46c2790cbf24b577d3711e4bc671411ebc662d Mon Sep 17 00:00:00 2001 From: rene-ye Date: Fri, 23 Mar 2018 10:03:58 -0700 Subject: [PATCH 08/21] Spacing fixes --- .../com/microsoft/sqlserver/jdbc/SQLServerResultSet.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index 5b43443ff6..ad7c6a385d 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -1071,11 +1071,11 @@ private void lookForErrors() throws SQLServerException { // Remove as many values from the front as possible to avoid any possible inconsistencies // Also make sure not to parse anything after the message, 2 bytes for every UTF-16 character byte[] errB = Arrays.copyOfRange(byteBuffer, messageOffset, messageOffset + (messageLength*2)); - String errMsg = new String(errB, "UTF-16"); - throw new SQLServerException(errMsg, SQLState.DATA_EXCEPTION_NOT_SPECIFIC, DriverError.NOT_SET, null); + String errMsg = new String(errB, "UTF-16"); + throw new SQLServerException(errMsg, SQLState.DATA_EXCEPTION_NOT_SPECIFIC, DriverError.NOT_SET, null); } catch (UnsupportedEncodingException e) { - throw new SQLServerException(e.getMessage(), SQLState.DATA_EXCEPTION_NOT_SPECIFIC, DriverError.NOT_SET, e); - } + throw new SQLServerException(e.getMessage(), SQLState.DATA_EXCEPTION_NOT_SPECIFIC, DriverError.NOT_SET, e); + } } } } From 9f9872aff0aeddeca5a1677c18438456bbbd8507 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Fri, 23 Mar 2018 14:13:14 -0700 Subject: [PATCH 09/21] Added test case --- .../jdbc/exception/ExceptionTest.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) 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 37dd3e6b65..4c78554604 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,54 @@ 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(); + 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()); + } + } } \ No newline at end of file From 247c419f9605fc8c2cdcf2f9d529c1a2711cdc52 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Fri, 23 Mar 2018 14:17:20 -0700 Subject: [PATCH 10/21] spacing adjustment --- .../jdbc/exception/ExceptionTest.java | 47 +++++++++---------- 1 file changed, 23 insertions(+), 24 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 4c78554604..bfeba9522d 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java @@ -107,30 +107,29 @@ public void testResultSetErrorSearch() throws Exception { 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);"; - + "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;"; + + "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(); @@ -148,4 +147,4 @@ public void testResultSetErrorSearch() throws Exception { assertTrue(e.getMessage().contains("Error occured during the insert:"), "Unexpected Error Message:" + e.getMessage()); } } -} \ No newline at end of file +} From 3f8b7f64b130f92723abfb4bf5acf1c0359631fa Mon Sep 17 00:00:00 2001 From: rene-ye Date: Mon, 26 Mar 2018 10:09:50 -0700 Subject: [PATCH 11/21] Edited test drop procedures Changed IF EXISTS DROP commands to be compatible with sql server 2008 --- .../sqlserver/jdbc/exception/ExceptionTest.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 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 bfeba9522d..8c6ba90888 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java @@ -104,8 +104,17 @@ 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 dropTable_sql = "IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES " + + "WHERE TABLE_NAME = 'TEST659')) " + + "BEGIN " + + "DROP TABLE TEST659 " + + "END"; + String dropProc_sql = "IF EXISTS (SELECT * FROM sysobjects " + + "WHERE id = object_id(N'[dbo].proc_insert_masse_TEST') " + + "AND OBJECTPROPERTY(id, N'IsProcedure') = 1 ) " + + "BEGIN " + + "DROP PROCEDURE [dbo].proc_insert_masse_TEST " + + "END"; String createTable_sql = "CREATE TABLE TEST659 (ID INT IDENTITY NOT NULL," + "FIELD1 VARCHAR (255) NOT NULL," + "FIELD2 VARCHAR (255) NOT NULL);"; @@ -144,7 +153,7 @@ public void testResultSetErrorSearch() throws Exception { rs.next(); fail("No exceptions caught."); } catch (SQLException e) { - assertTrue(e.getMessage().contains("Error occured during the insert:"), "Unexpected Error Message:" + e.getMessage()); + assertTrue(e.getMessage().contains("Error occured during the insert:"), "Unexpected Error Message: " + e.getMessage()); } } } From 49a51238b1b16941a4358ca0876932b0a0deec4c Mon Sep 17 00:00:00 2001 From: rene-ye Date: Mon, 26 Mar 2018 10:13:41 -0700 Subject: [PATCH 12/21] github spacing misalignment fixes --- .../jdbc/exception/ExceptionTest.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 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 8c6ba90888..1bdf3f5205 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java @@ -105,16 +105,16 @@ public void testResultSetErrorSearch() throws Exception { ds.setURL(connectionString); String dropTable_sql = "IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES " + - "WHERE TABLE_NAME = 'TEST659')) " + - "BEGIN " + - "DROP TABLE TEST659 " + - "END"; + "WHERE TABLE_NAME = 'TEST659')) " + + "BEGIN " + + "DROP TABLE TEST659 " + + "END"; String dropProc_sql = "IF EXISTS (SELECT * FROM sysobjects " + - "WHERE id = object_id(N'[dbo].proc_insert_masse_TEST') " + - "AND OBJECTPROPERTY(id, N'IsProcedure') = 1 ) " + - "BEGIN " + - "DROP PROCEDURE [dbo].proc_insert_masse_TEST " + - "END"; + "WHERE id = object_id(N'[dbo].proc_insert_masse_TEST') " + + "AND OBJECTPROPERTY(id, N'IsProcedure') = 1 ) " + + "BEGIN " + + "DROP PROCEDURE [dbo].proc_insert_masse_TEST " + + "END"; String createTable_sql = "CREATE TABLE TEST659 (ID INT IDENTITY NOT NULL," + "FIELD1 VARCHAR (255) NOT NULL," + "FIELD2 VARCHAR (255) NOT NULL);"; From df87d27a1e61feec9231636a6a0a022d40392393 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Mon, 26 Mar 2018 12:40:41 -0700 Subject: [PATCH 13/21] Changed test condition now only runs on compatible database or higher --- .../jdbc/exception/ExceptionTest.java | 43 ++++++++----------- 1 file changed, 19 insertions(+), 24 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 1bdf3f5205..9b7e0d269c 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java @@ -13,6 +13,7 @@ import java.io.UnsupportedEncodingException; import java.net.SocketTimeoutException; import java.sql.Connection; +import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; @@ -104,17 +105,8 @@ public void testResultSetErrorSearch() throws Exception { SQLServerDataSource ds = new SQLServerDataSource(); ds.setURL(connectionString); - String dropTable_sql = "IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES " + - "WHERE TABLE_NAME = 'TEST659')) " + - "BEGIN " + - "DROP TABLE TEST659 " + - "END"; - String dropProc_sql = "IF EXISTS (SELECT * FROM sysobjects " + - "WHERE id = object_id(N'[dbo].proc_insert_masse_TEST') " + - "AND OBJECTPROPERTY(id, N'IsProcedure') = 1 ) " + - "BEGIN " + - "DROP PROCEDURE [dbo].proc_insert_masse_TEST " + - "END"; + 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);"; @@ -142,18 +134,21 @@ public void testResultSetErrorSearch() throws Exception { String proc_sql = "EXECUTE [dbo].proc_insert_masse_TEST N'[{\"FIELD1\" : \"TEST\"}]';"; Connection conn = ds.getConnection(); - 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()); - } + 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 6dd712a6847cba4b687cd8f6ade8f84f7c1abc45 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Tue, 27 Mar 2018 10:29:57 -0700 Subject: [PATCH 14/21] Removed error check Removed a previous implementation in favor of one that changes the TDS parser --- .../sqlserver/jdbc/SQLServerResultSet.java | 55 ++++--------------- 1 file changed, 10 insertions(+), 45 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index ad7c6a385d..43ced77d7a 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -1030,12 +1030,6 @@ public boolean next() throws SQLServerException { return true; } } - - // We have no rows, if an error occurred, there should be 1 column and we need to throw an exception - if (rowCount == BEFORE_FIRST_ROW && columns.length == 1) { - lookForErrors(); - } - // Otherwise, we have reached the end of the result set if (UNKNOWN_ROW_COUNT == rowCount) rowCount = currentRow; @@ -1045,42 +1039,6 @@ public boolean next() throws SQLServerException { return false; } - /* - * A function that looks for an error message in the current TDS packet, and throws an SQLServerException if found. - * - * @throw SQLServerException - * if the packet contains an error message - * @return - */ - private void lookForErrors() throws SQLServerException { - int packetSize = tdsReader.availableCurrentPacket(); - if (packetSize > 0) { - // There's a response available, but we have no rows. Take a look through the packet. - byte[] byteBuffer = new byte[packetSize]; - tdsReader.readBytes(byteBuffer, 0, packetSize); - for (int i = 0; i < byteBuffer.length; i++) { - int token = byteBuffer[i] & 0xFF; - // Parse the packet, look for a TDS 'AA' token indicating an error. - if (token == TDS.TDS_ERR) { - try { - int messageOffset = i + ERROR_EXCESS_INFO; - // Get the message length, represented as 1 byte in front of our message - // This byte is unsigned so we convert with '& 0xFF' - int messageLength = byteBuffer[messageOffset - 1] & 0xFF; - // The fields are of varying byte sizes, this causes problems with String[byte[], "UTF-16") - // Remove as many values from the front as possible to avoid any possible inconsistencies - // Also make sure not to parse anything after the message, 2 bytes for every UTF-16 character - byte[] errB = Arrays.copyOfRange(byteBuffer, messageOffset, messageOffset + (messageLength*2)); - String errMsg = new String(errB, "UTF-16"); - throw new SQLServerException(errMsg, SQLState.DATA_EXCEPTION_NOT_SPECIFIC, DriverError.NOT_SET, null); - } catch (UnsupportedEncodingException e) { - throw new SQLServerException(e.getMessage(), SQLState.DATA_EXCEPTION_NOT_SPECIFIC, DriverError.NOT_SET, e); - } - } - } - } - } - public boolean wasNull() throws SQLServerException { loggerExternal.entering(getClassNameLogging(), "wasNull"); checkClosed(); @@ -6380,9 +6338,16 @@ boolean onNBCRow(TDSReader tdsReader) throws SQLServerException { boolean onDone(TDSReader tdsReader) throws SQLServerException { ensureStartMark(); - // Consume the done token - StreamDone doneToken = new StreamDone(); - doneToken.setFromTDS(tdsReader); + // Consume the done token if the message is final (0x01) or there is no error (0x02) + int packetType = tdsReader.peekTokenType(); + if (TDS.TDS_DONEINPROC == packetType) { + short status = tdsReader.peekStatusFlag(); + if ((status & 0x001) != 0 || (status & 0x002) != 0) { + StreamDone doneToken = new StreamDone(); + doneToken.setFromTDS(tdsReader); + return true; + } + } // 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 From d8691bf936e74417421baeee161ec22ebc3dc805 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Tue, 27 Mar 2018 16:26:03 -0700 Subject: [PATCH 15/21] tdsreader change --- .../sqlserver/jdbc/SQLServerResultSet.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index 43ced77d7a..e75e9ef520 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -6338,14 +6338,19 @@ boolean onNBCRow(TDSReader tdsReader) throws SQLServerException { boolean onDone(TDSReader tdsReader) throws SQLServerException { ensureStartMark(); - // Consume the done token if the message is final (0x01) or there is no error (0x02) + int token = tdsReader.peekTokenType(); + StreamDone doneToken = new StreamDone(); + doneToken.setFromTDS(tdsReader); + int packetType = tdsReader.peekTokenType(); - if (TDS.TDS_DONEINPROC == packetType) { - short status = tdsReader.peekStatusFlag(); - if ((status & 0x001) != 0 || (status & 0x002) != 0) { - StreamDone doneToken = new StreamDone(); - doneToken.setFromTDS(tdsReader); - return true; + if (-1 != packetType && TDS.TDS_DONEINPROC == token) { + switch (packetType) + { + case TDS.TDS_ENV_CHG: + case TDS.TDS_ERR: + return true; + default: + break; } } From 3d7634c953e70bdf26a114c1142540e85e76504a Mon Sep 17 00:00:00 2001 From: rene-ye Date: Tue, 27 Mar 2018 16:40:19 -0700 Subject: [PATCH 16/21] removing test for now --- .../com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 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 9b7e0d269c..67c61b013b 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java @@ -100,7 +100,7 @@ private void createWaitForDelayPreocedure(SQLServerConnection conn) throws SQLEx conn.createStatement().execute(sql); } - @Test + /*@Test public void testResultSetErrorSearch() throws Exception { SQLServerDataSource ds = new SQLServerDataSource(); ds.setURL(connectionString); @@ -150,5 +150,5 @@ public void testResultSetErrorSearch() throws Exception { assertTrue(e.getMessage().contains("Error occured during the insert:"), "Unexpected Error Message: " + e.getMessage()); } } - } + }*/ } From 63783f78947528e3bcdd34bebe0c9142ee2d8a43 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Wed, 28 Mar 2018 10:10:10 -0700 Subject: [PATCH 17/21] enabled tests --- .../com/microsoft/sqlserver/jdbc/SQLServerResultSet.java | 7 ++----- .../microsoft/sqlserver/jdbc/exception/ExceptionTest.java | 5 ++--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index e75e9ef520..a232c122f5 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -12,7 +12,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.Reader; -import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.sql.Array; import java.sql.Blob; @@ -174,9 +173,6 @@ final void setDeletedCurrentRow(boolean rowDeleted) { static final int UNKNOWN_ROW_COUNT = -3; private int rowCount; - //The number of bytes to skip from a TDS token to reach the message. Used when parsing a TDS packet. - static final int ERROR_EXCESS_INFO = 10; - /** The current row's column values */ private final Column[] columns; @@ -1030,6 +1026,7 @@ public boolean next() throws SQLServerException { return true; } } + // Otherwise, we have reached the end of the result set if (UNKNOWN_ROW_COUNT == rowCount) rowCount = currentRow; @@ -1038,7 +1035,7 @@ public boolean next() throws SQLServerException { loggerExternal.exiting(getClassNameLogging(), "next", false); return false; } - + public boolean wasNull() throws SQLServerException { loggerExternal.entering(getClassNameLogging(), "wasNull"); checkClosed(); 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 67c61b013b..69245d7edf 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/exception/ExceptionTest.java @@ -13,7 +13,6 @@ import java.io.UnsupportedEncodingException; import java.net.SocketTimeoutException; import java.sql.Connection; -import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; @@ -100,7 +99,7 @@ private void createWaitForDelayPreocedure(SQLServerConnection conn) throws SQLEx conn.createStatement().execute(sql); } - /*@Test + @Test public void testResultSetErrorSearch() throws Exception { SQLServerDataSource ds = new SQLServerDataSource(); ds.setURL(connectionString); @@ -150,5 +149,5 @@ public void testResultSetErrorSearch() throws Exception { assertTrue(e.getMessage().contains("Error occured during the insert:"), "Unexpected Error Message: " + e.getMessage()); } } - }*/ + } } From 42259e0d5610b24a6a684745152dbe857222756b Mon Sep 17 00:00:00 2001 From: rene-ye Date: Wed, 28 Mar 2018 10:12:39 -0700 Subject: [PATCH 18/21] github spacing fix --- .../sqlserver/jdbc/SQLServerResultSet.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index a232c122f5..d8a6c2085f 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -172,7 +172,7 @@ final void setDeletedCurrentRow(boolean rowDeleted) { */ static final int UNKNOWN_ROW_COUNT = -3; private int rowCount; - + /** The current row's column values */ private final Column[] columns; @@ -1026,7 +1026,7 @@ public boolean next() throws SQLServerException { return true; } } - + // Otherwise, we have reached the end of the result set if (UNKNOWN_ROW_COUNT == rowCount) rowCount = currentRow; @@ -6336,18 +6336,17 @@ boolean onDone(TDSReader tdsReader) throws SQLServerException { ensureStartMark(); int token = tdsReader.peekTokenType(); - StreamDone doneToken = new StreamDone(); - doneToken.setFromTDS(tdsReader); + 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; + switch (packetType) { + case TDS.TDS_ENV_CHG: + case TDS.TDS_ERR: + return true; + default: + break; } } From 96660f7735afbc71b8183d7cffb61125a46d2e24 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Wed, 28 Mar 2018 10:14:09 -0700 Subject: [PATCH 19/21] removed array import --- .../java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index d8a6c2085f..31b8222667 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -13,7 +13,6 @@ import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; -import java.sql.Array; import java.sql.Blob; import java.sql.Clob; import java.sql.NClob; From 255e96ec447d3771e44c2f616bdca850bf018d56 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Wed, 28 Mar 2018 10:15:18 -0700 Subject: [PATCH 20/21] removed "arrays" instead of "array" --- .../java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index 31b8222667..4f4be53e54 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -13,6 +13,7 @@ import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; +import java.sql.Array; import java.sql.Blob; import java.sql.Clob; import java.sql.NClob; @@ -25,7 +26,6 @@ import java.sql.SQLWarning; import java.sql.SQLXML; import java.text.MessageFormat; -import java.util.Arrays; import java.util.Calendar; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; From 4f9c8c36528e27ef28a2c80e95e3a6b2a050b526 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Tue, 3 Apr 2018 11:49:23 -0700 Subject: [PATCH 21/21] spacing changes --- .../sqlserver/jdbc/SQLServerResultSet.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index 4f4be53e54..0a81edf900 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -6335,17 +6335,17 @@ boolean onDone(TDSReader tdsReader) throws SQLServerException { ensureStartMark(); int token = tdsReader.peekTokenType(); - StreamDone doneToken = new StreamDone(); - doneToken.setFromTDS(tdsReader); + 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; + case TDS.TDS_ENV_CHG: + case TDS.TDS_ERR: + return true; + default: + break; } }