diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCachedBuffer.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCachedBuffer.cs index 1d756f21be..000d2647cc 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCachedBuffer.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCachedBuffer.cs @@ -7,7 +7,6 @@ using System.Data.SqlTypes; using System.Diagnostics; using System.IO; -using System.Reflection; using System.Runtime.CompilerServices; using System.Xml; using Microsoft.Data.SqlTypes; @@ -145,7 +144,5 @@ public bool IsNull return (_cachedBytes == null) ? true : false; } } - } - } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDataReader.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDataReader.cs index 16e505a33c..0c2200321e 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDataReader.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDataReader.cs @@ -4393,7 +4393,7 @@ out dataLength } else { - //Debug.Assert(false, "we have read past the column somehow, this is an error"); + Debug.Assert(false, "we have read past the column somehow, this is an error"); } } else diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj index c16f3e559c..79543bc85c 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj @@ -66,7 +66,7 @@ - + diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderStreamsTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderStreamsTest.cs index 6520c185c1..8c8b2bc1d4 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderStreamsTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderStreamsTest.cs @@ -119,6 +119,40 @@ public static async Task GetFieldValueAsync_OfTextReader(CommandBehavior behavio Assert.Equal(originalText, outputText); } + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [MemberData(nameof(GetCommandBehavioursAndIsAsync))] + public static async Task GetFieldValueAsync_Char_OfTextReader(CommandBehavior behavior, bool isExecuteAsync) + { + const int PacketSize = 512; // force minimun packet size so that the test data spans multiple packets to test sequential access spanning + string connectionString = SetConnectionStringPacketSize(DataTestUtility.TCPConnectionString, PacketSize); + string originalText = new ('c', PacketSize * 4); + string query = CreateCharDataQuery(originalText); + + string streamTypeName = null; + string outputText = null; + using (SqlConnection connection = new SqlConnection(connectionString)) + using (SqlCommand command = new SqlCommand(query, connection)) + { + connection.Open(); + using (SqlDataReader reader = await ExecuteReader(command, behavior, isExecuteAsync)) + { + if (await Read(reader, isExecuteAsync)) + { + using (TextReader textReader = await reader.GetFieldValueAsync(1)) + { + streamTypeName = textReader.GetType().Name; + outputText = await textReader.ReadToEndAsync(); + } + } + } + } + + Assert.True(behavior != CommandBehavior.SequentialAccess || streamTypeName.Contains("Sequential")); + Assert.NotNull(outputText); + Assert.Equal(originalText.Length, outputText.Length); + Assert.Equal(originalText, outputText); + } + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] [MemberData(nameof(GetCommandBehavioursAndIsAsync))] public static async void GetFieldValue_OfXmlReader(CommandBehavior behavior, bool isExecuteAsync) @@ -407,7 +441,33 @@ public static void NullStreamProperties(CommandBehavior behavior, AccessorType a } } } + } + + [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] + [MemberData(nameof(GetCommandBehaviourAndAccessorTypes))] + public static void InvalidCastExceptionStream(CommandBehavior behavior, AccessorType accessorType) + { + string query = "SELECT convert(xml,NULL) AS XmlData, convert(nvarchar(max),NULL) as TextData"; + using (SqlConnection connection = new SqlConnection(DataTestUtility.TCPConnectionString)) + using (SqlCommand command = new SqlCommand(query, connection)) + { + connection.Open(); + + using (SqlDataReader reader = command.ExecuteReader(behavior)) + { + Assert.True(reader.Read(), "It's excpected to read a row."); + + InvalidCastException ex = Assert.Throws(() => GetValue(reader, 0, accessorType)); + Assert.Contains("The GetTextReader function can only be used on columns of type Char, NChar, NText, NVarChar, Text or VarChar.", ex.Message); + + ex = Assert.Throws(() => GetValue(reader, 0, accessorType)); + Assert.Contains("The GetStream function can only be used on columns of type Binary, Image, Udt or VarBinary.", ex.Message); + + ex = Assert.Throws(() => GetValue(reader, 1, accessorType)); + Assert.Contains("The GetXmlReader function can only be used on columns of type Xml.", ex.Message); + } + } } private static async Task ExecuteReader(SqlCommand command, CommandBehavior behavior, bool isExecuteAsync) @@ -573,6 +633,15 @@ private static string CreateTextDataQuery(string originalText) return queryBuilder.ToString(); } + private static string CreateCharDataQuery(string originalText) + { + StringBuilder queryBuilder = new StringBuilder(originalText.Length + 128); + queryBuilder.Append($"SELECT 1 as DummyField, convert(char({originalText.Length}),'"); + queryBuilder.Append(originalText); + queryBuilder.Append("') AS Data"); + return queryBuilder.ToString(); + } + private static string GetXmlDocumentContents(XmlReader xmlReader) { string outputXml;