示例#1
0
        //  ----------------------------------------------------------------------------

        public XPathBuilder(IXPathEnvironment environment)
        {
            _environment       = environment;
            _f                 = _environment.Factory;
            this.fixupCurrent  = _f.Unknown(T.NodeNotRtf);
            this.fixupPosition = _f.Unknown(T.DoubleX);
            this.fixupLast     = _f.Unknown(T.DoubleX);
            _fixupVisitor      = new FixupVisitor(_f, fixupCurrent, fixupPosition, fixupLast);
        }
示例#2
0
        //also used by XPathPatternBuilder
        public static QilNode BuildOnePredicate(QilNode nodeset, QilNode predicate, bool isReverseStep,
                                                XPathQilFactory f, FixupVisitor fixupVisitor,
                                                ref int numFixupCurrent, ref int numFixupPosition, ref int numFixupLast)
        {
            nodeset = f.EnsureNodeSet(nodeset);

            // Mirgeing nodeset and predicate:
            // 1. Predicate contains 0 last() :
            //      for $i in nodeset
            //      where predicate
            //      return $i
            //   Note: Currently we are keepeing old output to minimize diff.
            // 2. Predicate contains 1 last()
            //      let $cach := nodeset return
            //          for $i in $cach
            //          where predicate(length($cach))
            //          return $i
            //   Suggestion: This is a little optimisation we can do or don't do.
            // 3. Predicate contains 2+ last()
            //      let $cash := nodeset return
            //          let $size := length($cash) return
            //              for $i in $cash
            //              where predicate($size)
            //              return $i

            QilNode result;

            if (numFixupLast != 0 && fixupVisitor.CountUnfixedLast(predicate) != 0)
            {
                // this subtree has unfixed last() nodes
                QilIterator cash = f.Let(nodeset);
                QilIterator size = f.Let(f.XsltConvert(f.Length(cash), T.DoubleX));
                QilIterator it   = f.For(cash);
                predicate         = fixupVisitor.Fixup(predicate, /*current:*/ it, /*last:*/ size);
                numFixupCurrent  -= fixupVisitor.numCurrent;
                numFixupPosition -= fixupVisitor.numPosition;
                numFixupLast     -= fixupVisitor.numLast;
                result            = f.Loop(cash, f.Loop(size, f.Filter(it, predicate)));
            }
            else
            {
                QilIterator it = f.For(nodeset);
                predicate         = fixupVisitor.Fixup(predicate, /*current:*/ it, /*last:*/ null);
                numFixupCurrent  -= fixupVisitor.numCurrent;
                numFixupPosition -= fixupVisitor.numPosition;
                numFixupLast     -= fixupVisitor.numLast;
                result            = f.Filter(it, predicate);
            }
            if (isReverseStep)
            {
                result = f.DocOrderDistinct(result);
            }
            return(result);
        }
        /// <summary>
        /// Костыль для запросов по интерфейсу. Просто вызвать метод.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="q"></param>
        /// <returns></returns>
        public static IQueryable <T> Fix <T>(this IQueryable <T> q)
        {
            var visitor = new FixupVisitor();

            return(q.Provider.CreateQuery <T>(visitor.Visit(q.Expression)));
        }