/// <summary> /// Creates an AnyNode or an AllNode from the given /// </summary> /// <param name="state">State of binding.</param> /// <param name="parent">Parent node to the lambda.</param> /// <param name="lambdaExpression">Bound Lambda expression.</param> /// <param name="newRangeVariable">The new range variable being added by this lambda node.</param> /// <param name="queryTokenKind">Token kind.</param> /// <returns>A new LambdaNode bound to metadata.</returns> internal static LambdaNode CreateLambdaNode( BindingState state, CollectionNode parent, SingleValueNode lambdaExpression, RangeVariable newRangeVariable, QueryTokenKind queryTokenKind) { LambdaNode lambdaNode; if (queryTokenKind == QueryTokenKind.Any) { lambdaNode = new AnyNode(new Collection <RangeVariable>(state.RangeVariables.ToList()), newRangeVariable) { Body = lambdaExpression, Source = parent, }; } else { Debug.Assert(queryTokenKind == QueryTokenKind.All, "LambdaQueryNodes must be Any or All only."); lambdaNode = new AllNode(new Collection <RangeVariable>(state.RangeVariables.ToList()), newRangeVariable) { Body = lambdaExpression, Source = parent, }; } return(lambdaNode); }
private void TestLambda <TLambda, TParam, TReturn>(CollectionNode source, string parameterName, SingleValueNode body, Expression <Func <TParam, TReturn> > expectedExpression) where TLambda : LambdaNode { ResourceRangeVariable currentRangeVariable = null; if (parameterName != null) { currentRangeVariable = new ResourceRangeVariable(parameterName, new EdmEntityTypeReference(this.customerEdmType, false), this.entitySet); this.testSubject.ParameterExpressions[currentRangeVariable] = Expression.Parameter(typeof(TParam), parameterName); } LambdaNode node; if (typeof(TLambda) == typeof(AnyNode)) { node = new AnyNode(new Collection <RangeVariable>(), currentRangeVariable); } else { node = new AllNode(new Collection <RangeVariable>(), currentRangeVariable); } node.Body = body; node.Source = source; var result = this.testSubject.TranslateNode(node); CompareExpressions(expectedExpression.Body, result); }
private string BindAnyNode(AnyNode anyNode, ICollection <BinderNode> nodes) { const string pattern = @"^\."; var rgx = new Regex(pattern); var source = rgx.Replace(Bind(anyNode.Source, nodes), String.Empty); string body = null; var innerQuery = "exists ( from " + source + " " + anyNode.RangeVariables.First().Name; if (anyNode.Body != null) { body = Bind(anyNode.Body, nodes); innerQuery += " where " + body; } nodes.Add(new BinderNode { Left = source, OperatorKind = BinaryOperatorKind.Equal, Right = body, }); return(innerQuery + ")"); }
private void FindKeyNodes() { for (int i = nodes.Count - 1; i > -1; i--) { if (nodes[i] == null) { nodes.RemoveAt(i); } } foreach (BaseNode node in nodes) { node.graph = this; if (node.NodeType == NodeType.Start) { startNode = (StartNode)node; } if (node.NodeType == NodeType.End) { endNode = (EndNode)node; } if (node.NodeType == NodeType.Any) { anyNode = (AnyNode)node; } } }
/// <summary> /// Override this method to restrict the 'any' query inside the filter query. /// </summary> /// <remarks> /// This method is intended to be called from method overrides in subclasses. This method also supports unit-testing scenarios and is not intended to be called from user code. /// Call the Validate method to validate a <see cref="FilterQueryOption"/> instance. /// </remarks> /// <param name="anyNode"></param> /// <param name="settings"></param> public virtual void ValidateAnyNode(AnyNode anyNode, ODataValidationSettings settings) { if (anyNode == null) { throw Error.ArgumentNull("anyNode"); } if (settings == null) { throw Error.ArgumentNull("settings"); } ValidateFunction("any", settings); EnterLambda(settings); try { ValidateQueryNode(anyNode.Source, settings); if (anyNode.Body != null && anyNode.Body.Kind != QueryNodeKind.Constant) { ValidateQueryNode(anyNode.Body, settings); } } finally { ExitLambda(); } }
private Node ParseFactor() { Node n; Token t = GetToken(); switch (t) { case Token.Byte: n = new ByteNode(this.b, positions.Count); positions.Add(n); AddCharacterClass(b); break; case Token.Dot: n = new AnyNode(positions.Count); positions.Add(n); break; case Token.LParen: n = Parse(); Expect(Token.RParen); break; default: return(SyntaxError()); } return(n); }
/// <summary> /// We return the <see cref="ResourceRangeVariableReferenceNode"/> within a <see cref="QueryNode"/> /// </summary> /// <param name="node">The node to extract the ResourceRangeVariableReferenceNode.</param> /// <returns>The extracted ResourceRangeVariableReferenceNode.</returns> private ResourceRangeVariableReferenceNode GetResourceRangeVariableReferenceNode(QueryNode node) { if (node == null) { return(null); } switch (node.Kind) { case QueryNodeKind.SingleValuePropertyAccess: SingleValuePropertyAccessNode singleValuePropertyAccessNode = node as SingleValuePropertyAccessNode; return(GetResourceRangeVariableReferenceNode(singleValuePropertyAccessNode.Source)); case QueryNodeKind.Convert: ConvertNode convertNode = node as ConvertNode; return(GetResourceRangeVariableReferenceNode(convertNode.Source)); case QueryNodeKind.Any: AnyNode anyNode = node as AnyNode; return(GetResourceRangeVariableReferenceNode(anyNode.Source)); case QueryNodeKind.SingleValueFunctionCall: SingleValueFunctionCallNode singleValueFunctionCallNode = node as SingleValueFunctionCallNode; return(GetResourceRangeVariableReferenceNode(singleValueFunctionCallNode.Parameters.First())); case QueryNodeKind.ResourceRangeVariableReference: return(node as ResourceRangeVariableReferenceNode); case QueryNodeKind.SingleValueOpenPropertyAccess: SingleValueOpenPropertyAccessNode singleValueOpenPropertyAccessNode = node as SingleValueOpenPropertyAccessNode; return(GetResourceRangeVariableReferenceNode(singleValueOpenPropertyAccessNode.Source)); case QueryNodeKind.SingleComplexNode: SingleComplexNode singleComplexNode = node as SingleComplexNode; return(GetResourceRangeVariableReferenceNode(singleComplexNode.Source)); case QueryNodeKind.CollectionComplexNode: CollectionComplexNode collectionComplexNode = node as CollectionComplexNode; return(GetResourceRangeVariableReferenceNode(collectionComplexNode.Source)); case QueryNodeKind.CollectionNavigationNode: CollectionNavigationNode collectionNavigationNode = node as CollectionNavigationNode; return(GetResourceRangeVariableReferenceNode(collectionNavigationNode.Source)); case QueryNodeKind.SingleNavigationNode: SingleNavigationNode singleNavigationNode = node as SingleNavigationNode; return(GetResourceRangeVariableReferenceNode(singleNavigationNode.Source)); case QueryNodeKind.CollectionResourceFunctionCall: CollectionResourceFunctionCallNode collectionResourceFunctionCallNode = node as CollectionResourceFunctionCallNode; return(GetResourceRangeVariableReferenceNode(collectionResourceFunctionCallNode.Source)); case QueryNodeKind.SingleResourceFunctionCall: SingleResourceFunctionCallNode singleResourceFunctionCallNode = node as SingleResourceFunctionCallNode; return(GetResourceRangeVariableReferenceNode(singleResourceFunctionCallNode.Source)); } return(null); }
/// <summary> /// Translates a V3 AnyNode to V4 AnyNode /// </summary> /// <param name="nodeIn">V3 AnyNode</param> /// <returns>V4 AnyNode</returns> public override QueryNode Visit(Data.OData.Query.SemanticAst.AnyNode nodeIn) { List<RangeVariable> translated = nodeIn.RangeVariables.Select(r => TranslateRangeVariable(r)).ToList(); AnyNode ret = new AnyNode(new Collection<RangeVariable>(translated), TranslateRangeVariable(nodeIn.CurrentRangeVariable)); ret.Source = (CollectionNode)nodeIn.Source.Accept(this); ret.Body = (SingleValueNode)nodeIn.Body.Accept(this); return ret; }
public override int Visit(AnyNode nodeIn) { var sourceNode = (CollectionNavigationNode)nodeIn.Source; int h1 = sourceNode.NavigationProperty.Name.GetHashCode(); int h2 = nameof(Enumerable.Any).GetHashCode(); int h3 = TranslateNode(nodeIn.Body); return(CombineHashCodes(h1, h2, h3)); }
public void TypeReferenceShouldBeBoolean() { EntityRangeVariable rangeVariable = (EntityRangeVariable)NodeFactory.CreateImplicitRangeVariable(HardCodedTestModel.GetDogTypeReference(), HardCodedTestModel.GetDogsSet()); Collection<RangeVariable> rangeVariables = new Collection<RangeVariable> { rangeVariable }; AnyNode anyNode = new AnyNode(rangeVariables, rangeVariable); anyNode.TypeReference.FullName().Should().Be("Edm.Boolean"); }
private void ValidateAnyNode(AnyNode node, ValidationSettings settings) { ValidateFunction("any", settings); ValidateQueryNode(node.Source, settings); if (node.Body != null && node.Body.Kind != QueryNodeKind.Constant) { ValidateQueryNode(node.Body, settings); } }
public void KindShouldBeAnyNode() { EntityRangeVariable rangeVariable = (EntityRangeVariable)NodeFactory.CreateImplicitRangeVariable(HardCodedTestModel.GetDogTypeReference(), HardCodedTestModel.GetDogsSet()); Collection<RangeVariable> rangeVariables = new Collection<RangeVariable> { rangeVariable }; AnyNode anyNode = new AnyNode(rangeVariables, rangeVariable); anyNode.InternalKind.Should().Be(InternalQueryNodeKind.Any); }
static string BindAnyNode(AnyNode anyNode, List <DbParameter> pars, DbUtility dbUtility) { string innerQuery = "exists ( from " + Bind(anyNode.Source, pars, dbUtility) + " " + anyNode.RangeVariables.First().Name; if (anyNode.Body != null) { innerQuery += " where " + Bind(anyNode.Body, pars, dbUtility); } return(innerQuery + ")"); }
private string BindAnyNode(AnyNode anyNode) { string innerQuery = "exists ( from " + Bind(anyNode.Source) + " " + anyNode.RangeVariables.First().Name; if (anyNode.Body != null) { innerQuery += " where " + Bind(anyNode.Body); } return(innerQuery + ")"); }
protected virtual QueryNode VisitAny(AnyNode node, AzureQueryOptimizerState state) { QueryNode queryNode1 = this.Visit(node.SourceNode, state); QueryNode queryNode2 = this.Visit(node.PredicateNode, state); if (queryNode2.NodeType == QueryNodeType.MatchAll) { return((QueryNode) new AnyNode(queryNode1, queryNode2)); } return((QueryNode) new AnyNode(this.VisitAnd(new AndNode(queryNode1, queryNode2), state), (QueryNode) new MatchAllNode())); }
public void TypeReferenceShouldBeBoolean() { ResourceRangeVariable rangeVariable = (ResourceRangeVariable)NodeFactory.CreateImplicitRangeVariable(HardCodedTestModel.GetDogTypeReference(), HardCodedTestModel.GetDogsSet()); Collection <RangeVariable> rangeVariables = new Collection <RangeVariable> { rangeVariable }; AnyNode anyNode = new AnyNode(rangeVariables, rangeVariable); Assert.Equal("Edm.Boolean", anyNode.TypeReference.FullName()); }
public void KindShouldBeAnyNode() { ResourceRangeVariable rangeVariable = (ResourceRangeVariable)NodeFactory.CreateImplicitRangeVariable(HardCodedTestModel.GetDogTypeReference(), HardCodedTestModel.GetDogsSet()); Collection <RangeVariable> rangeVariables = new Collection <RangeVariable> { rangeVariable }; AnyNode anyNode = new AnyNode(rangeVariables, rangeVariable); Assert.Equal(InternalQueryNodeKind.Any, anyNode.InternalKind); }
public void KindShouldBeAnyNode() { EntityRangeVariable rangeVariable = (EntityRangeVariable)NodeFactory.CreateImplicitRangeVariable(HardCodedTestModel.GetDogTypeReference(), HardCodedTestModel.GetDogsSet()); Collection <RangeVariable> rangeVariables = new Collection <RangeVariable> { rangeVariable }; AnyNode anyNode = new AnyNode(rangeVariables, rangeVariable); anyNode.InternalKind.Should().Be(InternalQueryNodeKind.Any); }
public void TypeReferenceShouldBeBoolean() { EntityRangeVariable rangeVariable = (EntityRangeVariable)NodeFactory.CreateImplicitRangeVariable(HardCodedTestModel.GetDogTypeReference(), HardCodedTestModel.GetDogsSet()); Collection <RangeVariable> rangeVariables = new Collection <RangeVariable> { rangeVariable }; AnyNode anyNode = new AnyNode(rangeVariables, rangeVariable); anyNode.TypeReference.FullName().Should().Be("Edm.Boolean"); }
/// <summary> /// Translates a <see cref="AnyNode"/> into a corresponding <see cref="string"/>. /// </summary> /// <param name="node">The node to translate.</param> /// <returns>The translated string.</returns> public override string Visit(AnyNode node) { if (node.CurrentRangeVariable == null && node.Body.Kind == QueryNodeKind.Constant) { return(string.Concat(this.TranslateNode(node.Source), Constants.SymbolForwardSlash, Constants.KeywordAny, Constants.SymbolOpenParen, Constants.SymbolClosedParen)); } else { return(string.Concat(this.TranslateNode(node.Source), Constants.SymbolForwardSlash, Constants.KeywordAny, Constants.SymbolOpenParen, node.CurrentRangeVariable.Name, ":", this.TranslateNode(node.Body), Constants.SymbolClosedParen)); } }
protected virtual QueryNode VisitAny(AnyNode node, ElasticSearchQueryOptimizerState state) { var node2 = Visit(node.SourceNode, state); var node3 = Visit(node.PredicateNode, state); if (node3.NodeType == QueryNodeType.MatchAll) { return(new AnyNode(node2, node3)); } return(new AnyNode(VisitAnd(new AndNode(node2, node3), state), new MatchAllNode())); }
/// <summary> /// Translates a <see cref="AnyNode"/> into a corresponding <see cref="string"/>. /// </summary> /// <param name="node">The node to translate.</param> /// <returns>The translated string.</returns> public override string Visit(AnyNode node) { //should return something like JOIN a in c.companies //if (node.CurrentRangeVariable == null && node.Body.Kind == QueryNodeKind.Constant) //{ // return string.Concat(Constants.Delimiter, this.TranslateNode(node.Source, true), Constants.SymbolForwardSlash, Constants.KeywordAny, Constants.SymbolOpenParen, Constants.SymbolClosedParen, Constants.Delimiter); //} //else //{ return(string.Concat(Constants.Delimiter, this.TranslateNode(node.Source, true), Constants.Delimiter, this.TranslateNode(node.Body))); //} }
/// <summary> /// in AnyNode: such as SkuBomParents/any(m: m eq 1363) /// anyNode.Source is SkuBomParents, which is a CollectionPropertyAccessNode. /// anyNode.Body is m eq 1363, which is a BinaryOperatorNode. /// For $filter=SkuBomParents/any(m: m eq 1363) /// it translates to /// 1 self join clause: join d0 in c.SkuBomParents /// the where clause: d0 = 1363 /// For $filter=BGs/any(m: m eq '640') and DCs/any(m: m eq 'ACT01') /// it translates to /// 2 self join clauses: /// join d0 in c.BGs /// join d1 in c.DCs /// and the where clause is (d0 = "640") and (d1="ACT01") /// For SkuChildren/any(m:m/dummy/any(n:n eq 'abc')) /// it translates to /// 2 self join clauses: /// join d0 in c.SkuChildren /// join d1 in d0.dummy /// and the where clause is ((d1 = "abc")) /// </summary> private string TranslateAnyNode(AnyNode anyNode) { var cnt = whereAndJoinClause.JoinClause.Count(); var rangeVariableName = string.Format("d{0}", cnt); var src = Translate(anyNode.Source); whereAndJoinClause.JoinClause.Add(string.Format("join {0} in {1}", rangeVariableName, src)); RangeVariablesNameForAnyNodeBody.Push(rangeVariableName); var res = Translate(anyNode.Body); RangeVariablesNameForAnyNodeBody.Pop(); return(res); }
/// <summary> /// Translates a <see cref="AnyNode"/> into a corresponding <see cref="String"/>. /// </summary> /// <param name="node">The node to translate.</param> /// <returns>The translated String.</returns> public override String Visit(AnyNode node) { ExceptionUtils.CheckArgumentNotNull(node, "node"); if (node.CurrentRangeVariable == null && node.Body.Kind == QueryNodeKind.Constant) { return(String.Concat(this.TranslateNode(node.Source), ExpressionConstants.SymbolForwardSlash, ExpressionConstants.KeywordAny, ExpressionConstants.SymbolOpenParen, ExpressionConstants.SymbolClosedParen)); } else { return(String.Concat(this.TranslateNode(node.Source), ExpressionConstants.SymbolForwardSlash, ExpressionConstants.KeywordAny, ExpressionConstants.SymbolOpenParen, node.CurrentRangeVariable.Name, ":", this.TranslateNode(node.Body), ExpressionConstants.SymbolClosedParen)); } }
public void RangeVariableShouldBeSetCorrectly() { EntityRangeVariable rangeVariable = (EntityRangeVariable) NodeFactory.CreateImplicitRangeVariable(HardCodedTestModel.GetDogTypeReference(), HardCodedTestModel.GetDogsSet()); Collection<RangeVariable> rangeVariables = new Collection<RangeVariable> { rangeVariable }; AnyNode anyNode = new AnyNode(rangeVariables, rangeVariable); anyNode.CurrentRangeVariable.Name.Should().Be(ExpressionConstants.It); anyNode.CurrentRangeVariable.Kind.Should().Be(RangeVariableKind.Entity); anyNode.CurrentRangeVariable.TypeReference.FullName().Should().Be(HardCodedTestModel.GetDogTypeReference().FullName()); }
/// <summary> /// Binds a <see cref="AnyNode"/> to create a LINQ <see cref="Expression"/> that /// represents the semantics of the <see cref="AnyNode"/>. /// </summary> /// <param name="anyNode">The node to bind.</param> /// <returns>The LINQ <see cref="Expression"/> created.</returns> public virtual Expression BindAnyNode(AnyNode anyNode) { if (anyNode == null) { throw Error.ArgumentNull(nameof(anyNode)); } ParameterExpression anyIt = HandleLambdaParameters(anyNode.RangeVariables); Expression source; Contract.Assert(anyNode.Source != null); source = Bind(anyNode.Source); Expression body = null; // uri parser places an Constant node with value true for empty any() body if (anyNode.Body != null && anyNode.Body.Kind != QueryNodeKind.Constant) { body = Bind(anyNode.Body); body = ApplyNullPropagationForFilterBody(body); body = Expression.Lambda(body, anyIt); } else if (anyNode.Body != null && anyNode.Body.Kind == QueryNodeKind.Constant && (bool)(anyNode.Body as ConstantNode).Value == false) { // any(false) is the same as just false ExitLamdbaScope(); return(FalseConstant); } Expression any = Any(source, body); ExitLamdbaScope(); if (QuerySettings.HandleNullPropagation == HandleNullPropagationOption.True && IsNullable(source.Type)) { // IFF(source == null) null; else Any(body); any = ToNullable(any); return(Expression.Condition( test: Expression.Equal(source, NullConstant), ifTrue: Expression.Constant(null, any.Type), ifFalse: any)); } else { return(any); } }
public void RangeVariableShouldBeSetCorrectly() { ResourceRangeVariable rangeVariable = (ResourceRangeVariable) NodeFactory.CreateImplicitRangeVariable(HardCodedTestModel.GetDogTypeReference(), HardCodedTestModel.GetDogsSet()); Collection <RangeVariable> rangeVariables = new Collection <RangeVariable> { rangeVariable }; AnyNode anyNode = new AnyNode(rangeVariables, rangeVariable); Assert.Equal(ExpressionConstants.It, anyNode.CurrentRangeVariable.Name); Assert.Equal(RangeVariableKind.Resource, anyNode.CurrentRangeVariable.Kind); Assert.Equal(HardCodedTestModel.GetDogTypeReference().FullName(), anyNode.CurrentRangeVariable.TypeReference.FullName()); }
public void TranslatorShouldRequireProtocolAndRequestVersionThreeForAnyAndAll() { ODataProtocolVersion validatedProtocolVersion = ODataProtocolVersion.V4; ODataProtocolVersion validatedRequestVersion = ODataProtocolVersion.V4; var withVersionCallbacks = this.CreateTestSubject(verifyProtocolVersion: v => { validatedProtocolVersion = v; }, verifyRequestVersion: v => { validatedRequestVersion = v; }); LambdaNode node = new AnyNode(new Collection <RangeVariable>(), null); node.Body = Constant(true); node.Source = this.CollectionNavigationFromParameter("o"); withVersionCallbacks.TranslateNode(node); validatedProtocolVersion.Should().Be(ODataProtocolVersion.V4); validatedRequestVersion.Should().Be(ODataProtocolVersion.V4); }
public void RangeVariableShouldBeSetCorrectly() { EntityRangeVariable rangeVariable = (EntityRangeVariable) NodeFactory.CreateImplicitRangeVariable(HardCodedTestModel.GetDogTypeReference(), HardCodedTestModel.GetDogsSet()); Collection <RangeVariable> rangeVariables = new Collection <RangeVariable> { rangeVariable }; AnyNode anyNode = new AnyNode(rangeVariables, rangeVariable); anyNode.CurrentRangeVariable.Name.Should().Be(ExpressionConstants.It); anyNode.CurrentRangeVariable.Kind.Should().Be(RangeVariableKind.Entity); anyNode.CurrentRangeVariable.TypeReference.FullName().Should().Be(HardCodedTestModel.GetDogTypeReference().FullName()); }
/// <summary> /// Translate an AnyNode. /// </summary> /// <param name="nodeIn">The node to be translated.</param> /// <returns>The translated node.</returns> public override QueryNode Visit(AnyNode nodeIn) { AnyNode anyNode = new AnyNode(nodeIn.RangeVariables, nodeIn.CurrentRangeVariable); if (nodeIn.Source != null) { anyNode.Source = (CollectionNode)nodeIn.Source.Accept(this); } if (nodeIn.Body != null) { anyNode.Body = (SingleValueNode)nodeIn.Body.Accept(this); } return(anyNode); }
public override QueryNode Visit(AnyNode nodeIn) { var body = (SingleValueNode)Visit(nodeIn.Body); CollectionNode?source = nodeIn.Source == null ? null : (CollectionNode)Visit(nodeIn.Source); if (nodeIn.Body != body || nodeIn.Source != source) { nodeIn = new AnyNode(nodeIn.RangeVariables, nodeIn.CurrentRangeVariable) { Body = body, Source = source } } ; return(nodeIn); }
public void RangeVariablesShouldBeSetCorrectly() { ResourceRangeVariable rangeVariable = (ResourceRangeVariable)NodeFactory.CreateImplicitRangeVariable(HardCodedTestModel.GetDogTypeReference(), HardCodedTestModel.GetDogsSet()); Collection <RangeVariable> rangeVariables = new Collection <RangeVariable> { rangeVariable }; AnyNode anyNode = new AnyNode(rangeVariables, rangeVariable); anyNode.RangeVariables.Count.Should().Be(1); anyNode.RangeVariables[0].Name.Should().Be(ExpressionConstants.It); anyNode.RangeVariables[0].Kind.Should().Be(RangeVariableKind.Resource); anyNode.RangeVariables[0].TypeReference.FullName().Should().Be(HardCodedTestModel.GetDogTypeReference().FullName()); ResourceRangeVariable returnedRangeVariable = (ResourceRangeVariable)anyNode.RangeVariables[0]; returnedRangeVariable.NavigationSource.Should().Be(HardCodedTestModel.GetDogsSet()); }
/// <summary> /// Override this method to restrict the 'any' query inside the filter query /// </summary> /// <param name="anyNode"></param> /// <param name="settings"></param> public virtual void ValidateAnyNode(AnyNode anyNode, ODataValidationSettings settings) { if (anyNode == null) { throw Error.ArgumentNull("anyNode"); } if (settings == null) { throw Error.ArgumentNull("settings"); } ValidateQueryNode(anyNode.Source, settings); if (anyNode.Body != null && anyNode.Body.Kind != QueryNodeKind.Constant) { ValidateQueryNode(anyNode.Body, settings); } }
/// <inheritdoc /> public override string Visit(AnyNode node) { if (node.CurrentRangeVariable == null && node.Body.Kind == QueryNodeKind.Constant) { return(string.Concat(TranslateNode(node.Source), Constants.SymbolForwardSlash, Constants.KeywordAny, Constants.SymbolOpenParen, Constants.SymbolClosedParen)); } else { var source = TranslateNode(node.Source); var body = TranslateNode(node.Body); var variableName = node.CurrentRangeVariable?.Name; var result = string.Concat(source, Constants.SymbolForwardSlash, Constants.KeywordAny, Constants.SymbolOpenParen, variableName, ":", body, Constants.SymbolClosedParen); return(result); } }
/// <summary> /// Writes any node to string. /// </summary> /// <param name="node">Node to write to string</param> /// <returns>String representation of node.</returns> private static string ToString(AnyNode node) { if (node != null) { return tabHelper.Prefix + "AnyNode" + tabHelper.Indent(() => { string text = tabHelper.Prefix + "TypeReference = " + node.TypeReference + tabHelper.Prefix + "Body = " + ToString(node.Body) + tabHelper.Prefix + "Source = " + ToString(node.Source) + tabHelper.Prefix + "Parameters = "; for (int i = 0; i < node.RangeVariables.Count(); ++i) { text += ToStringParameter(node.RangeVariables.ElementAt(i)); } return text; }); } return String.Empty; }
private static void BuildFilterWithNestedAny() { var personTypeRef = new EdmEntityTypeReference(TripPinModel.Person, false); var tripTypeRef = new EdmEntityTypeReference(TripPinModel.Trip, false); var friendsProp = (IEdmNavigationProperty)TripPinModel.Person.FindProperty("Friends"); var tripsProp = (IEdmNavigationProperty)TripPinModel.Person.FindProperty("Trips"); var budgetProp = TripPinModel.Trip.FindProperty("Budget"); var topIt = new EntityRangeVariable("$it", personTypeRef, TripPinModel.PeopleSet); var topItRef = new EntityRangeVariableReferenceNode("$it", topIt); var friendsNavNode0 = new CollectionNavigationNode(friendsProp, topItRef); var e0 = new EntityRangeVariable("e0", personTypeRef, friendsNavNode0); var e0Ref = new EntityRangeVariableReferenceNode("e0", e0); var friendsNavNode1 = new CollectionNavigationNode(friendsProp, e0Ref); var e1 = new EntityRangeVariable("e1", personTypeRef, friendsNavNode1); var e1Ref = new EntityRangeVariableReferenceNode("e1", e1); var tripNavNode = new CollectionNavigationNode(tripsProp, e1Ref); var e2 = new EntityRangeVariable("e2", tripTypeRef, friendsNavNode1); var e2Ref = new EntityRangeVariableReferenceNode("e2", e2); var bugetNode = new SingleValuePropertyAccessNode(e2Ref, budgetProp); var gt = new BinaryOperatorNode( BinaryOperatorKind.GreaterThan, bugetNode, new ConstantNode(1200, "1200")); var any2 = new AnyNode(new Collection<RangeVariable> { e2 }, e2) { Body = gt, Source = tripNavNode }; var any1 = new AnyNode(new Collection<RangeVariable> { e1 }, e1) { Body = any2, Source = friendsNavNode1 }; var any0 = new AnyNode(new Collection<RangeVariable> { e0 }, e0) { Body = any1, Source = friendsNavNode0 }; var odataUri = new ODataUri { Path = new ODataPath(new EntitySetSegment(TripPinModel.PeopleSet)), ServiceRoot = TripPinRoot, Filter = new FilterClause(any0, topIt) }; var builder = new ODataUriBuilder(ODataUrlConventions.Default, odataUri); Console.WriteLine(builder.BuildUri()); // http://services.odata.org/V4/TripPinService/People?$filter=Friends%2Fany(e0:e0%2FFriends%2Fany(e1:e1%2FTrips%2Fany(e2:e2%2FBudget gt 1200))) }
private string BindAnyNode(AnyNode anyNode) { string innerQuery = "exists ( from " + Bind(anyNode.Source) + " " + anyNode.RangeVariables.First().Name; if (anyNode.Body != null) { innerQuery += " where " + Bind(anyNode.Body); } return innerQuery + ")"; }
private static void BuildFilterWithBinaryOperator() { var personTypeRef = new EdmEntityTypeReference(TripPinModel.Person, false); var friendsProp = (IEdmNavigationProperty)TripPinModel.Person.FindProperty("Friends"); var firstNameProp = TripPinModel.Person.FindProperty("FirstName"); var lastNameProp = TripPinModel.Person.FindProperty("LastName"); var topIt = new EntityRangeVariable("$it", personTypeRef, TripPinModel.PeopleSet); var topItRef = new EntityRangeVariableReferenceNode("$it", topIt); var friendsNavNode = new CollectionNavigationNode(friendsProp, topItRef); var e0 = new EntityRangeVariable("e0", personTypeRef, friendsNavNode); var e0Ref = new EntityRangeVariableReferenceNode("e0", e0); var fun1 = new SingleValueFunctionCallNode( "startswith", new QueryNode[] { new SingleValuePropertyAccessNode(e0Ref, firstNameProp), new ConstantNode("var1", "'var1'") }, EdmCoreModel.Instance.GetBoolean(false)); var friendsNavNode2 = new CollectionNavigationNode(friendsProp, e0Ref); var e1 = new EntityRangeVariable("e1", personTypeRef, friendsNavNode2); var e1Ref = new EntityRangeVariableReferenceNode("e1", e1); var fun2 = new SingleValueFunctionCallNode( "contains", new QueryNode[] { new SingleValuePropertyAccessNode(e1Ref, lastNameProp), new ConstantNode("var2", "'var2'") }, EdmCoreModel.Instance.GetBoolean(false)); // Actually $it also needed, but would not be used in UriBuilder, so omit it here. var any2 = new AnyNode(new Collection<RangeVariable> { e1 }, e1) { Body = fun2, Source = friendsNavNode2 }; var any1 = new AnyNode(new Collection<RangeVariable> { e0 }, e0) { Body = new BinaryOperatorNode(BinaryOperatorKind.And, fun1, any2), Source = friendsNavNode }; var odataUri = new ODataUri { Path = new ODataPath(new EntitySetSegment(TripPinModel.PeopleSet)), ServiceRoot = TripPinRoot, Filter = new FilterClause(any1, topIt) }; var builder = new ODataUriBuilder(ODataUrlConventions.Default, odataUri); Console.WriteLine(builder.BuildUri()); // http://services.odata.org/V4/TripPinService/People?$filter=Friends%2Fany( // e0:startswith(e0%2FFirstName%2C'var1') and e0%2FFriends%2Fany(e1:contains(e1%2FLastName%2C'var2'))) }
/// <summary> /// Compares any query nodes. /// </summary> /// <param name="left">Left side of comparison</param> /// <param name="right">Right side of comparison</param> /// <returns>True if equal, otherwise false</returns> private bool Compare(AnyNode left, AnyNode right) { if (left.TypeReference != right.TypeReference) return false; if (!this.Compare(left.Body, right.Body)) return false; if (left.RangeVariables.Count() != right.RangeVariables.Count()) return false; for (int i = 0; i < left.RangeVariables.Count(); ++i) { if (!this.CompareParameters(left.RangeVariables.ElementAt(i), right.RangeVariables.ElementAt(i))) return false; } return this.Compare(left.Source, right.Source); }
internal void AddAny(XmlSchemaAny any) { ContentNode n = new AnyNode(any); if (stack.Count > 0) { InternalNode inNode = (InternalNode)stack.Pop(); if (inNode != null) { inNode.RightNode = n; n.ParentNode = inNode; n = inNode; } } stack.Push( n ); isPartial = true; abnormalContent = true; }
public override void ValidateAnyNode(AnyNode anyQueryNode, ODataValidationSettings settings) { IncrementCount("ValidateAnyQueryNode"); base.ValidateAnyNode(anyQueryNode, settings); }
/// <summary> /// Creates an AnyNode or an AllNode from the given /// </summary> /// <param name="state">State of binding.</param> /// <param name="parent">Parent node to the lambda.</param> /// <param name="lambdaExpression">Bound Lambda expression.</param> /// <param name="newRangeVariable">The new range variable being added by this lambda node.</param> /// <param name="queryTokenKind">Token kind.</param> /// <returns>A new LambdaNode bound to metadata.</returns> internal static LambdaNode CreateLambdaNode( BindingState state, CollectionNode parent, SingleValueNode lambdaExpression, RangeVariable newRangeVariable, QueryTokenKind queryTokenKind) { LambdaNode lambdaNode; if (queryTokenKind == QueryTokenKind.Any) { lambdaNode = new AnyNode(new Collection<RangeVariable>(state.RangeVariables.ToList()), newRangeVariable) { Body = lambdaExpression, Source = parent, }; } else { Debug.Assert(queryTokenKind == QueryTokenKind.All, "LambdaQueryNodes must be Any or All only."); lambdaNode = new AllNode(new Collection<RangeVariable>(state.RangeVariables.ToList()), newRangeVariable) { Body = lambdaExpression, Source = parent, }; } return lambdaNode; }
void ParseInternal() { this.mainBlock = new BlockNode(null); this.stack = new Stack<BlockNode>(); this.errors = new List<TemplateError>(); PushBlock(mainBlock); var matches = TemplateUtils.KeywordsRegex.Matches(text); if (matches.Count == 0) { stack.Peek().Nodes.Add(new LiteralNode { Text = text }); stack.Pop(); return; } int index = 0; foreach (Match match in matches) { if (index < match.Index) { stack.Peek().Nodes.Add(new LiteralNode { Text = text.Substring(index, match.Index - index) }); } var type = match.Groups["type"].Value; var token = match.Groups["token"].Value; var keyword = match.Groups["keyword"].Value; var dec = match.Groups["dec"].Value; switch (keyword) { case "": case "raw": var tok = TemplateUtils.TokenFormatRegex.Match(token); if (!tok.Success) AddError(true, "{0} has invalid format".FormatWith(token)); else { var t = TryParseValueProvider(type, tok.Groups["token"].Value, dec); stack.Peek().Nodes.Add(new ValueNode(t, tok.Groups["format"].Value.DefaultText(null), isRaw: keyword.Contains("raw"))); DeclareVariable(t); } break; case "declare": { var t = TryParseValueProvider(type, token, dec); stack.Peek().Nodes.Add(new DeclareNode(t, this.AddError)); DeclareVariable(t); } break; case "any": { AnyNode any; ValueProviderBase vp; var filter = TemplateUtils.TokenOperationValueRegex.Match(token); if (!filter.Success) { vp = TryParseValueProvider(type, token, dec); any = new AnyNode(vp); } else { vp = TryParseValueProvider(type, filter.Groups["token"].Value, dec); var comparer = filter.Groups["comparer"].Value; var value = filter.Groups["value"].Value; any = new AnyNode(vp, comparer, value, this.AddError); } stack.Peek().Nodes.Add(any); PushBlock(any.AnyBlock); DeclareVariable(vp); break; } case "notany": { var an = (AnyNode)PopBlock(typeof(AnyNode)).owner; if (an != null) PushBlock(an.CreateNotAny()); break; } case "endany": { PopBlock(typeof(AnyNode)); break; } case "foreach": { ValueProviderBase vp = TryParseValueProvider(type, token, dec); var fn = new ForeachNode(vp); stack.Peek().Nodes.Add(fn); PushBlock(fn.Block); vp.IsForeach = true; DeclareVariable(vp); break; } case "endforeach": { PopBlock(typeof(ForeachNode)); } break; case "if": { IfNode ifn; ValueProviderBase vp; var filter = TemplateUtils.TokenOperationValueRegex.Match(token); if (!filter.Success) { vp = TryParseValueProvider(type, token, dec); ifn = new IfNode(vp, this); } else { vp = TryParseValueProvider(type, filter.Groups["token"].Value, dec); var comparer = filter.Groups["comparer"].Value; var value = filter.Groups["value"].Value; ifn = new IfNode(vp, comparer, value, this.AddError); } stack.Peek().Nodes.Add(ifn); PushBlock(ifn.IfBlock); DeclareVariable(vp); break; } case "else": { var ifn = (IfNode)PopBlock(typeof(IfNode)).owner; if (ifn != null) PushBlock(ifn.CreateElse()); break; } case "endif": { PopBlock(typeof(IfNode)); break; } default : AddError(true, "'{0}' is deprecated".FormatWith(keyword)); break; } index = match.Index + match.Length; } if (stack.Count != 1) AddError(true, "Last block is not closed: {0}".FormatWith(stack.Peek())); var lastM = matches.Cast<Match>().LastOrDefault(); if (lastM != null && lastM.Index + lastM.Length < text.Length) stack.Peek().Nodes.Add(new LiteralNode { Text = text.Substring(lastM.Index + lastM.Length) }); stack.Pop(); }
private Node ParseFactor() { Node n; Token t = GetToken(); switch (t) { case Token.Byte: n = new ByteNode(this.b, positions.Count); positions.Add(n); AddCharacterClass(b); break; case Token.Dot: n = new AnyNode(positions.Count); positions.Add(n); break; case Token.LParen: n = Parse(); Expect(Token.RParen); break; default: return SyntaxError(); } return n; }