Skip to content

Commit 710a44d

Browse files
authored
Prep for release and add App Compat switch for the recent breaking change (Azure#47751)
1 parent 63a37cb commit 710a44d

File tree

6 files changed

+49
-11
lines changed

6 files changed

+49
-11
lines changed

sdk/tables/Azure.Data.Tables/CHANGELOG.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
# Release History
22

3-
## 12.10.0-beta.1 (Unreleased)
4-
5-
### Features Added
3+
## 12.10.0 (2025-01-14)
64

75
### Breaking Changes
86

9-
- Calling `TableClient.Query`, `TableClient.QueryAsync`, or `TableClient.CreateQueryFilter` with a filter expression that uses `string.Equals` or `string.Compare` with a `StringComparison` parameter will now throw an exception. This is because the Azure Table service does not support these methods in query filters. Previously the `StringComparison` argument was silently ignored, which can lead to subtle bugs in client code.
7+
- Calling `TableClient.Query`, `TableClient.QueryAsync`, or `TableClient.CreateQueryFilter` with a filter expression that uses `string.Equals` or `string.Compare` with a `StringComparison` parameter will now throw an exception. This is because the Azure Table service does not support these methods in query filters. Previously the `StringComparison` argument was silently ignored, which can lead to subtle bugs in client code. The new behavior can be overridden by either setting an AppContext switch named "Azure.Data.Tables.DisableThrowOnStringComparisonFilter" to `true` or by setting the environment variable "AZURE_DATA_TABLES_DISABLE_THROWONSTRINGCOMPARISONFILTER" to "true". Note: AppContext switches can also be configured via configuration like below:
8+
9+
```xml
10+
<ItemGroup>
11+
<RuntimeHostConfigurationOption Include="Azure.Data.Tables.DisableThrowOnStringComparisonFilter" Value="true" />
12+
</ItemGroup>
13+
```
1014

11-
### Bugs Fixed
1215

1316
### Other Changes
1417
- Improved the performance of `TableServiceClient.GetTableClient()`

sdk/tables/Azure.Data.Tables/src/Azure.Data.Tables.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<PropertyGroup>
33
<Description>This client library enables working with the Microsoft Azure Table service</Description>
44
<AssemblyTitle>Microsoft Azure.Data.Tables client library</AssemblyTitle>
5-
<Version>12.10.0-beta.1</Version>
5+
<Version>12.10.0</Version>
66
<!--The ApiCompatVersion is managed automatically and should not generally be modified manually.-->
77
<ApiCompatVersion>12.9.1</ApiCompatVersion>
88
<DefineConstants>TableSDK;$(DefineConstants)</DefineConstants>

sdk/tables/Azure.Data.Tables/src/Queryable/ExpressionNormalizer.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ internal Expression VisitMethodCallNoRewrite(MethodCallExpression call)
162162

163163
if (visited.Method.IsStatic && visited.Method.Name == "Equals" && visited.Arguments.Count > 1)
164164
{
165-
if (visited.Arguments.Count > 2)
165+
if (visited.Arguments.Count > 2 && !TablesCompatSwitches.DisableThrowOnStringComparisonFilter)
166166
{
167167
throw new NotSupportedException("string.Equals method with more than two arguments is not supported.");
168168
}
@@ -171,7 +171,7 @@ internal Expression VisitMethodCallNoRewrite(MethodCallExpression call)
171171

172172
if (!visited.Method.IsStatic && visited.Method.Name == "Equals" && visited.Arguments.Count > 0)
173173
{
174-
if (visited.Arguments.Count > 1)
174+
if (visited.Arguments.Count > 1 && !TablesCompatSwitches.DisableThrowOnStringComparisonFilter)
175175
{
176176
throw new NotSupportedException("Equals method with more than two arguments is not supported.");
177177
}
@@ -190,7 +190,7 @@ internal Expression VisitMethodCallNoRewrite(MethodCallExpression call)
190190

191191
if (visited.Method.IsStatic && visited.Method.Name == "Compare" && visited.Arguments.Count > 1 && visited.Method.ReturnType == typeof(int))
192192
{
193-
if (visited.Arguments.Count > 2)
193+
if (visited.Arguments.Count > 2 && !TablesCompatSwitches.DisableThrowOnStringComparisonFilter)
194194
{
195195
throw new NotSupportedException("string.Compare method with more than two arguments is not supported.");
196196
}

sdk/tables/Azure.Data.Tables/src/TableConstants.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ internal static class CompatSwitches
1717
public const string DisableEscapeSingleQuotesOnGetEntityEnvVar = "AZURE_DATA_TABLES_DISABLE_ESCAPESINGLEQUOTESONGETENTITY";
1818
public const string DisableEscapeSingleQuotesOnDeleteEntitySwitchName = "Azure.Data.Tables.DisableEscapeSingleQuotesOnDeleteEntity";
1919
public const string DisableEscapeSingleQuotesOnDeleteEntityEnvVar = "AZURE_DATA_TABLES_DISABLE_ESCAPESINGLEQUOTESONDELETEENTITY";
20+
public const string DisableThrowOnStringComparisonFilterSwitchName = "Azure.Data.Tables.DisableThrowOnStringComparisonFilter";
21+
public const string DisableThrowOnStringComparisonFilterEnvVar = "AZURE_DATA_TABLES_DISABLE_THROWONSTRINGCOMPARISONFILTER";
2022
}
2123

2224
internal static class HeaderNames

sdk/tables/Azure.Data.Tables/src/TablesCompatSwitches.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,10 @@ public static bool DisableEscapeSingleQuotesOnDeleteEntity
1616
=> AppContextSwitchHelper.GetConfigValue(
1717
TableConstants.CompatSwitches.DisableEscapeSingleQuotesOnDeleteEntitySwitchName,
1818
TableConstants.CompatSwitches.DisableEscapeSingleQuotesOnDeleteEntityEnvVar);
19+
20+
public static bool DisableThrowOnStringComparisonFilter
21+
=> AppContextSwitchHelper.GetConfigValue(
22+
TableConstants.CompatSwitches.DisableThrowOnStringComparisonFilterSwitchName,
23+
TableConstants.CompatSwitches.DisableThrowOnStringComparisonFilterEnvVar);
1924
}
2025
}

sdk/tables/Azure.Data.Tables/tests/TableClientQueryExpressionTests.cs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Linq;
66
using System.Linq.Expressions;
77
using System.Xml;
8+
using Azure.Core.TestFramework;
89
using Azure.Data.Tables.Models;
910
using NUnit.Framework;
1011
using static Azure.Data.Tables.Tests.TableServiceLiveTestsBase;
@@ -176,7 +177,7 @@ public class TableClientQueryExpressionTests
176177
new object[] { $"PartitionKey eq '{Partition}'", s_tableEntExpEquals },
177178
};
178179

