diff --git a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.csproj b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.csproj
index 006f98d86..bcc5db494 100644
--- a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.csproj
+++ b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.csproj
@@ -33,12 +33,15 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml
index 4d0e931a0..150a6d7a8 100644
--- a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml
+++ b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml
@@ -7570,6 +7570,11 @@
A value that corresponds to allowing 'All' function in $filter.
+
+
+ A value that corresponds to allowing 'MatchesPattern' function in $filter.
+
+
A value that corresponds to allowing all string related functions in $filter.
@@ -8074,7 +8079,7 @@
-
String related:
contains, endswith, startswith, length, indexof, substring, tolower, toupper, trim,
- concat e.g. ~/Customers?$filter=length(CompanyName) eq 19
+ concat, matchesPattern e.g. ~/Customers?$filter=length(CompanyName) eq 19
-
DateTime related:
@@ -9102,6 +9107,14 @@
The query binder context.
The LINQ created.
+
+
+ Binds a 'matchesPattern' function to create a LINQ .
+
+ The query node to bind.
+ The query binder context.
+ The LINQ created.
+
Binds date related functions to create a LINQ .
@@ -11577,7 +11590,7 @@
The allowed functions include the following:
- String related: contains, endswith, startswith, length, indexof, substring, tolower, toupper, trim, concat
+ String related: contains, endswith, startswith, length, indexof, substring, tolower, toupper, trim, concat, matchesPattern
e.g. ~/Customers?$filter=length(CompanyName) eq 19
diff --git a/src/Microsoft.AspNetCore.OData/Query/AllowedFunctions.cs b/src/Microsoft.AspNetCore.OData/Query/AllowedFunctions.cs
index fde630bb2..bcdca1897 100644
--- a/src/Microsoft.AspNetCore.OData/Query/AllowedFunctions.cs
+++ b/src/Microsoft.AspNetCore.OData/Query/AllowedFunctions.cs
@@ -150,10 +150,15 @@ public enum AllowedFunctions
///
All = 0x10000000,
+ ///
+ /// A value that corresponds to allowing 'MatchesPattern' function in $filter.
+ ///
+ MatchesPattern = 0x20000000,
+
///
/// A value that corresponds to allowing all string related functions in $filter.
///
- AllStringFunctions = StartsWith | EndsWith | Contains | Length | IndexOf | Concat | Substring | ToLower | ToUpper | Trim,
+ AllStringFunctions = StartsWith | EndsWith | Contains | Length | IndexOf | Concat | Substring | ToLower | ToUpper | Trim | MatchesPattern,
///
/// A value that corresponds to allowing all datetime related functions in $filter.
diff --git a/src/Microsoft.AspNetCore.OData/Query/ClrCanonicalFunctions.cs b/src/Microsoft.AspNetCore.OData/Query/ClrCanonicalFunctions.cs
index 3f44db2c7..268953a90 100644
--- a/src/Microsoft.AspNetCore.OData/Query/ClrCanonicalFunctions.cs
+++ b/src/Microsoft.AspNetCore.OData/Query/ClrCanonicalFunctions.cs
@@ -16,6 +16,7 @@
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
+using System.Text.RegularExpressions;
using Microsoft.OData.Edm;
namespace Microsoft.AspNetCore.OData.Query
@@ -36,6 +37,7 @@ internal class ClrCanonicalFunctions
internal const string ToupperFunctionName = "toupper";
internal const string TrimFunctionName = "trim";
internal const string ConcatFunctionName = "concat";
+ internal const string MatchesPatternFunctionName = "matchesPattern";
internal const string YearFunctionName = "year";
internal const string MonthFunctionName = "month";
internal const string DayFunctionName = "day";
@@ -66,6 +68,7 @@ internal class ClrCanonicalFunctions
public static readonly MethodInfo ToUpper = MethodOf(_ => _defaultString.ToUpper());
public static readonly MethodInfo Trim = MethodOf(_ => _defaultString.Trim());
public static readonly MethodInfo Concat = MethodOf(_ => String.Concat(default(string), default(string)));
+ public static readonly MethodInfo MatchesMattern = MethodOf(_ => Regex.IsMatch(default(string), default(string), default(RegexOptions)));
// math functions
public static readonly MethodInfo CeilingOfDouble = MethodOf(_ => Math.Ceiling(default(double)));
diff --git a/src/Microsoft.AspNetCore.OData/Query/EnableQueryAttribute.Config.cs b/src/Microsoft.AspNetCore.OData/Query/EnableQueryAttribute.Config.cs
index 856ce9012..8db9a7cb0 100644
--- a/src/Microsoft.AspNetCore.OData/Query/EnableQueryAttribute.Config.cs
+++ b/src/Microsoft.AspNetCore.OData/Query/EnableQueryAttribute.Config.cs
@@ -150,7 +150,7 @@ public AllowedQueryOptions AllowedQueryOptions
/// -
/// String related:
/// contains, endswith, startswith, length, indexof, substring, tolower, toupper, trim,
- /// concat e.g. ~/Customers?$filter=length(CompanyName) eq 19
+ /// concat, matchesPattern e.g. ~/Customers?$filter=length(CompanyName) eq 19
///
/// -
/// DateTime related:
diff --git a/src/Microsoft.AspNetCore.OData/Query/Expressions/ExpressionBinderBase.cs b/src/Microsoft.AspNetCore.OData/Query/Expressions/ExpressionBinderBase.cs
index 0985ff1cb..c4d4196bb 100644
--- a/src/Microsoft.AspNetCore.OData/Query/Expressions/ExpressionBinderBase.cs
+++ b/src/Microsoft.AspNetCore.OData/Query/Expressions/ExpressionBinderBase.cs
@@ -13,6 +13,7 @@
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
+using System.Text.RegularExpressions;
using System.Xml.Linq;
using Microsoft.AspNetCore.OData.Abstracts;
using Microsoft.AspNetCore.OData.Common;
@@ -199,6 +200,9 @@ public virtual Expression BindSingleValueFunctionCallNode(SingleValueFunctionCal
case ClrCanonicalFunctions.ConcatFunctionName:
return BindConcat(node);
+ case ClrCanonicalFunctions.MatchesPatternFunctionName:
+ return BindMatchesPattern(node);
+
case ClrCanonicalFunctions.YearFunctionName:
case ClrCanonicalFunctions.MonthFunctionName:
case ClrCanonicalFunctions.DayFunctionName:
@@ -545,6 +549,21 @@ private Expression BindConcat(SingleValueFunctionCallNode node)
return ExpressionBinderHelper.MakeFunctionCall(ClrCanonicalFunctions.Concat, QuerySettings, arguments);
}
+ private Expression BindMatchesPattern(SingleValueFunctionCallNode node)
+ {
+ Contract.Assert("matchesPattern" == node.Name);
+
+ Expression[] arguments = BindArguments(node.Parameters);
+ ValidateAllStringArguments(node.Name, arguments);
+
+ Contract.Assert(arguments.Length == 2 && arguments[0].Type == typeof(string) && arguments[1].Type == typeof(string));
+
+ //add argument that must be ECMAScript compatible regex
+ arguments = new[] { arguments[0], arguments[1], Expression.Constant(RegexOptions.ECMAScript) };
+
+ return ExpressionBinderHelper.MakeFunctionCall(ClrCanonicalFunctions.MatchesMattern, QuerySettings, arguments);
+ }
+
private Expression BindTrim(SingleValueFunctionCallNode node)
{
Contract.Assert("trim" == node.Name);
diff --git a/src/Microsoft.AspNetCore.OData/Query/Expressions/QueryBinder.SingleValueFunctionCall.cs b/src/Microsoft.AspNetCore.OData/Query/Expressions/QueryBinder.SingleValueFunctionCall.cs
index 9c63e8e5d..496800ed7 100644
--- a/src/Microsoft.AspNetCore.OData/Query/Expressions/QueryBinder.SingleValueFunctionCall.cs
+++ b/src/Microsoft.AspNetCore.OData/Query/Expressions/QueryBinder.SingleValueFunctionCall.cs
@@ -11,6 +11,7 @@
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
+using System.Text.RegularExpressions;
using Microsoft.AspNetCore.OData.Common;
using Microsoft.AspNetCore.OData.Edm;
using Microsoft.OData;
@@ -68,6 +69,9 @@ public virtual Expression BindSingleValueFunctionCallNode(SingleValueFunctionCal
case ClrCanonicalFunctions.ConcatFunctionName:
return BindConcat(node, context);
+ case ClrCanonicalFunctions.MatchesPatternFunctionName:
+ return BindMatchesPattern(node, context);
+
case ClrCanonicalFunctions.YearFunctionName:
case ClrCanonicalFunctions.MonthFunctionName:
case ClrCanonicalFunctions.DayFunctionName:
@@ -337,6 +341,27 @@ protected virtual Expression BindConcat(SingleValueFunctionCallNode node, QueryB
return ExpressionBinderHelper.MakeFunctionCall(ClrCanonicalFunctions.Concat, context.QuerySettings, arguments);
}
+ ///
+ /// Binds a 'matchesPattern' function to create a LINQ .
+ ///
+ /// The query node to bind.
+ /// The query binder context.
+ /// The LINQ created.
+ protected virtual Expression BindMatchesPattern(SingleValueFunctionCallNode node, QueryBinderContext context)
+ {
+ CheckArgumentNull(node, context, "matchesPattern");
+
+ Expression[] arguments = BindArguments(node.Parameters, context);
+ ValidateAllStringArguments(node.Name, arguments);
+
+ Contract.Assert(arguments.Length == 2 && arguments[0].Type == typeof(string) && arguments[1].Type == typeof(string));
+
+ //add argument that must be ECMAScript compatible regex
+ arguments = new[] { arguments[0], arguments[1], Expression.Constant(RegexOptions.ECMAScript) };
+
+ return ExpressionBinderHelper.MakeFunctionCall(ClrCanonicalFunctions.MatchesMattern, context.QuerySettings, arguments);
+ }
+
///
/// Binds date related functions to create a LINQ .
///
diff --git a/src/Microsoft.AspNetCore.OData/Query/Validator/FilterQueryValidator.cs b/src/Microsoft.AspNetCore.OData/Query/Validator/FilterQueryValidator.cs
index bc120ec74..80180cbb1 100644
--- a/src/Microsoft.AspNetCore.OData/Query/Validator/FilterQueryValidator.cs
+++ b/src/Microsoft.AspNetCore.OData/Query/Validator/FilterQueryValidator.cs
@@ -816,6 +816,9 @@ private static AllowedFunctions ToODataFunction(string functionName)
case ClrCanonicalFunctions.LengthFunctionName:
result = AllowedFunctions.Length;
break;
+ case ClrCanonicalFunctions.MatchesPatternFunctionName:
+ result = AllowedFunctions.MatchesPattern;
+ break;
case ClrCanonicalFunctions.MinuteFunctionName:
result = AllowedFunctions.Minute;
break;
diff --git a/src/Microsoft.AspNetCore.OData/Query/Validator/ODataValidationSettings.cs b/src/Microsoft.AspNetCore.OData/Query/Validator/ODataValidationSettings.cs
index 3d07c574c..d66200817 100644
--- a/src/Microsoft.AspNetCore.OData/Query/Validator/ODataValidationSettings.cs
+++ b/src/Microsoft.AspNetCore.OData/Query/Validator/ODataValidationSettings.cs
@@ -57,7 +57,7 @@ public AllowedArithmeticOperators AllowedArithmeticOperators
///
/// The allowed functions include the following:
///
- /// String related: contains, endswith, startswith, length, indexof, substring, tolower, toupper, trim, concat
+ /// String related: contains, endswith, startswith, length, indexof, substring, tolower, toupper, trim, concat, matchesPattern
///
/// e.g. ~/Customers?$filter=length(CompanyName) eq 19
///
diff --git a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl
index a8e204cae..41ec65407 100644
--- a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl
+++ b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net5.bsl
@@ -1110,9 +1110,9 @@ FlagsAttribute(),
public enum Microsoft.AspNetCore.OData.Query.AllowedFunctions : int {
All = 268435456
AllDateTimeFunctions = 7010304
- AllFunctions = 535494655
+ AllFunctions = 1072365567
AllMathFunctions = 58720256
- AllStringFunctions = 1023
+ AllStringFunctions = 536871935
Any = 134217728
Cast = 1024
Ceiling = 33554432
@@ -1127,6 +1127,7 @@ public enum Microsoft.AspNetCore.OData.Query.AllowedFunctions : int {
IndexOf = 16
IsOf = 67108864
Length = 8
+ MatchesPattern = 536870912
Minute = 524288
Month = 8192
None = 0
@@ -2712,6 +2713,7 @@ public abstract class Microsoft.AspNetCore.OData.Query.Expressions.QueryBinder {
public virtual System.Linq.Expressions.Expression BindInNode (Microsoft.OData.UriParser.InNode inNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
protected virtual System.Linq.Expressions.Expression BindIsOf (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
protected virtual System.Linq.Expressions.Expression BindLength (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
+ protected virtual System.Linq.Expressions.Expression BindMatchesPattern (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
public virtual System.Linq.Expressions.Expression BindNavigationPropertyNode (Microsoft.OData.UriParser.QueryNode sourceNode, Microsoft.OData.Edm.IEdmNavigationProperty navigationProperty, string propertyPath, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
protected virtual System.Linq.Expressions.Expression BindNow (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
public virtual System.Linq.Expressions.Expression BindPropertyAccessQueryNode (Microsoft.OData.UriParser.SingleValuePropertyAccessNode propertyAccessNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
diff --git a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net6.bsl b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net6.bsl
index a8e204cae..41ec65407 100644
--- a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net6.bsl
+++ b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.Net6.bsl
@@ -1110,9 +1110,9 @@ FlagsAttribute(),
public enum Microsoft.AspNetCore.OData.Query.AllowedFunctions : int {
All = 268435456
AllDateTimeFunctions = 7010304
- AllFunctions = 535494655
+ AllFunctions = 1072365567
AllMathFunctions = 58720256
- AllStringFunctions = 1023
+ AllStringFunctions = 536871935
Any = 134217728
Cast = 1024
Ceiling = 33554432
@@ -1127,6 +1127,7 @@ public enum Microsoft.AspNetCore.OData.Query.AllowedFunctions : int {
IndexOf = 16
IsOf = 67108864
Length = 8
+ MatchesPattern = 536870912
Minute = 524288
Month = 8192
None = 0
@@ -2712,6 +2713,7 @@ public abstract class Microsoft.AspNetCore.OData.Query.Expressions.QueryBinder {
public virtual System.Linq.Expressions.Expression BindInNode (Microsoft.OData.UriParser.InNode inNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
protected virtual System.Linq.Expressions.Expression BindIsOf (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
protected virtual System.Linq.Expressions.Expression BindLength (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
+ protected virtual System.Linq.Expressions.Expression BindMatchesPattern (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
public virtual System.Linq.Expressions.Expression BindNavigationPropertyNode (Microsoft.OData.UriParser.QueryNode sourceNode, Microsoft.OData.Edm.IEdmNavigationProperty navigationProperty, string propertyPath, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
protected virtual System.Linq.Expressions.Expression BindNow (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
public virtual System.Linq.Expressions.Expression BindPropertyAccessQueryNode (Microsoft.OData.UriParser.SingleValuePropertyAccessNode propertyAccessNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
diff --git a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl
index a8e204cae..41ec65407 100644
--- a/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl
+++ b/test/Microsoft.AspNetCore.OData.Tests/PublicApi/Microsoft.AspNetCore.OData.PublicApi.NetCore31.bsl
@@ -1110,9 +1110,9 @@ FlagsAttribute(),
public enum Microsoft.AspNetCore.OData.Query.AllowedFunctions : int {
All = 268435456
AllDateTimeFunctions = 7010304
- AllFunctions = 535494655
+ AllFunctions = 1072365567
AllMathFunctions = 58720256
- AllStringFunctions = 1023
+ AllStringFunctions = 536871935
Any = 134217728
Cast = 1024
Ceiling = 33554432
@@ -1127,6 +1127,7 @@ public enum Microsoft.AspNetCore.OData.Query.AllowedFunctions : int {
IndexOf = 16
IsOf = 67108864
Length = 8
+ MatchesPattern = 536870912
Minute = 524288
Month = 8192
None = 0
@@ -2712,6 +2713,7 @@ public abstract class Microsoft.AspNetCore.OData.Query.Expressions.QueryBinder {
public virtual System.Linq.Expressions.Expression BindInNode (Microsoft.OData.UriParser.InNode inNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
protected virtual System.Linq.Expressions.Expression BindIsOf (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
protected virtual System.Linq.Expressions.Expression BindLength (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
+ protected virtual System.Linq.Expressions.Expression BindMatchesPattern (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
public virtual System.Linq.Expressions.Expression BindNavigationPropertyNode (Microsoft.OData.UriParser.QueryNode sourceNode, Microsoft.OData.Edm.IEdmNavigationProperty navigationProperty, string propertyPath, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
protected virtual System.Linq.Expressions.Expression BindNow (Microsoft.OData.UriParser.SingleValueFunctionCallNode node, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
public virtual System.Linq.Expressions.Expression BindPropertyAccessQueryNode (Microsoft.OData.UriParser.SingleValuePropertyAccessNode propertyAccessNode, Microsoft.AspNetCore.OData.Query.Expressions.QueryBinderContext context)
diff --git a/test/Microsoft.AspNetCore.OData.Tests/Query/AllowedFunctionsTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Query/AllowedFunctionsTests.cs
index 616457d6c..02e43df86 100644
--- a/test/Microsoft.AspNetCore.OData.Tests/Query/AllowedFunctionsTests.cs
+++ b/test/Microsoft.AspNetCore.OData.Tests/Query/AllowedFunctionsTests.cs
@@ -32,6 +32,7 @@ public static TheoryDataSet AllStringFunctionsData
AllowedFunctions.ToLower,
AllowedFunctions.ToUpper,
AllowedFunctions.Trim,
+ AllowedFunctions.MatchesPattern,
};
}
}
diff --git a/test/Microsoft.AspNetCore.OData.Tests/Query/Expressions/FilterBinderTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Query/Expressions/FilterBinderTests.cs
index 887d42cd0..a23bbf1d5 100644
--- a/test/Microsoft.AspNetCore.OData.Tests/Query/Expressions/FilterBinderTests.cs
+++ b/test/Microsoft.AspNetCore.OData.Tests/Query/Expressions/FilterBinderTests.cs
@@ -1145,6 +1145,25 @@ public void StringFunctions_StringConcat()
InvokeFiltersAndVerify(filters, new Product { ProductName = "Food" }, (true, true));
}
+ [Fact]
+ public void StringFunctions_StringMatchesPattern()
+ {
+ // Arrange & Act & Assert
+ var filters = BindFilterAndVerify(
+ "matchesPattern(ProductName, 'A\\wc')",
+ "$it => $it.ProductName.IsMatch(\"A\\wc\", ECMAScript)",
+ NotTesting);
+
+ // Arrange & Act & Assert
+ InvokeFiltersAndThrows(filters, new Product { ProductName = null }, (typeof(ArgumentNullException), false));
+
+ InvokeFiltersAndVerify(filters, new Product { ProductName = "Abcd" }, (true, true));
+
+ InvokeFiltersAndVerify(filters, new Product { ProductName = "Abd" }, (false, false));
+
+ InvokeFiltersAndVerify(filters, new Product { ProductName = "Aθd" }, (false, false)); // ECMAScript has strict matching of \w
+ }
+
[Fact]
public void StringFunctions_RecursiveMethodCall()
{
diff --git a/test/Microsoft.AspNetCore.OData.Tests/Query/Validator/FilterQueryValidatorTests.cs b/test/Microsoft.AspNetCore.OData.Tests/Query/Validator/FilterQueryValidatorTests.cs
index 2297ffed8..dd5999074 100644
--- a/test/Microsoft.AspNetCore.OData.Tests/Query/Validator/FilterQueryValidatorTests.cs
+++ b/test/Microsoft.AspNetCore.OData.Tests/Query/Validator/FilterQueryValidatorTests.cs
@@ -556,6 +556,10 @@ public static TheoryDataSet StringFunctions
{ AllowedFunctions.StartsWith, "startswith(null, 'Name')", "startswith" },
{ AllowedFunctions.StartsWith, "startswith(ProductName,'Name')", "startswith" },
{ AllowedFunctions.StartsWith, "startswith(ProductName, 'Name')", "startswith" },
+ { AllowedFunctions.MatchesPattern, "matchesPattern(null,'Name')", "matchesPattern" },
+ { AllowedFunctions.MatchesPattern, "matchesPattern(null, 'Name')", "matchesPattern" },
+ { AllowedFunctions.MatchesPattern, "matchesPattern(ProductName,'Name')", "matchesPattern" },
+ { AllowedFunctions.MatchesPattern, "matchesPattern(ProductName, 'Name')", "matchesPattern" },
{ AllowedFunctions.Substring, "substring(null,1) eq 'Name'", "substring" },
{ AllowedFunctions.Substring, "substring(null, 1) eq 'Name'", "substring" },
{ AllowedFunctions.Substring, "substring(ProductName,1) eq 'Name'", "substring" },