diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index eedcf86f8f..87d4999727 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -4268,6 +4268,9 @@ internal int GetCodePage(SqlCollation collation, TdsParserStateObject stateObj) { } break; + case 0x43f: + codePage = 1251; // Kazakh code page based on SQL Server + break; default: break; } diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs index 692d3ef85c..930deee878 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -4730,6 +4730,9 @@ internal int GetCodePage(SqlCollation collation, TdsParserStateObject stateObj) ADP.TraceExceptionWithoutRethrow(e); } break; + case 0x43f: + codePage = 1251; // Kazakh code page based on SQL Server + break; default: break; } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderTest.cs index dca2c07362..b7787b5855 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/DataReaderTest/DataReaderTest.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Data; using System.Text; +using System.Threading; using Xunit; namespace Microsoft.Data.SqlClient.ManualTesting.Tests @@ -145,6 +146,60 @@ public static void CheckSparseColumnBit() } } + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer))] + public static void CollatedDataReaderTest() + { + var databaseName = DataTestUtility.GetUniqueName("DB"); + // Remove square brackets + var dbName = databaseName.Substring(1, databaseName.Length - 2); + + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(DataTestUtility.TCPConnectionString) + { + InitialCatalog = dbName, + Pooling = false + }; + + using (SqlConnection con = new SqlConnection(DataTestUtility.TCPConnectionString)) + using (SqlCommand cmd = con.CreateCommand()) + { + try + { + con.Open(); + + // Create collated database + cmd.CommandText = $"CREATE DATABASE {databaseName} COLLATE KAZAKH_90_CI_AI"; + cmd.ExecuteNonQuery(); + + //Create connection without pooling in order to delete database later. + using (SqlConnection dbCon = new SqlConnection(builder.ConnectionString)) + using (SqlCommand dbCmd = dbCon.CreateCommand()) + { + var data = "TestData"; + + dbCon.Open(); + dbCmd.CommandText = $"SELECT '{data}'"; + using (SqlDataReader reader = dbCmd.ExecuteReader()) + { + reader.Read(); + Assert.Equal(data, reader.GetString(0)); + } + } + + // Let connection close safely before dropping database for slow servers. + Thread.Sleep(500); + } + catch (SqlException e) + { + Assert.True(false, $"Unexpected Exception occurred: {e.Message}"); + } + finally + { + cmd.CommandText = $"DROP DATABASE {databaseName}"; + cmd.ExecuteNonQuery(); + } + } + } + private static bool IsColumnBitSet(SqlConnection con, string selectQuery, int indexOfColumnSet) { bool columnSetPresent = false;