Skip to content

Commit

Permalink
Prep for release and add App Compat switch for the recent breaking ch…
Browse files Browse the repository at this point in the history
…ange (#47751)
  • Loading branch information
christothes authored Jan 9, 2025
1 parent 63a37cb commit 710a44d
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 11 deletions.
13 changes: 8 additions & 5 deletions sdk/tables/Azure.Data.Tables/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
# Release History

## 12.10.0-beta.1 (Unreleased)

### Features Added
## 12.10.0 (2025-01-14)

### Breaking Changes

- 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.
- 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:

```xml
<ItemGroup>
<RuntimeHostConfigurationOption Include="Azure.Data.Tables.DisableThrowOnStringComparisonFilter" Value="true" />
</ItemGroup>
```

### Bugs Fixed

### Other Changes
- Improved the performance of `TableServiceClient.GetTableClient()`
Expand Down
2 changes: 1 addition & 1 deletion sdk/tables/Azure.Data.Tables/src/Azure.Data.Tables.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<Description>This client library enables working with the Microsoft Azure Table service</Description>
<AssemblyTitle>Microsoft Azure.Data.Tables client library</AssemblyTitle>
<Version>12.10.0-beta.1</Version>
<Version>12.10.0</Version>
<!--The ApiCompatVersion is managed automatically and should not generally be modified manually.-->
<ApiCompatVersion>12.9.1</ApiCompatVersion>
<DefineConstants>TableSDK;$(DefineConstants)</DefineConstants>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ internal Expression VisitMethodCallNoRewrite(MethodCallExpression call)

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

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

if (visited.Method.IsStatic && visited.Method.Name == "Compare" && visited.Arguments.Count > 1 && visited.Method.ReturnType == typeof(int))
{
if (visited.Arguments.Count > 2)
if (visited.Arguments.Count > 2 && !TablesCompatSwitches.DisableThrowOnStringComparisonFilter)
{
throw new NotSupportedException("string.Compare method with more than two arguments is not supported.");
}
Expand Down
2 changes: 2 additions & 0 deletions sdk/tables/Azure.Data.Tables/src/TableConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ internal static class CompatSwitches
public const string DisableEscapeSingleQuotesOnGetEntityEnvVar = "AZURE_DATA_TABLES_DISABLE_ESCAPESINGLEQUOTESONGETENTITY";
public const string DisableEscapeSingleQuotesOnDeleteEntitySwitchName = "Azure.Data.Tables.DisableEscapeSingleQuotesOnDeleteEntity";
public const string DisableEscapeSingleQuotesOnDeleteEntityEnvVar = "AZURE_DATA_TABLES_DISABLE_ESCAPESINGLEQUOTESONDELETEENTITY";
public const string DisableThrowOnStringComparisonFilterSwitchName = "Azure.Data.Tables.DisableThrowOnStringComparisonFilter";
public const string DisableThrowOnStringComparisonFilterEnvVar = "AZURE_DATA_TABLES_DISABLE_THROWONSTRINGCOMPARISONFILTER";
}

internal static class HeaderNames
Expand Down
5 changes: 5 additions & 0 deletions sdk/tables/Azure.Data.Tables/src/TablesCompatSwitches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,10 @@ public static bool DisableEscapeSingleQuotesOnDeleteEntity
=> AppContextSwitchHelper.GetConfigValue(
TableConstants.CompatSwitches.DisableEscapeSingleQuotesOnDeleteEntitySwitchName,
TableConstants.CompatSwitches.DisableEscapeSingleQuotesOnDeleteEntityEnvVar);

public static bool DisableThrowOnStringComparisonFilter
=> AppContextSwitchHelper.GetConfigValue(
TableConstants.CompatSwitches.DisableThrowOnStringComparisonFilterSwitchName,
TableConstants.CompatSwitches.DisableThrowOnStringComparisonFilterEnvVar);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using System.Linq.Expressions;
using System.Xml;
using Azure.Core.TestFramework;
using Azure.Data.Tables.Models;
using NUnit.Framework;
using static Azure.Data.Tables.Tests.TableServiceLiveTestsBase;
Expand Down Expand Up @@ -176,7 +177,7 @@ public class TableClientQueryExpressionTests
new object[] { $"PartitionKey eq '{Partition}'", s_tableEntExpEquals },
};

public static object[] UnSupportedTableItemExpressionTestCases =
public static object[] UnsupportedTableItemExpressionTestCases =
{
new object[] { s_TEequalsUnsupported },
new object[] { s_TEequalsStaticUnsupported },
Expand Down Expand Up @@ -211,11 +212,38 @@ public void TestDictionaryTableEntityFilterExpressions(string expectedFilter, Ex
Assert.That(filter, Is.EqualTo(expectedFilter));
}

[TestCaseSource(nameof(UnSupportedTableItemExpressionTestCases))]
[TestCaseSource(nameof(UnsupportedTableItemExpressionTestCases))]
[Test]
[NonParallelizable]
public void TestTableItemFilterExpressionsUnsupported(Expression<Func<TableEntity, bool>> expression)
{
Assert.Throws<NotSupportedException>(() => TableClient.CreateQueryFilter(expression));
}

[TestCaseSource(nameof(UnsupportedTableItemExpressionTestCases))]
[Test]
[NonParallelizable]
public void TestTableItemFilterExpressionsUnsupportedDoesNotThrowWithCompatSwitch(Expression<Func<TableEntity, bool>> expression)
{
if (expression == s_TEequalsStaticUnsupported)
{
Assert.Ignore("Ignore this expression because it was never supported.");
}
using var ctx = new TestAppContextSwitch(TableConstants.CompatSwitches.DisableThrowOnStringComparisonFilterSwitchName, true.ToString());
TableClient.CreateQueryFilter(expression);
}

[TestCaseSource(nameof(UnsupportedTableItemExpressionTestCases))]
[Test]
[NonParallelizable]
public void TestTableItemFilterExpressionsUnsupportedDoesNotThrowWithCompatSwitchEnv(Expression<Func<TableEntity, bool>> expression)
{
if (expression == s_TEequalsStaticUnsupported)
{
Assert.Ignore("Ignore this expression because it was never supported.");
}
using var env = new TestEnvVar(TableConstants.CompatSwitches.DisableThrowOnStringComparisonFilterEnvVar, true.ToString());
TableClient.CreateQueryFilter(expression);
}
}
}

0 comments on commit 710a44d

Please sign in to comment.