Describe the bug
It appears that the library fails to parse a request URL that computes a custom property using the $compute query option and includes the computed property to the $select query option.
Consider the following request URL.
GET /Collection1
?$compute=graph.VectorDistance(contentVector, [1, 2, 3]) as SimilarityScore
&$select=Id, Title, SimilarityScore
In this case SimilarityScore is not a property defined on the entity type, but computed dynamically from the $compute expression. When I try to parse this URL, I get an error stating that it could not find the SimilarityScore property on the type. Is this a bug, feature gap, or by design?
I also removed the $select query option to see if the error would go away:
GET /Collection1
?$compute=graph.VectorDistance(contentVector,[1,2,3]) as SimilarityScore
But I got an error saying that the parameter to the VectorDistance function is not a single-valued parameter. So it seems like the library also does not support having a collection as the parameter of a function.
The argument for an invocation of a function with name 'graph.VectorDistance' is not a single value. All arguments for this function must be single values
If this is not supported by OData or not a bug, is there an alternative construct we can use to represent vector search queries?
Assemblies affected
Microsoft.OData.Core 8.4.0
Steps to Reproduce
Create a new console application with the following code. Make sure to also install Microsoft.OData.Core 8.4.0.
using Microsoft.OData.Edm;
using Microsoft.OData.Edm.Csdl;
using Microsoft.OData.UriParser;
using System.Text;
Console.WriteLine("Hello, World!");
var schema =
"""
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0"
xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:DataServices>
<Schema Namespace="graph" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<!-- Entity Type -->
<EntityType Name="Item">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.String" Nullable="false"/>
<Property Name="Title" Type="Edm.String" Nullable="true"/>
<Property Name="contentVector" Type="Collection(Edm.Double)" Nullable="false"/>
</EntityType>
<Function Name="VectorDistance" IsComposable="true">
<Parameter Name="vector1" Type="Collection(Edm.Double)" />
<Parameter Name="vector2" Type="Collection(Edm.Double)" />
<ReturnType Type="Edm.Double" />
</Function>
<!-- Entity Container -->
<EntityContainer Name="DefaultContainer">
<EntitySet Name="Collection1" EntityType="graph.Item" />
</EntityContainer>
<!-- Custom Function -->
</Schema>
</edmx:DataServices>
</edmx:Edmx>
""";
var stream = new MemoryStream(Encoding.UTF8.GetBytes(schema));
var reader = System.Xml.XmlReader.Create(stream);
var model = CsdlReader.Parse(reader);
var serviceRoot = new Uri("https://example.com/");
var fullUri = new Uri(serviceRoot, "Collection1?$compute=graph.VectorDistance(contentVector,[1,2,3]) as SimilarityScore&$select=Id,Title,SimilarityScore");
// Parse the URI
var fn = model.FindDeclaredOperations("graph.VectorDistance").First();
CustomUriFunctions.AddCustomUriFunction("graph.VectorDistance", new FunctionSignatureWithReturnType(fn.GetReturn().Type, fn.Parameters.Select(p => p.Type).ToArray()));
var parser = new ODataUriParser(model, serviceRoot, fullUri);
var parsedUri = parser.ParseUri();
// Display parsed structure
Console.WriteLine("Parsed Path: " + parsedUri.Path.ToString());
if (parsedUri.Compute != null)
{
Console.WriteLine("Compute expressions:");
foreach (var expr in parsedUri.Compute.ComputedItems)
{
Console.WriteLine($" {expr.Expression} AS {expr.Alias}");
}
}
if (parsedUri.SelectAndExpand != null)
{
Console.WriteLine("Selected properties:");
foreach (var sel in parsedUri.SelectAndExpand.SelectedItems)
{
Console.WriteLine(" " + sel.ToString());
}
}
Console.WriteLine("Parsing complete!");
Then run the code.
Expected behaviour
The query options should be correctly parsed, and the sample app above should print the projected select items.
Actual behaviour
I got an exception saying that the property SimilarityScore could not be found. This is surprising, I believe the $select query option should be able to handle properties created by $compute.
Could not find a property named 'SimilarityScore' on type 'graph.Item'.
at Microsoft.OData.UriParser.SelectPathSegmentTokenBinder.ConvertNonTypeTokenToSegment(PathSegmentToken tokenIn, IEdmModel model, IEdmStructuredType edmType, ODataUriResolver resolver, BindingState state) in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\Binders\SelectPathSegmentTokenBinder.cs:line 90
at Microsoft.OData.UriParser.SelectExpandBinder.ProcessSelectTokenPath(PathSegmentToken tokenIn) in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\Binders\SelectExpandBinder.cs:line 694
at Microsoft.OData.UriParser.SelectExpandBinder.GenerateSelectItem(SelectTermToken tokenIn) in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\Binders\SelectExpandBinder.cs:line 276
at Microsoft.OData.UriParser.SelectExpandBinder.Bind(ExpandToken expandToken, SelectToken selectToken) in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\Binders\SelectExpandBinder.cs:line 153
at Microsoft.OData.UriParser.SelectExpandSemanticBinder.Bind(ODataPathInfo odataPathInfo, ExpandToken expandToken, SelectToken selectToken, ODataUriParserConfiguration configuration, BindingState state) in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\Binders\SelectExpandSemanticBinder.cs:line 37
at Microsoft.OData.UriParser.ODataQueryOptionParser.ParseSelectAndExpandImplementation(String select, String expand, ODataUriParserConfiguration configuration, ODataPathInfo odataPathInfo) in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\ODataQueryOptionParser.cs:line 451
at Microsoft.OData.UriParser.ODataQueryOptionParser.ParseSelectAndExpand() in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\ODataQueryOptionParser.cs:line 236
at Microsoft.OData.UriParser.ODataUriParser.ParseSelectAndExpand() in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\ODataUriParser.cs:line 322
at Microsoft.OData.UriParser.ODataUriParser.ParseUri() in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\ODataUriParser.cs:line 485
at Program.<Main>$(String[] args) in C:\repos\tinker\ODataAggregationExample\ODataAggregationExample\Program.cs:line 58
After removing the $select query option, I got the following exception:
The argument for an invocation of a function with name 'graph.VectorDistance' is not a single value. All arguments for this function must be single values.
at Microsoft.OData.UriParser.FunctionCallBinder.ValidateArgumentsAreSingleValue(String functionName, List`1 argumentNodes) in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\Binders\FunctionCallBinder.cs:line 82
at Microsoft.OData.UriParser.FunctionCallBinder.BindAsUriFunction(FunctionCallToken functionCallToken, List`1 argumentNodes) in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\Binders\FunctionCallBinder.cs:line 306
at Microsoft.OData.UriParser.FunctionCallBinder.BindFunctionCall(FunctionCallToken functionCallToken) in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\Binders\FunctionCallBinder.cs:line 238
at Microsoft.OData.UriParser.MetadataBinder.BindFunctionCall(FunctionCallToken functionCallToken) in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\Binders\MetadataBinder.cs:line 346
at Microsoft.OData.UriParser.MetadataBinder.Bind(QueryToken token) in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\Binders\MetadataBinder.cs:line 186
at Microsoft.OData.UriParser.ComputeBinder.BindComputeExpressionToken(ComputeExpressionToken token) in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\Binders\ComputeBinder.cs:line 38
at Microsoft.OData.UriParser.ComputeBinder.BindCompute(ComputeToken token) in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\Binders\ComputeBinder.cs:line 29
at Microsoft.OData.UriParser.ODataQueryOptionParser.ParseComputeImplementation(String compute, ODataUriParserConfiguration configuration, ODataPathInfo odataPathInfo) in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\ODataQueryOptionParser.cs:line 651
at Microsoft.OData.UriParser.ODataQueryOptionParser.ParseCompute() in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\ODataQueryOptionParser.cs:line 367
at Microsoft.OData.UriParser.ODataUriParser.ParseCompute() in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\ODataUriParser.cs:line 471
at Microsoft.OData.UriParser.ODataUriParser.ParseUri() in D:\a\_work\1\s\src\Microsoft.OData.Core\UriParser\ODataUriParser.cs:line 490
at Program.<Main>$(String[] args) in C:\repos\ODataAggregationExample\ODataAggregationExample\Program.cs:line 58
Additional details
Optional, details of the root cause if known. Delete this section if you have no additional details to add.
Describe the bug
It appears that the library fails to parse a request URL that computes a custom property using the
$computequery option and includes the computed property to the$selectquery option.Consider the following request URL.
In this case
SimilarityScoreis not a property defined on the entity type, but computed dynamically from the$computeexpression. When I try to parse this URL, I get an error stating that it could not find theSimilarityScoreproperty on the type. Is this a bug, feature gap, or by design?I also removed the
$selectquery option to see if the error would go away:But I got an error saying that the parameter to the
VectorDistancefunction is not a single-valued parameter. So it seems like the library also does not support having a collection as the parameter of a function.If this is not supported by OData or not a bug, is there an alternative construct we can use to represent vector search queries?
Assemblies affected
Microsoft.OData.Core8.4.0Steps to Reproduce
Create a new console application with the following code. Make sure to also install
Microsoft.OData.Core8.4.0.Then run the code.
Expected behaviour
The query options should be correctly parsed, and the sample app above should print the projected select items.
Actual behaviour
I got an exception saying that the property
SimilarityScorecould not be found. This is surprising, I believe the $select query option should be able to handle properties created by $compute.After removing the
$selectquery option, I got the following exception:Additional details
Optional, details of the root cause if known. Delete this section if you have no additional details to add.