internal void CompileForInternal(string xpath, XmlNamespaceManager names)
 {
     base.query = null;
     xpath      = xpath.Trim();
     if (xpath.Length == 0)
     {
         base.query  = matchAlwaysFilter;
         this.flags |= XPathFilterFlags.AlwaysMatch;
     }
     else if ((1 == xpath.Length) && ('/' == xpath[0]))
     {
         base.query  = rootFilter.First;
         this.flags |= XPathFilterFlags.AlwaysMatch;
     }
     else
     {
         ValueDataType type;
         OpcodeBlock   block = QueryMatcher.CompileForInternalEngine(xpath, names, QueryCompilerFlags.None, out type);
         if (this.match)
         {
             block.Append(new MatchResultOpcode());
         }
         else
         {
             block.Append(new QueryResultOpcode());
         }
         base.query = block.First;
     }
     this.flags &= ~XPathFilterFlags.IsFxFilter;
 }
        static XPathQueryMatcher()
        {
            ValueDataType type;

            matchAlwaysFilter = new PushBooleanOpcode(true);
            rootFilter        = QueryMatcher.CompileForInternalEngine("/", null, QueryCompilerFlags.None, out type);
            rootFilter.Append(new MatchResultOpcode());
        }
Example #3
0
        internal void Add(string expression, XmlNamespaceManager names, object item, bool forceExternal)
        {
            Fx.Assert(null != item, "");

            // Compile the new filter

            bool        compiled  = false;
            OpcodeBlock codeBlock = new OpcodeBlock();

            codeBlock.Append(new NoOpOpcode(OpcodeID.QueryTree));
            if (!forceExternal)
            {
                try
                {
                    ValueDataType returnType = ValueDataType.None;

                    // Try to compile and merge the compiled query into the query tree
                    codeBlock.Append(QueryMatcher.CompileForInternalEngine(expression, names, QueryCompilerFlags.InverseQuery, out returnType));

                    MultipleResultOpcode opcode;

                    if (!this.match)
                    {
                        opcode = new QueryMultipleResultOpcode();
                    }
                    else
                    {
                        opcode = new MatchMultipleResultOpcode();
                    }

                    opcode.AddItem(item);
                    codeBlock.Append(opcode);
                    compiled = true;

                    // Perform SubExpression Elimination
                    codeBlock        = new OpcodeBlock(this.elim.Add(item, codeBlock.First));
                    this.subExprVars = this.elim.VariableCount;
                }
                catch (QueryCompileException)
                {
                    // If the filter couldn't be compiled, we drop down to the framework engine
                }
            }

            if (!compiled)
            {
                codeBlock.Append(QueryMatcher.CompileForExternalEngine(expression, names, item, this.match));
            }

            // Merge the compiled query into the query tree
            QueryTreeBuilder builder = new QueryTreeBuilder();

            this.query = builder.Build(this.query, codeBlock);
            // To de-merge this filter from the tree, we'll have to walk backwards up the tree... so we
            // have to remember the last opcode that is executed on behalf of this filter
            this.lastLookup[item] = builder.LastOpcode;
        }
        internal void Add(string expression, XmlNamespaceManager names, object item, bool forceExternal)
        {
            bool        flag     = false;
            OpcodeBlock newBlock = new OpcodeBlock();

            newBlock.Append(new NoOpOpcode(OpcodeID.QueryTree));
            if (!forceExternal)
            {
                try
                {
                    MultipleResultOpcode opcode;
                    ValueDataType        none = ValueDataType.None;
                    newBlock.Append(QueryMatcher.CompileForInternalEngine(expression, names, QueryCompilerFlags.InverseQuery, out none));
                    if (!this.match)
                    {
                        opcode = new QueryMultipleResultOpcode();
                    }
                    else
                    {
                        opcode = new MatchMultipleResultOpcode();
                    }
                    opcode.AddItem(item);
                    newBlock.Append(opcode);
                    flag             = true;
                    newBlock         = new OpcodeBlock(this.elim.Add(item, newBlock.First));
                    base.subExprVars = this.elim.VariableCount;
                }
                catch (QueryCompileException)
                {
                }
            }
            if (!flag)
            {
                newBlock.Append(QueryMatcher.CompileForExternalEngine(expression, names, item, this.match));
            }
            QueryTreeBuilder builder = new QueryTreeBuilder();

            base.query            = builder.Build(base.query, newBlock);
            this.lastLookup[item] = builder.LastOpcode;
        }
Example #5
0
        /// <summary>
        /// Compile for the internal engine with default flags
        /// By defalt, we compile an xpath to run stand alone, with standard optimizations
        /// </summary>
        internal void CompileForInternal(string xpath, XmlNamespaceManager names)
        {
            this.query = null;
            xpath      = xpath.Trim();

            if (0 == xpath.Length)
            {
                // Empty xpaths always match. Same for xpaths that refer to the root only
                // We will evaluate such filters with minimal overhead. However, we
                // don't want a null value for this.query, so we stick a dummy value in there
                this.query  = XPathQueryMatcher.matchAlwaysFilter;
                this.flags |= (XPathFilterFlags.AlwaysMatch);
            }
            else if (1 == xpath.Length && '/' == xpath[0])
            {
                this.query  = XPathQueryMatcher.rootFilter.First;
                this.flags |= (XPathFilterFlags.AlwaysMatch);
            }
            else
            {
                ValueDataType returnType;
                OpcodeBlock   codeBlock = QueryMatcher.CompileForInternalEngine(xpath, names, QueryCompilerFlags.None, out returnType);
                // Inject a final opcode that will place the query result on the query context
                // This query is now ready for execution STAND ALONE
                if (this.match)
                {
                    codeBlock.Append(new MatchResultOpcode());
                }
                else
                {
                    codeBlock.Append(new QueryResultOpcode());
                }

                this.query = codeBlock.First;
            }

            this.flags &= ~XPathFilterFlags.IsFxFilter;
        }
Example #6
0
 internal static OpcodeBlock CompileForInternalEngine(string xpath, XmlNamespaceManager ns, QueryCompilerFlags flags, out ValueDataType returnType)
 {
     return(QueryMatcher.CompileForInternalEngine(xpath, ns, flags, QueryMatcher.defaultFunctionLibs, out returnType));
 }
Example #7
0
 /// <summary>
 /// Compile the given filter for evaluation using the internal engine.
 /// </summary>
 /// <param name="flags">Caller customizes optimizations via the flags parameter</param>
 /// <param name="returnType">Every xpath expression has a return type</param>
 /// <returns>The opcode block we execute to evaluate</returns>
 internal static OpcodeBlock CompileForInternalEngine(XPathMessageFilter filter, QueryCompilerFlags flags, IFunctionLibrary[] functionLibs, out ValueDataType returnType)
 {
     return(QueryMatcher.CompileForInternalEngine(filter.XPath.Trim(), filter.namespaces, flags, functionLibs, out returnType));
 }