diff --git a/src/Microsoft.OData.Core/UriParser/Binders/FunctionCallBinder.cs b/src/Microsoft.OData.Core/UriParser/Binders/FunctionCallBinder.cs
index 49cf0da4ab..de4ff7da72 100644
--- a/src/Microsoft.OData.Core/UriParser/Binders/FunctionCallBinder.cs
+++ b/src/Microsoft.OData.Core/UriParser/Binders/FunctionCallBinder.cs
@@ -100,7 +100,7 @@ internal static SingleValueNode[] ValidateArgumentsAreSingleValue(string functio
/// The nodes of the arguments, can be new {null,null}.
/// The signatures to match against
/// Returns the matching signature or throws
- internal static FunctionSignatureWithReturnType MatchSignatureToBuiltInFunction(string functionName, SingleValueNode[] argumentNodes, FunctionSignatureWithReturnType[] signatures)
+ internal static FunctionSignatureWithReturnType MatchSignatureToUriFunction(string functionName, SingleValueNode[] argumentNodes, FunctionSignatureWithReturnType[] signatures)
{
FunctionSignatureWithReturnType signature;
IEdmTypeReference[] argumentTypes = argumentNodes.Select(s => s.TypeReference).ToArray();
@@ -202,7 +202,7 @@ internal QueryNode BindFunctionCall(FunctionCallToken functionCallToken)
// If there isn't, bind as built-in function
// Bind all arguments
List argumentNodes = new List(functionCallToken.Arguments.Select(ar => this.bindMethod(ar)));
- return BindAsBuiltInFunction(functionCallToken, argumentNodes);
+ return BindAsUriFunction(functionCallToken, argumentNodes);
}
///
@@ -250,7 +250,7 @@ internal bool TryBindDottedIdentifierAsFunctionCall(DottedIdentifierToken dotted
/// the function call token to bind
/// list of semantically bound arguments
/// A function call node bound to this function.
- private QueryNode BindAsBuiltInFunction(FunctionCallToken functionCallToken, List argumentNodes)
+ private QueryNode BindAsUriFunction(FunctionCallToken functionCallToken, List argumentNodes)
{
if (functionCallToken.Source != null)
{
@@ -270,7 +270,7 @@ private QueryNode BindAsBuiltInFunction(FunctionCallToken functionCallToken, Lis
// Do some validation and get potential built-in functions that could match what we saw
FunctionSignatureWithReturnType[] signatures = GetUriFunctionSignatures(functionCallTokenName);
SingleValueNode[] argumentNodeArray = ValidateArgumentsAreSingleValue(functionCallTokenName, argumentNodes);
- FunctionSignatureWithReturnType signature = MatchSignatureToBuiltInFunction(functionCallTokenName, argumentNodeArray, signatures);
+ FunctionSignatureWithReturnType signature = MatchSignatureToUriFunction(functionCallTokenName, argumentNodeArray, signatures);
if (signature.ReturnType != null)
{
TypePromoteArguments(signature, argumentNodes);
diff --git a/test/FunctionalTests/Microsoft.OData.Core.Tests/ScenarioTests/UriParser/CustomUriFunctionsTests.cs b/test/FunctionalTests/Microsoft.OData.Core.Tests/ScenarioTests/UriParser/CustomUriFunctionsTests.cs
index 050e6ad28a..db42186c75 100644
--- a/test/FunctionalTests/Microsoft.OData.Core.Tests/ScenarioTests/UriParser/CustomUriFunctionsTests.cs
+++ b/test/FunctionalTests/Microsoft.OData.Core.Tests/ScenarioTests/UriParser/CustomUriFunctionsTests.cs
@@ -9,6 +9,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using Microsoft.OData.Core.Tests.UriParser;
namespace Microsoft.OData.Core.Tests.ScenarioTests.UriParser
{
@@ -513,6 +514,34 @@ public void RemoveCustomFunction_RemoveFunctionWithSameNameAndSignature_OtherOve
#endregion
+ #region ODataUriParser
+
+ [Fact]
+ public void ParseWithCustomUriFunction()
+ {
+ try
+ {
+ FunctionSignatureWithReturnType myStringFunction
+ = new FunctionSignatureWithReturnType(EdmCoreModel.Instance.GetBoolean(true), EdmCoreModel.Instance.GetString(true), EdmCoreModel.Instance.GetString(true));
+
+ // Add a custom uri function
+ CustomUriFunctions.AddCustomUriFunction("mystringfunction", myStringFunction);
+
+ var fullUri = new Uri("http://www.odata.com/OData/People" + "?$filter=mystringfunction(Name, 'BlaBla')");
+ ODataUriParser parser = new ODataUriParser(HardCodedTestModel.TestModel, new Uri("http://www.odata.com/OData/"), fullUri);
+
+ var startsWithArgs = parser.ParseFilter().Expression.ShouldBeSingleValueFunctionCallQueryNode("mystringfunction").And.Parameters.ToList();
+ startsWithArgs[0].ShouldBeSingleValuePropertyAccessQueryNode(HardCodedTestModel.GetPersonNameProp());
+ startsWithArgs[1].ShouldBeConstantQueryNode("BlaBla");
+ }
+ finally
+ {
+ CustomUriFunctions.RemoveCustomUriFunction("mystringfunction");
+ }
+ }
+
+ #endregion
+
#region Private Methods
private FunctionSignatureWithReturnType[] GetCustomFunctionSignaturesOrNull(string customFunctionName)
diff --git a/test/FunctionalTests/Microsoft.OData.Core.Tests/UriParser/Binders/FunctionCallBinderTests.cs b/test/FunctionalTests/Microsoft.OData.Core.Tests/UriParser/Binders/FunctionCallBinderTests.cs
index 0f111af705..4c5db49a57 100644
--- a/test/FunctionalTests/Microsoft.OData.Core.Tests/UriParser/Binders/FunctionCallBinderTests.cs
+++ b/test/FunctionalTests/Microsoft.OData.Core.Tests/UriParser/Binders/FunctionCallBinderTests.cs
@@ -296,7 +296,7 @@ public void MatchArgumentsToSignatureDuplicateSignature()
};
var signatures = this.GetDuplicateIndexOfFunctionSignatureForTest();
- Action bind = () => FunctionCallBinder.MatchSignatureToBuiltInFunction(
+ Action bind = () => FunctionCallBinder.MatchSignatureToUriFunction(
"IndexOf",
new SingleValueNode[] {
new SingleValuePropertyAccessNode(new ConstantNode(null)/*parent*/, new EdmStructuralProperty(new EdmEntityType("MyNamespace", "MyEntityType"), "myPropertyName", argumentNodes[0].GetEdmTypeReference())),
@@ -318,7 +318,7 @@ public void MatchArgumentsToSignature()
};
var signatures = this.GetHardCodedYearFunctionSignatureForTest();
- var result = FunctionCallBinder.MatchSignatureToBuiltInFunction(
+ var result = FunctionCallBinder.MatchSignatureToUriFunction(
"year",
argumentNodes.Select(s => (SingleValueNode)s).ToArray(),
signatures);
@@ -336,7 +336,7 @@ public void MatchArgumentsToSignatureNoMatchEmpty()
new ConstantNode(4)
};
- Action bind = () => FunctionCallBinder.MatchSignatureToBuiltInFunction(
+ Action bind = () => FunctionCallBinder.MatchSignatureToUriFunction(
"year",
new SingleValueNode[] {
new SingleValuePropertyAccessNode(new ConstantNode(null)/*parent*/, new EdmStructuralProperty(new EdmEntityType("MyNamespace", "MyEntityType"), "myPropertyName", argumentNodes[0].GetEdmTypeReference()))},
@@ -356,7 +356,7 @@ public void MatchArgumentsToSignatureNoMatchContainsSignatures()
new ConstantNode(4)
};
- Action bind = () => FunctionCallBinder.MatchSignatureToBuiltInFunction(
+ Action bind = () => FunctionCallBinder.MatchSignatureToUriFunction(
"year",
new SingleValueNode[] {
new SingleValuePropertyAccessNode(new ConstantNode(null)/*parent*/, new EdmStructuralProperty(new EdmEntityType("MyNamespace", "MyEntityType"), "myPropertyName", argumentNodes[0].GetEdmTypeReference()))},
@@ -370,7 +370,7 @@ public void MatchArgumentsToSignatureNoMatchContainsSignatures()
[Fact]
public void MatchArgumentsToSignatureWillPickRightSignatureForSomeNullArgumentTypes()
{
- var result = FunctionCallBinder.MatchSignatureToBuiltInFunction(
+ var result = FunctionCallBinder.MatchSignatureToUriFunction(
"substring",
new SingleValueNode[] {
new SingleValuePropertyAccessNode(new ConstantNode(null)/*parent*/, new EdmStructuralProperty(new EdmEntityType("MyNamespace", "MyEntityType"), "myPropertyName", EdmCoreModel.Instance.GetString(true))),