Beispiel #1
0
 private LogicalExpr(LogicalExpr other)
     : base(other)
 {
     this.op = other.op;
     this.opnd1 = Clone(other.opnd1);
     this.opnd2 = Clone(other.opnd2);
 }
Beispiel #2
0
        protected override object MatchLogicalExpr(LogicalExpr expr)
        {
            Resolve(expr.Left);
            Resolve(expr.Right);

            return(null);
        }
Beispiel #3
0
        private Expr And()
        {
            var expr = Equality();

            while (Match(TokenType.And))
            {
                var op    = Previous();
                var right = Equality();
                expr = new LogicalExpr(expr, op, right);
            }

            return(expr);
        }
Beispiel #4
0
        private Expr Or()
        {
            var expr = And();

            while (Match(TokenType.Or))
            {
                var op    = Previous();
                var right = And();
                expr = new LogicalExpr(expr, op, right);
            }

            return(expr);
        }
Beispiel #5
0
        private Query ProcessFilter(Filter root, Flags flags, out Props props)
        {
            bool first = ((flags & Flags.Filter) == 0);

            Props propsCond;
            Query cond = ProcessNode(root.Condition, Flags.None, out propsCond);

            if (
                CanBeNumber(cond) ||
                (propsCond & (Props.HasPosition | Props.HasLast)) != 0
            )
            {
                propsCond |= Props.HasPosition;
                flags |= Flags.PosFilter;
            }

            // We don't want DescendantOverDescendant pattern to be recognized here (in case descendent::foo[expr]/descendant::bar)
            // So we clean this flag here:
            flags &= ~Flags.SmartDesc;
            // ToDo: Instead it would be nice to wrap descendent::foo[expr] into special query that will flatten it -- i.e.
            //       remove all nodes that are descendant of other nodes. This is very easy because for sorted nodesets all children 
            //       follow its parent. One step caching. This can be easily done by rightmost DescendantQuery itself.
            //       Interesting note! Can we guarantee that DescendantOverDescendant returns flat nodeset? This definitely true if it's input is flat.

            Query qyInput = ProcessNode(root.Input, flags | Flags.Filter, out props);

            if (root.Input.Type != AstNode.AstType.Filter)
            {
                // Props.PosFilter is for nested filters only. 
                // We clean it here to avoid cleaning it in all other ast nodes.
                props &= ~Props.PosFilter;
            }
            if ((propsCond & Props.HasPosition) != 0)
            {
                // this condition is positional rightmost filter should be avare of this.
                props |= Props.PosFilter;
            }

            /*merging predicates*/
            {
                FilterQuery qyFilter = qyInput as FilterQuery;
                if (qyFilter != null && (propsCond & Props.HasPosition) == 0 && qyFilter.Condition.StaticType != XPathResultType.Any)
                {
                    Query prevCond = qyFilter.Condition;
                    if (prevCond.StaticType == XPathResultType.Number)
                    {
                        prevCond = new LogicalExpr(Operator.Op.EQ, new NodeFunctions(FT.FuncPosition, null), prevCond);
                    }
                    cond = new BooleanExpr(Operator.Op.AND, prevCond, cond);
                    qyInput = qyFilter.qyInput;
                }
            }

            if ((props & Props.PosFilter) != 0 && qyInput is DocumentOrderQuery)
            {
                qyInput = ((DocumentOrderQuery)qyInput).input;
            }
            if (_firstInput == null)
            {
                _firstInput = qyInput as BaseAxisQuery;
            }

            bool merge = (qyInput.Properties & QueryProps.Merge) != 0;
            bool reverse = (qyInput.Properties & QueryProps.Reverse) != 0;
            if ((propsCond & Props.HasPosition) != 0)
            {
                if (reverse)
                {
                    qyInput = new ReversePositionQuery(qyInput);
                }
                else if ((propsCond & Props.HasLast) != 0)
                {
                    qyInput = new ForwardPositionQuery(qyInput);
                }
            }

            if (first && _firstInput != null)
            {
                if (merge && (props & Props.PosFilter) != 0)
                {
                    qyInput = new FilterQuery(qyInput, cond, /*noPosition:*/false);
                    Query parent = _firstInput.qyInput;
                    if (!(parent is ContextQuery))
                    { // we don't need to wrap filter with MergeFilterQuery when cardinality is parent <: ?
                        _firstInput.qyInput = new ContextQuery();
                        _firstInput = null;
                        return new MergeFilterQuery(parent, qyInput);
                    }
                    _firstInput = null;
                    return qyInput;
                }
                _firstInput = null;
            }
            return new FilterQuery(qyInput, cond, /*noPosition:*/(propsCond & Props.HasPosition) == 0);
        }
Beispiel #6
0
 protected abstract object MatchLogicalExpr(LogicalExpr logicalExpr);
