Skip to content

Commit 5da0f2d

Browse files
committed
Fixes #1161: Enable Parameter alias for collection value
Related the parameter alias to collection value node, not only the single value node,
1 parent 6f0d76b commit 5da0f2d

File tree

18 files changed

+228
-53
lines changed

18 files changed

+228
-53
lines changed

src/Microsoft.OData.Core/PublicAPI/net10.0/PublicAPI.Shipped.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,7 +1091,7 @@ Microsoft.OData.ODataUri.Index.set -> void
10911091
Microsoft.OData.ODataUri.ODataUri() -> void
10921092
Microsoft.OData.ODataUri.OrderBy.get -> Microsoft.OData.UriParser.OrderByClause
10931093
Microsoft.OData.ODataUri.OrderBy.set -> void
1094-
Microsoft.OData.ODataUri.ParameterAliasNodes.get -> System.Collections.Generic.IDictionary<string, Microsoft.OData.UriParser.SingleValueNode>
1094+
Microsoft.OData.ODataUri.ParameterAliasNodes.get -> System.Collections.Generic.IDictionary<string, Microsoft.OData.UriParser.QueryNode>
10951095
Microsoft.OData.ODataUri.Path.get -> Microsoft.OData.UriParser.ODataPath
10961096
Microsoft.OData.ODataUri.Path.set -> void
10971097
Microsoft.OData.ODataUri.QueryCount.get -> bool?
@@ -1568,7 +1568,7 @@ Microsoft.OData.UriParser.ODataQueryOptionParser.ODataQueryOptionParser(Microsof
15681568
Microsoft.OData.UriParser.ODataQueryOptionParser.ODataQueryOptionParser(Microsoft.OData.Edm.IEdmModel model, Microsoft.OData.Edm.IEdmType targetEdmType, Microsoft.OData.Edm.IEdmNavigationSource targetNavigationSource, System.Collections.Generic.IDictionary<string, string> queryOptions, System.IServiceProvider container) -> void
15691569
Microsoft.OData.UriParser.ODataQueryOptionParser.ODataQueryOptionParser(Microsoft.OData.Edm.IEdmModel model, Microsoft.OData.UriParser.ODataPath odataPath, System.Collections.Generic.IDictionary<string, string> queryOptions) -> void
15701570
Microsoft.OData.UriParser.ODataQueryOptionParser.ODataQueryOptionParser(Microsoft.OData.Edm.IEdmModel model, Microsoft.OData.UriParser.ODataPath odataPath, System.Collections.Generic.IDictionary<string, string> queryOptions, System.IServiceProvider container) -> void
1571-
Microsoft.OData.UriParser.ODataQueryOptionParser.ParameterAliasNodes.get -> System.Collections.Generic.IDictionary<string, Microsoft.OData.UriParser.SingleValueNode>
1571+
Microsoft.OData.UriParser.ODataQueryOptionParser.ParameterAliasNodes.get -> System.Collections.Generic.IDictionary<string, Microsoft.OData.UriParser.QueryNode>
15721572
Microsoft.OData.UriParser.ODataQueryOptionParser.ParseApply() -> Microsoft.OData.UriParser.Aggregation.ApplyClause
15731573
Microsoft.OData.UriParser.ODataQueryOptionParser.ParseCompute() -> Microsoft.OData.UriParser.ComputeClause
15741574
Microsoft.OData.UriParser.ODataQueryOptionParser.ParseCount() -> bool?
@@ -1615,7 +1615,7 @@ Microsoft.OData.UriParser.ODataUriParser.ODataUriParser(Microsoft.OData.Edm.IEdm
16151615
Microsoft.OData.UriParser.ODataUriParser.ODataUriParser(Microsoft.OData.Edm.IEdmModel model, System.Uri relativeUri, System.IServiceProvider container) -> void
16161616
Microsoft.OData.UriParser.ODataUriParser.ODataUriParser(Microsoft.OData.Edm.IEdmModel model, System.Uri serviceRoot, System.Uri uri) -> void
16171617
Microsoft.OData.UriParser.ODataUriParser.ODataUriParser(Microsoft.OData.Edm.IEdmModel model, System.Uri serviceRoot, System.Uri uri, System.IServiceProvider container) -> void
1618-
Microsoft.OData.UriParser.ODataUriParser.ParameterAliasNodes.get -> System.Collections.Generic.IDictionary<string, Microsoft.OData.UriParser.SingleValueNode>
1618+
Microsoft.OData.UriParser.ODataUriParser.ParameterAliasNodes.get -> System.Collections.Generic.IDictionary<string, Microsoft.OData.UriParser.QueryNode>
16191619
Microsoft.OData.UriParser.ODataUriParser.ParseApply() -> Microsoft.OData.UriParser.Aggregation.ApplyClause
16201620
Microsoft.OData.UriParser.ODataUriParser.ParseCompute() -> Microsoft.OData.UriParser.ComputeClause
16211621
Microsoft.OData.UriParser.ODataUriParser.ParseCount() -> bool?
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
Microsoft.OData.ODataNestedResourceInfo.InstanceAnnotations.get -> System.Collections.Generic.ICollection<Microsoft.OData.ODataInstanceAnnotation>
22
Microsoft.OData.ODataNestedResourceInfo.InstanceAnnotations.set -> void
33
Microsoft.OData.ValidationKinds.ThrowOnUnexpectedODataPropertyAnnotationOnNavigationProperty = 8 -> Microsoft.OData.ValidationKinds
4+
Microsoft.OData.UriParser.ParameterAliasCollectionNode
5+
Microsoft.OData.UriParser.ParameterAliasCollectionNode.Alias.get -> string
6+
Microsoft.OData.UriParser.ParameterAliasCollectionNode.ParameterAliasCollectionNode(string alias, Microsoft.OData.Edm.IEdmCollectionTypeReference collectionType) -> void
7+
override Microsoft.OData.UriParser.ParameterAliasCollectionNode.Accept<T>(Microsoft.OData.UriParser.QueryNodeVisitor<T> visitor) -> T
8+
override Microsoft.OData.UriParser.ParameterAliasCollectionNode.CollectionType.get -> Microsoft.OData.Edm.IEdmCollectionTypeReference
9+
override Microsoft.OData.UriParser.ParameterAliasCollectionNode.ItemType.get -> Microsoft.OData.Edm.IEdmTypeReference
10+
virtual Microsoft.OData.UriParser.QueryNodeVisitor<T>.Visit(Microsoft.OData.UriParser.ParameterAliasCollectionNode nodeIn) -> T

src/Microsoft.OData.Core/Uri/NodeToStringBuilder.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,17 @@ public override String Visit(ParameterAliasNode node)
397397
return node.Alias;
398398
}
399399

400+
/// <summary>
401+
/// Translates a <see cref="ParameterAliasCollectionNode"/> into a corresponding <see cref="String"/>.
402+
/// </summary>
403+
/// <param name="node">The node to translate.</param>
404+
/// <returns>The translated String.</returns>
405+
public override String Visit(ParameterAliasCollectionNode node)
406+
{
407+
ExceptionUtils.CheckArgumentNotNull(node, "node");
408+
return node.Alias;
409+
}
410+
400411
/// <summary>
401412
/// Translates a <see cref="NamedFunctionParameterNode"/> into a corresponding <see cref="String"/>.
402413
/// </summary>
@@ -570,12 +581,12 @@ internal string TranslateComputeClause(ComputeClause computeClause)
570581
/// </summary>
571582
/// <param name="dictionary">Dictionary</param>
572583
/// <returns>The url query string of dictionary's key value pairs (URL encoded)</returns>
573-
internal String TranslateParameterAliasNodes(IDictionary<string, SingleValueNode> dictionary)
584+
internal String TranslateParameterAliasNodes(IDictionary<string, QueryNode> dictionary)
574585
{
575586
String result = null;
576587
if (dictionary != null)
577588
{
578-
foreach (KeyValuePair<string, SingleValueNode> keyValuePair in dictionary)
589+
foreach (KeyValuePair<string, QueryNode> keyValuePair in dictionary)
579590
{
580591
if (keyValuePair.Value != null)
581592
{

src/Microsoft.OData.Core/Uri/ODataUri.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public Uri ServiceRoot
124124
/// <summary>
125125
/// Get the parameter alias nodes info.
126126
/// </summary>
127-
public IDictionary<string, SingleValueNode> ParameterAliasNodes
127+
public IDictionary<string, QueryNode> ParameterAliasNodes
128128
{
129129
get
130130
{

src/Microsoft.OData.Core/Uri/ODataUriSlim.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public ODataUriSlim(ODataUriSlim odataUriSlim)
6969
/// <summary>
7070
/// Get the parameter alias nodes info.
7171
/// </summary>
72-
public IDictionary<string, SingleValueNode> ParameterAliasNodes => this.odataUri.ParameterAliasNodes;
72+
public IDictionary<string, QueryNode> ParameterAliasNodes => this.odataUri.ParameterAliasNodes;
7373

7474
/// <summary>
7575
/// Gets any custom query options for this uri.

src/Microsoft.OData.Core/UriParser/Binders/MetadataBinder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ protected internal QueryNode Bind(QueryToken token)
224224
/// </summary>
225225
/// <param name="functionParameterAliasToken">The alias syntactics token.</param>
226226
/// <returns>The semantics node for parameter alias.</returns>
227-
protected virtual SingleValueNode BindParameterAlias(FunctionParameterAliasToken functionParameterAliasToken)
227+
protected virtual QueryNode BindParameterAlias(FunctionParameterAliasToken functionParameterAliasToken)
228228
{
229229
ParameterAliasBinder binder = new ParameterAliasBinder(this.Bind);
230230
return binder.BindParameterAlias(this.BindingState, functionParameterAliasToken);

src/Microsoft.OData.Core/UriParser/Binders/ParameterAliasBinder.cs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
using Microsoft.OData.Metadata;
88
using Microsoft.OData.Edm;
9-
using Microsoft.OData.Core;
109

1110
namespace Microsoft.OData.UriParser
1211
{
@@ -38,7 +37,7 @@ internal ParameterAliasBinder(MetadataBinder.QueryTokenVisitor bindMethod)
3837
/// <param name="bindingState">The alias name which is inside another alias value.</param>
3938
/// <param name="aliasToken">The cache of alias value nodes</param>
4039
/// <returns>The semantics node tree for alias (the @p1 in "@p1=...", not alias value expression)</returns>
41-
internal ParameterAliasNode BindParameterAlias(BindingState bindingState, FunctionParameterAliasToken aliasToken)
40+
internal QueryNode BindParameterAlias(BindingState bindingState, FunctionParameterAliasToken aliasToken)
4241
{
4342
ExceptionUtils.CheckArgumentNotNull(bindingState, "bindingState");
4443
ExceptionUtils.CheckArgumentNotNull(aliasToken, "aliasToken");
@@ -51,7 +50,7 @@ internal ParameterAliasNode BindParameterAlias(BindingState bindingState, Functi
5150
}
5251

5352
// in cache?
54-
SingleValueNode aliasValueNode = null;
53+
QueryNode aliasValueNode = null;
5554
if (!aliasValueAccessor.ParameterAliasValueNodesCached.TryGetValue(alias, out aliasValueNode))
5655
{
5756
// has value expression?
@@ -67,6 +66,11 @@ internal ParameterAliasNode BindParameterAlias(BindingState bindingState, Functi
6766
}
6867
}
6968

69+
if (aliasValueNode is CollectionNode collectionNode)
70+
{
71+
return new ParameterAliasCollectionNode(alias, collectionNode.CollectionType);
72+
}
73+
7074
return new ParameterAliasNode(alias, aliasValueNode.GetEdmTypeReference());
7175
}
7276

@@ -77,7 +81,7 @@ internal ParameterAliasNode BindParameterAlias(BindingState bindingState, Functi
7781
/// <param name="aliasValueExpression">The alias value's expression text.</param>
7882
/// <param name="parameterType">The edm type of the parameter.</param>
7983
/// <returns>The semantics node of the expression text.</returns>
80-
private SingleValueNode ParseAndBindParameterAliasValueExpression(BindingState bindingState, string aliasValueExpression, IEdmTypeReference parameterType)
84+
private QueryNode ParseAndBindParameterAliasValueExpression(BindingState bindingState, string aliasValueExpression, IEdmTypeReference parameterType)
8185
{
8286
// Get the syntactic representation of the filter expression
8387
// TODO: change Settings.FilterLimit to ParameterAliasValueLimit
@@ -87,16 +91,8 @@ private SingleValueNode ParseAndBindParameterAliasValueExpression(BindingState b
8791
// Special logic to handle parameter alias token.
8892
aliasValueToken = ParseComplexOrCollectionAlias(aliasValueToken, parameterType, bindingState.Model);
8993

90-
// Get the semantic node, and check for SingleValueNode
91-
QueryNode aliasValueNode = this.bindMethod(aliasValueToken);
92-
SingleValueNode result = aliasValueNode as SingleValueNode;
93-
if (result == null)
94-
{
95-
// TODO: add string resource
96-
throw new ODataException(SRResources.MetadataBinder_ParameterAliasValueExpressionNotSingleValue);
97-
}
98-
99-
return result;
94+
// Get the semantic node, it should support single and collection value node.
95+
return this.bindMethod(aliasValueToken);
10096
}
10197

10298
/// <summary>

src/Microsoft.OData.Core/UriParser/ODataQueryOptionParser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ public ODataUriParserSettings Settings
137137
/// <summary>
138138
/// Get the parameter alias nodes info.
139139
/// </summary>
140-
public IDictionary<string, SingleValueNode> ParameterAliasNodes
140+
public IDictionary<string, QueryNode> ParameterAliasNodes
141141
{
142142
get { return this.Configuration.ParameterAliasValueAccessor.ParameterAliasValueNodesCached; }
143143
}

src/Microsoft.OData.Core/UriParser/ODataUriParser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ public ParseDynamicPathSegment ParseDynamicPathSegmentFunc
214214
/// <summary>
215215
/// Get the parameter alias nodes info.
216216
/// </summary>
217-
public IDictionary<string, SingleValueNode> ParameterAliasNodes
217+
public IDictionary<string, QueryNode> ParameterAliasNodes
218218
{
219219
get
220220
{
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//---------------------------------------------------------------------
2+
// <copyright file="ParameterAliasCollectionNode.cs" company="Microsoft">
3+
// Copyright (C) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
4+
// </copyright>
5+
//---------------------------------------------------------------------
6+
7+
namespace Microsoft.OData.UriParser
8+
{
9+
using Microsoft.OData.Edm;
10+
11+
/// <summary>
12+
/// Represents a parameter alias that refers to a collection value.
13+
/// </summary>
14+
public class ParameterAliasCollectionNode : CollectionNode
15+
{
16+
/// <summary>
17+
/// Constructor.
18+
/// </summary>
19+
/// <param name="alias">The parameter alias.</param>
20+
/// <param name="collectionType">The alias' type which is inferred from the type of alias value's CollectionNode.</param>
21+
public ParameterAliasCollectionNode(string alias, IEdmCollectionTypeReference collectionType)
22+
{
23+
ExceptionUtils.CheckArgumentNotNull(collectionType, "collectionType");
24+
25+
Alias = alias;
26+
CollectionType = collectionType;
27+
}
28+
29+
/// <summary>
30+
/// The parameter alias.
31+
/// </summary>
32+
public string Alias { get; }
33+
34+
/// <summary>
35+
/// Gets the type of a single item from the collection represented by this node.
36+
/// </summary>
37+
public override IEdmTypeReference ItemType => CollectionType.ElementType();
38+
39+
/// <summary>
40+
/// The type of the collection represented by this node.
41+
/// </summary>
42+
public override IEdmCollectionTypeReference CollectionType { get; }
43+
44+
/// <summary>
45+
/// Is InternalQueryNodeKind.ParameterAliasCollection.
46+
/// </summary>
47+
internal override InternalQueryNodeKind InternalKind => InternalQueryNodeKind.ParameterAliasCollection;
48+
49+
/// <summary>
50+
/// Accept a <see cref="QueryNodeVisitor{T}"/> to walk a tree of <see cref="QueryNode"/>s.
51+
/// </summary>
52+
/// <typeparam name="T">Type that the visitor will return after visiting this token.</typeparam>
53+
/// <param name="visitor">An implementation of the visitor interface.</param>
54+
/// <returns>An object whose type is determined by the type parameter of the visitor.</returns>
55+
/// <exception cref="System.ArgumentNullException">Throws if the input visitor is null.</exception>
56+
public override T Accept<T>(QueryNodeVisitor<T> visitor)
57+
{
58+
ExceptionUtils.CheckArgumentNotNull(visitor, "visitor");
59+
return visitor.Visit(this);
60+
}
61+
}
62+
}

0 commit comments

Comments
 (0)