Skip to content

Commit

Permalink
Bacporting Fix | Default UTF8 collation conflict (#1910)
Browse files Browse the repository at this point in the history
[3.1.2] Backport: Fix | Default UTF8 collation conflict #1910
  • Loading branch information
Kaur-Parminder authored Jan 31, 2023
1 parent 7f078be commit 523a1ee
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3063,20 +3063,13 @@ private bool TryProcessEnvChange(int tokenLength, TdsParserStateObject stateObj,
_defaultCollation = env.newCollation;
_defaultLCID = env.newCollation.LCID;

int newCodePage = GetCodePage(env.newCollation, stateObj);

if ((env.newCollation.info & TdsEnums.UTF8_IN_TDSCOLLATION) == TdsEnums.UTF8_IN_TDSCOLLATION)
{ // UTF8 collation
_defaultEncoding = Encoding.UTF8;

if (newCodePage != _defaultCodePage)
{
_defaultCodePage = newCodePage;
}
}
else
{

int newCodePage = GetCodePage(env.newCollation, stateObj);
if (newCodePage != _defaultCodePage)
{
_defaultCodePage = newCodePage;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Text;
using System;
using Xunit;

namespace Microsoft.Data.SqlClient.ManualTesting.Tests
Expand Down Expand Up @@ -29,6 +31,64 @@ public static void CheckSupportUtf8ConnectionProperty()
}
}

// TODO: Write tests using UTF8 collations
// skip creating database on Azure
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer), nameof(DataTestUtility.IsNotAzureSynapse))]
public static void UTF8databaseTest()
{
const string letters = @"!\#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f€\u0081‚ƒ„…†‡ˆ‰Š‹Œ\u008dŽ\u008f\u0090‘’“”•–—˜™š›œ\u009džŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ";
string dbName = DataTestUtility.GetUniqueNameForSqlServer("UTF8databaseTest", false);
string tblName = "Table1";

SqlConnectionStringBuilder builder = new(DataTestUtility.TCPConnectionString);
builder.InitialCatalog = "master";

using SqlConnection cn = new(builder.ConnectionString);
cn.Open();

try
{
PrepareDatabaseUTF8(cn, dbName, tblName, letters);

builder.InitialCatalog = dbName;
using SqlConnection cnnTest = new(builder.ConnectionString);
// creating a databse is a time consumer action and could be retried.
SqlRetryLogicOption retryOption = new() { NumberOfTries = 3, DeltaTime = TimeSpan.FromMilliseconds(200) };
cnnTest.RetryLogicProvider = SqlConfigurableRetryFactory.CreateIncrementalRetryProvider(retryOption);
cnnTest.Open();

using SqlCommand cmd = cnnTest.CreateCommand();
cmd.CommandText = $"SELECT * FROM {tblName}";

using SqlDataReader reader = cmd.ExecuteReader();

Assert.True(reader.Read(), "The test table should have a row!");
object[] data = new object[1];
reader.GetSqlValues(data);
Assert.Equal(letters, data[0].ToString());
reader.Close();
cnnTest.Close();
}
finally
{
DataTestUtility.DropDatabase(cn, dbName);
}
}

private static void PrepareDatabaseUTF8(SqlConnection cnn, string dbName, string tblName, string letters)
{
StringBuilder sb = new();

using SqlCommand cmd = cnn.CreateCommand();

cmd.CommandText = $"CREATE DATABASE [{dbName}] COLLATE Latin1_General_100_CI_AS_SC_UTF8;";
cmd.ExecuteNonQuery();

sb.AppendLine($"CREATE TABLE [{dbName}].dbo.[{tblName}] (col VARCHAR(7633) COLLATE Latin1_General_100_CI_AS_SC);");
sb.AppendLine($"INSERT INTO [{dbName}].dbo.[{tblName}] VALUES (@letters);");

cmd.Parameters.Add(new SqlParameter("letters", letters));
cmd.CommandText = sb.ToString();
cmd.ExecuteNonQuery();
}
}
}

0 comments on commit 523a1ee

Please sign in to comment.