Beispiel #7
0
 private LogicalExpr(LogicalExpr other) : base(other)
 {
     _op = other._op;
     _opnd1 = Clone(other._opnd1);
     _opnd2 = Clone(other._opnd2);
 }
        private Query ProcessFilter(Filter root, Flags flags, out Props props) {
            bool first = ((flags & Flags.Filter) == 0);

            Props propsCond;
            Query cond = ProcessNode(root.Condition, Flags.None, out propsCond);

            if (
                CanBeNumber(cond) ||
                (propsCond & (Props.HasPosition | Props.HasLast)) != 0
            ) {
                propsCond |= Props.HasPosition;
                flags |= Flags.PosFilter;
            }

            // We don't want DescendantOverDescendant pattern to be recognized here (in case descendent::foo[expr]/descendant::bar)
            // So we clean this flag here:
            flags &= ~Flags.SmartDesc;

            Query qyInput = ProcessNode(root.Input, flags | Flags.Filter, out props);

            if (root.Input.Type != AstNode.AstType.Filter) {
                // Props.PosFilter is for nested filters only. 
                // We clean it here to avoid cleaning it in all other ast nodes.
                props &= ~Props.PosFilter; 
            }
            if ((propsCond & Props.HasPosition) != 0) {
                // this condition is positional rightmost filter should be avare of this.
                props |= Props.PosFilter;
            }

            /*merging predicates*/ {
                FilterQuery qyFilter = qyInput as FilterQuery;
                if (qyFilter != null && (propsCond & Props.HasPosition) == 0 && qyFilter.Condition.StaticType != XPathResultType.Any) {
                    Query prevCond = qyFilter.Condition;
                    if (prevCond.StaticType == XPathResultType.Number) {
                        prevCond = new LogicalExpr(Operator.Op.EQ, new NodeFunctions(FT.FuncPosition, null), prevCond);
                    }
                    cond = new BooleanExpr(Operator.Op.AND, prevCond, cond);
                    qyInput = qyFilter.qyInput;
                }
            }

            if ((props & Props.PosFilter) != 0 && qyInput is DocumentOrderQuery) {
                qyInput = ((DocumentOrderQuery)qyInput).input;
            }
            if (firstInput == null) {
                firstInput = qyInput as BaseAxisQuery;
            }
            
            bool merge   = (qyInput.Properties & QueryProps.Merge  ) != 0;
            bool reverse = (qyInput.Properties & QueryProps.Reverse) != 0;
            if ((propsCond & Props.HasPosition) != 0) {
                if (reverse) {
                    qyInput = new ReversePositionQuery(qyInput);
                } else if ((propsCond & Props.HasLast) != 0) {
                    qyInput = new ForwardPositionQuery(qyInput); 
                }
            }

            if (first && firstInput != null) {
                if (merge && (props & Props.PosFilter) != 0) {
                    qyInput = new FilterQuery(qyInput, cond, /*noPosition:*/false);
                    Query parent = firstInput.qyInput;
                    if (! (parent is ContextQuery)) { // we don't need to wrap filter with MergeFilterQuery when cardinality is parent <: ?
                        firstInput.qyInput = new ContextQuery();
                        firstInput = null;
                        return new MergeFilterQuery(parent, qyInput);
                    }
                    firstInput = null;
                    return qyInput;
                }
                firstInput = null;
            }
            return new FilterQuery(qyInput, cond, /*noPosition:*/(propsCond & Props.HasPosition) == 0);
        }
 private Query ProcessFilter(MS.Internal.Xml.XPath.Filter root, Flags flags, out Props props)
 {
     Props props2;
     bool flag = (flags & Flags.Filter) == Flags.None;
     Query q = this.ProcessNode(root.Condition, Flags.None, out props2);
     if (this.CanBeNumber(q) || ((props2 & (Props.HasLast | Props.HasPosition)) != Props.None))
     {
         props2 |= Props.HasPosition;
         flags |= Flags.PosFilter;
     }
     flags &= ~Flags.SmartDesc;
     Query input = this.ProcessNode(root.Input, flags | Flags.Filter, out props);
     if (root.Input.Type != AstNode.AstType.Filter)
     {
         props &= ~Props.PosFilter;
     }
     if ((props2 & Props.HasPosition) != Props.None)
     {
         props |= Props.PosFilter;
     }
     FilterQuery query3 = input as FilterQuery;
     if (((query3 != null) && ((props2 & Props.HasPosition) == Props.None)) && (query3.Condition.StaticType != XPathResultType.Any))
     {
         Query condition = query3.Condition;
         if (condition.StaticType == XPathResultType.Number)
         {
             condition = new LogicalExpr(Operator.Op.EQ, new NodeFunctions(Function.FunctionType.FuncPosition, null), condition);
         }
         q = new BooleanExpr(Operator.Op.AND, condition, q);
         input = query3.qyInput;
     }
     if (((props & Props.PosFilter) != Props.None) && (input is DocumentOrderQuery))
     {
         input = ((DocumentOrderQuery) input).input;
     }
     if (this.firstInput == null)
     {
         this.firstInput = input as BaseAxisQuery;
     }
     bool flag2 = (input.Properties & QueryProps.Merge) != QueryProps.None;
     bool flag3 = (input.Properties & QueryProps.Reverse) != QueryProps.None;
     if ((props2 & Props.HasPosition) != Props.None)
     {
         if (flag3)
         {
             input = new ReversePositionQuery(input);
         }
         else if ((props2 & Props.HasLast) != Props.None)
         {
             input = new ForwardPositionQuery(input);
         }
     }
     if (flag && (this.firstInput != null))
     {
         if (flag2 && ((props & Props.PosFilter) != Props.None))
         {
             input = new FilterQuery(input, q, false);
             Query qyInput = this.firstInput.qyInput;
             if (!(qyInput is ContextQuery))
             {
                 this.firstInput.qyInput = new ContextQuery();
                 this.firstInput = null;
                 return new MergeFilterQuery(qyInput, input);
             }
             this.firstInput = null;
             return input;
         }
         this.firstInput = null;
     }
     return new FilterQuery(input, q, (props2 & Props.HasPosition) == Props.None);
 }
Beispiel #10
0
 public virtual void Visit(LogicalExpr expr)
 {
 }
Beispiel #11
0
 public override void Visit(LogicalExpr expr)
 {
     expr.left.Accept(this);
     expr.right.Accept(this);
 }
Beispiel #12
0
 public override void Visit(LogicalExpr expr)
 {
     expr.left.Accept(this);
     AddStr(" " + expr.op.lexeme + " ");
     expr.right.Accept(this);
 }