179-
public static object[] UnSupportedTableItemExpressionTestCases =
180+
public static object[] UnsupportedTableItemExpressionTestCases =
180181
{
181182
new object[] { s_TEequalsUnsupported },
182183
new object[] { s_TEequalsStaticUnsupported },
@@ -211,11 +212,38 @@ public void TestDictionaryTableEntityFilterExpressions(string expectedFilter, Ex
211212
Assert.That(filter, Is.EqualTo(expectedFilter));
212213
}
213214

214-
[TestCaseSource(nameof(UnSupportedTableItemExpressionTestCases))]
215+
[TestCaseSource(nameof(UnsupportedTableItemExpressionTestCases))]
215216
[Test]
217+
[NonParallelizable]
216218
public void TestTableItemFilterExpressionsUnsupported(Expression<Func<TableEntity, bool>> expression)
217219
{
218220
Assert.Throws<NotSupportedException>(() => TableClient.CreateQueryFilter(expression));
219221
}
222+
223+
[TestCaseSource(nameof(UnsupportedTableItemExpressionTestCases))]
224+
[Test]
225+
[NonParallelizable]
226+
public void TestTableItemFilterExpressionsUnsupportedDoesNotThrowWithCompatSwitch(Expression<Func<TableEntity, bool>> expression)
227+
{
228+
if (expression == s_TEequalsStaticUnsupported)
229+
{
230+
Assert.Ignore("Ignore this expression because it was never supported.");
231+
}
232+
using var ctx = new TestAppContextSwitch(TableConstants.CompatSwitches.DisableThrowOnStringComparisonFilterSwitchName, true.ToString());
233+
TableClient.CreateQueryFilter(expression);
234+
}
235+
236+
[TestCaseSource(nameof(UnsupportedTableItemExpressionTestCases))]
237+
[Test]
238+
[NonParallelizable]
239+
public void TestTableItemFilterExpressionsUnsupportedDoesNotThrowWithCompatSwitchEnv(Expression<Func<TableEntity, bool>> expression)
240+
{
241+
if (expression == s_TEequalsStaticUnsupported)
242+
{
243+
Assert.Ignore("Ignore this expression because it was never supported.");
244+
}
245+
using var env = new TestEnvVar(TableConstants.CompatSwitches.DisableThrowOnStringComparisonFilterEnvVar, true.ToString());
246+
TableClient.CreateQueryFilter(expression);
247+
}
220248
}
221249
}

0 commit comments

Comments
 (0)