From 9c8e75401eeb03817c2222d17e5b8913ef087e02 Mon Sep 17 00:00:00 2001 From: Erik Ejlskov Jensen Date: Tue, 20 May 2025 15:03:02 +0200 Subject: [PATCH 1/4] avoid some allocations when opening a connection fixes #3363 --- .../src/Microsoft/Data/Common/AdapterUtil.cs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs index bf69c0346d..a60ccc329a 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs @@ -764,7 +764,7 @@ internal static Version GetAssemblyVersion() internal static bool IsAzureSynapseOnDemandEndpoint(string dataSource) { - return IsEndpoint(dataSource, ONDEMAND_PREFIX) + return IsEndpoint(dataSource, s_azureSqlServerOnDemandEndpoints) || dataSource.Contains(AZURE_SYNAPSE) || dataSource.Contains(FABRIC_DATAWAREHOUSE) || dataSource.Contains(PBI_DATAWAREHOUSE) @@ -777,14 +777,20 @@ internal static bool IsAzureSynapseOnDemandEndpoint(string dataSource) AZURE_SQL_USGOV, AZURE_SQL_CHINA, AZURE_SQL_FABRIC }; + + internal static readonly string[] s_azureSqlServerOnDemandEndpoints = { ONDEMAND_PREFIX + AZURE_SQL, + ONDEMAND_PREFIX + AZURE_SQL_GERMANY, + ONDEMAND_PREFIX + AZURE_SQL_USGOV, + ONDEMAND_PREFIX + AZURE_SQL_CHINA, + ONDEMAND_PREFIX + AZURE_SQL_FABRIC }; internal static bool IsAzureSqlServerEndpoint(string dataSource) { - return IsEndpoint(dataSource, null); + return IsEndpoint(dataSource, s_azureSqlServerEndpoints); } // This method assumes dataSource parameter is in TCP connection string format. - private static bool IsEndpoint(string dataSource, string prefix) + private static bool IsEndpoint(string dataSource, string[] endpoints) { int length = dataSource.Length; // remove server port @@ -805,8 +811,6 @@ private static bool IsEndpoint(string dataSource, string prefix) foundIndex = -1; } - - if (foundIndex > 0) { length = foundIndex; @@ -819,9 +823,9 @@ private static bool IsEndpoint(string dataSource, string prefix) } // check if servername ends with any endpoints - for (int index = 0; index < s_azureSqlServerEndpoints.Length; index++) + for (int index = 0; index < endpoints.Length; index++) { - string endpoint = string.IsNullOrEmpty(prefix) ? s_azureSqlServerEndpoints[index] : prefix + s_azureSqlServerEndpoints[index]; + string endpoint = endpoints[index]; if (length > endpoint.Length) { if (string.Compare(dataSource, length - endpoint.Length, endpoint, 0, endpoint.Length, StringComparison.OrdinalIgnoreCase) == 0) From 32afc35d278c399692e2b62e26cf7f7f2d5af92c Mon Sep 17 00:00:00 2001 From: Erik Ejlskov Jensen Date: Tue, 20 May 2025 15:24:09 +0200 Subject: [PATCH 2/4] PR feedback --- .../src/Microsoft/Data/Common/AdapterUtil.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs index a60ccc329a..bc641f8874 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs @@ -772,12 +772,23 @@ internal static bool IsAzureSynapseOnDemandEndpoint(string dataSource) || dataSource.Contains(PBI_DATAWAREHOUSE3); } + /// + /// Represents a collection of Azure SQL Server endpoint URLs for various regions and environments. + /// + /// This array includes endpoint URLs for Azure SQL in global, Germany, US Government, + /// China, and Fabric environments. These endpoints are used to identify and interact with Azure SQL services + /// in their respective regions or environments. internal static readonly string[] s_azureSqlServerEndpoints = { AZURE_SQL, AZURE_SQL_GERMANY, AZURE_SQL_USGOV, AZURE_SQL_CHINA, AZURE_SQL_FABRIC }; + /// + /// Contains endpoint strings for Azure SQL Server on-demand services. + /// Each entry is a combination of the ONDEMAND_PREFIX and a specific Azure SQL endpoint string. + /// Example format: "ondemand.database.windows.net". + /// internal static readonly string[] s_azureSqlServerOnDemandEndpoints = { ONDEMAND_PREFIX + AZURE_SQL, ONDEMAND_PREFIX + AZURE_SQL_GERMANY, ONDEMAND_PREFIX + AZURE_SQL_USGOV, @@ -823,9 +834,8 @@ private static bool IsEndpoint(string dataSource, string[] endpoints) } // check if servername ends with any endpoints - for (int index = 0; index < endpoints.Length; index++) + foreach (var endpoint in endpoints) { - string endpoint = endpoints[index]; if (length > endpoint.Length) { if (string.Compare(dataSource, length - endpoint.Length, endpoint, 0, endpoint.Length, StringComparison.OrdinalIgnoreCase) == 0) From ecfca89741fb17e1db024010633d11499abe9281 Mon Sep 17 00:00:00 2001 From: Erik Ejlskov Jensen Date: Tue, 20 May 2025 18:39:12 +0200 Subject: [PATCH 3/4] PR feedback --- .../src/Microsoft/Data/Common/AdapterUtil.cs | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs index bc641f8874..bc1ae27c06 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs @@ -24,6 +24,8 @@ using Microsoft.Identity.Client; using Microsoft.SqlServer.Server; using System.Security.Authentication; +using System.Linq; + #if NETFRAMEWORK using System.Reflection; @@ -762,16 +764,6 @@ internal static Version GetAssemblyVersion() private const string AZURE_SQL_CHINA = ".database.chinacloudapi.cn"; private const string AZURE_SQL_FABRIC = ".database.fabric.microsoft.com"; - internal static bool IsAzureSynapseOnDemandEndpoint(string dataSource) - { - return IsEndpoint(dataSource, s_azureSqlServerOnDemandEndpoints) - || dataSource.Contains(AZURE_SYNAPSE) - || dataSource.Contains(FABRIC_DATAWAREHOUSE) - || dataSource.Contains(PBI_DATAWAREHOUSE) - || dataSource.Contains(PBI_DATAWAREHOUSE2) - || dataSource.Contains(PBI_DATAWAREHOUSE3); - } - /// /// Represents a collection of Azure SQL Server endpoint URLs for various regions and environments. /// @@ -794,7 +786,25 @@ internal static bool IsAzureSynapseOnDemandEndpoint(string dataSource) ONDEMAND_PREFIX + AZURE_SQL_USGOV, ONDEMAND_PREFIX + AZURE_SQL_CHINA, ONDEMAND_PREFIX + AZURE_SQL_FABRIC }; - + /// + /// Represents a collection of endpoint identifiers for Azure Synapse and related services. + /// + /// This array contains predefined endpoint strings used to identify Azure Synapse and + /// associated services, such as Fabric Data Warehouse and Power BI Data Warehouse. + internal static readonly string[] s_azureSynapseEndpoints = { AZURE_SYNAPSE, + FABRIC_DATAWAREHOUSE, + PBI_DATAWAREHOUSE, + PBI_DATAWAREHOUSE2, + PBI_DATAWAREHOUSE3 }; + + internal static readonly string[] s_azureSynapseOnDemandEndpoints = s_azureSqlServerOnDemandEndpoints + .Concat(s_azureSynapseEndpoints) + .ToArray(); + internal static bool IsAzureSynapseOnDemandEndpoint(string dataSource) + { + return IsEndpoint(dataSource, s_azureSynapseOnDemandEndpoints); + } + internal static bool IsAzureSqlServerEndpoint(string dataSource) { return IsEndpoint(dataSource, s_azureSqlServerEndpoints); From 3953e73a127c05068d7eba56639c8900ab1e58ed Mon Sep 17 00:00:00 2001 From: Erik Ejlskov Jensen Date: Wed, 21 May 2025 08:01:56 +0200 Subject: [PATCH 4/4] Fix tests and PR feedback --- .../src/Microsoft/Data/Common/AdapterUtil.cs | 15 ++++++--------- .../tests/FunctionalTests/SqlConnectionTest.cs | 3 +++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs index bc1ae27c06..26fc98f464 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs @@ -24,8 +24,6 @@ using Microsoft.Identity.Client; using Microsoft.SqlServer.Server; using System.Security.Authentication; -using System.Linq; - #if NETFRAMEWORK using System.Reflection; @@ -791,18 +789,17 @@ internal static Version GetAssemblyVersion() /// /// This array contains predefined endpoint strings used to identify Azure Synapse and /// associated services, such as Fabric Data Warehouse and Power BI Data Warehouse. - internal static readonly string[] s_azureSynapseEndpoints = { AZURE_SYNAPSE, - FABRIC_DATAWAREHOUSE, + internal static readonly string[] s_azureSynapseEndpoints = { FABRIC_DATAWAREHOUSE, PBI_DATAWAREHOUSE, PBI_DATAWAREHOUSE2, PBI_DATAWAREHOUSE3 }; - internal static readonly string[] s_azureSynapseOnDemandEndpoints = s_azureSqlServerOnDemandEndpoints - .Concat(s_azureSynapseEndpoints) - .ToArray(); + internal static readonly string[] s_azureSynapseOnDemandEndpoints = [.. s_azureSqlServerOnDemandEndpoints, .. s_azureSynapseEndpoints]; + internal static bool IsAzureSynapseOnDemandEndpoint(string dataSource) { - return IsEndpoint(dataSource, s_azureSynapseOnDemandEndpoints); + return IsEndpoint(dataSource, s_azureSynapseOnDemandEndpoints) + || dataSource.IndexOf(AZURE_SYNAPSE, StringComparison.OrdinalIgnoreCase) >= 0; } internal static bool IsAzureSqlServerEndpoint(string dataSource) @@ -846,7 +843,7 @@ private static bool IsEndpoint(string dataSource, string[] endpoints) // check if servername ends with any endpoints foreach (var endpoint in endpoints) { - if (length > endpoint.Length) + if (length >= endpoint.Length) { if (string.Compare(dataSource, length - endpoint.Length, endpoint, 0, endpoint.Length, StringComparison.OrdinalIgnoreCase) == 0) { diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionTest.cs index d3b906c6b5..d61866f176 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionTest.cs @@ -1100,6 +1100,7 @@ public void ConnectionString_WithOnlyComma() [InlineData("myserver.database.windows.net")] [InlineData("myserver.database.cloudapi.de")] [InlineData("myserver.database.usgovcloudapi.net")] + [InlineData("myserver.DATABASE.usgovcloudapi.net")] [InlineData("myserver.database.chinacloudapi.cn")] [InlineData("myserver.database.fabric.microsoft.com")] public void ConnectionRetryForAzureDbEndpoints(string serverName) @@ -1112,8 +1113,10 @@ public void ConnectionRetryForAzureDbEndpoints(string serverName) [Theory] [InlineData("myserver-ondemand.sql.azuresynapse.net")] + [InlineData("myserver-ondemand.SQL.azuresynapse.net")] [InlineData("someserver-ondemand.database.windows.net")] [InlineData("datawarehouse.fabric.microsoft.com")] + [InlineData("datawarehouse.FABRIC.microsoft.com")] [InlineData("datawarehouse.pbidedicated.microsoft.com")] [InlineData("someserver.pbidedicated.microsoft.com")] [InlineData("someserver.pbidedicated.windows.net")]