Ejemplo n.º 1
0
        // locate subqueries or SRF in given expr and create plan for each
        // subquery, no change on the expr itself.
        //
        LogicNode setReturningExprCreatePlan(LogicNode root, Expr expr)
        {
            var newroot  = root;
            var subplans = new List <NamedQuery>();

            expr.VisitEachT <Expr>(e =>
            {
                if (e is SubqueryExpr x)
                {
                    Debug.Assert(expr.HasSubQuery());
                    x.query_.CreatePlan();
                    subplans.Add(new NamedQuery(x.query_, null));

                    // functionally we don't have to do rewrite since above
                    // plan is already runnable
                    if (queryOpt_.optimize_.enable_subquery_unnest_)
                    {
                        // use the plan 'root' containing the subexpr 'x'
                        var replacement = oneSubqueryToJoin(root, x);
                        newroot         = (LogicNode)newroot.SearchAndReplace(root,
                                                                              replacement);
                    }
                }
                else if (e is FuncExpr f && f.isSRF_)
                {
                    var newchild      = new LogicProjectSet(root.child_());
                    root.children_[0] = newchild;
                }
            });

            subQueries_.AddRange(subplans);
            return(newroot);
        }
Ejemplo n.º 2
0
        // locate subqueries or SRF in given expr and create plan for each
        // subquery, no change on the expr itself.
        //
        LogicNode setReturningExprCreatePlan(LogicNode root, Expr expr)
        {
            var newroot  = root;
            var subplans = new List <NamedQuery>();

            expr.VisitEachT <Expr>(e =>
            {
                if (e is SubqueryExpr x)
                {
                    Debug.Assert(expr.HasSubQuery());
                    x.query_.cteInfo_ = this.cteInfo_;
                    x.query_.CreatePlan();
                    subplans.Add(new NamedQuery(x.query_, null, NamedQuery.QueryType.UNSURE));

                    // functionally we don't have to do rewrite since above
                    // plan is already runnable
                    if (queryOpt_.optimize_.enable_subquery_unnest_)
                    {
                        // use the plan 'root' containing the subexpr 'x'
                        bool canReplaceRoot = false;
                        var replacement     = oneSubqueryToJoin(root, x, ref canReplaceRoot);
                        newroot             = (LogicNode)newroot.SearchAndReplace(root,
                                                                                  replacement);
                        // consider  mark@1 or @2 , @2 is not unnested yet,
                        // so it can't be push down i.e. it keep as a root
                        if (canReplaceRoot)
                        {
                            root = newroot;
                        }
                    }
                }
                else if (e is FuncExpr f && f.isSRF_)
                {
                    var newchild      = new LogicProjectSet(root.child_());
                    root.children_[0] = newchild;
                }
            });

            subQueries_.AddRange(subplans);
            return(newroot);
        }
Ejemplo n.º 3
0
        // expands [NOT] EXISTS filter to mark join
        //
        //  LogicNode_A
        //     Filter: @1 AND|OR <others1>
        //     <ExistSubqueryExpr> 1
        //          -> LogicNode_B
        //             Filter: b.b1[0]=?a.a1[0] AND|OR <others2>
        // =>
        //    Filter
        //      Filter: #marker AND|OR <others1>
        //      MarkJoin
        //         Filter:  (b.b1[0]=a.a1[0]) AND|OR <others2> as #marker
        //         LogicNode_A
        //         LogicNode_B
        //
        // further convert DJoin to semi-join here is by decorrelate process
        //
        LogicNode existsToMarkJoin(LogicNode nodeA, ExistSubqueryExpr existExpr)
        {
            var nodeAIsOnMarkJoin =
                nodeA is LogicFilter && (nodeA.child_() is LogicMarkJoin || nodeA.child_() is LogicSingleJoin);

            // nodeB contains the join filter
            var nodeB       = existExpr.query_.logicPlan_;
            var nodeBFilter = nodeB.filter_;

            nodeB.NullifyFilter();

            // nullify nodeA's filter: the rest is push to top filter. However,
            // if nodeA is a Filter|MarkJoin, keep its mark filter.
            var markerFilter = new ExprRef(new MarkerExpr(), 0);
            var nodeAFilter  = nodeA.filter_;

            if (nodeAIsOnMarkJoin)
            {
                nodeA.filter_ = markerFilter;
            }
            else
            {
                if (nodeAFilter != null)
                {
                    // a1 > @1 and a2 > @2 and a3 > 2, scalarExpr = @1
                    //   keeplist: a1 > @1 and a3 > 2
                    //   andlist after removal: a2 > @2
                    //   nodeAFilter = a1 > @1 and a3 > 2
                    //
                    var andlist  = nodeAFilter.FilterToAndList();
                    var keeplist = andlist.Where(x => x.VisitEachExists(e => e.Equals(existExpr))).ToList();
                    andlist.RemoveAll(x => x.VisitEachExists(e => e.Equals(existExpr)));
                    if (andlist.Count == 0)
                    {
                        nodeA.NullifyFilter();
                    }
                    else
                    {
                        nodeA.filter_ = andlist.AndListToExpr();
                        if (keeplist.Count > 0)
                        {
                            nodeAFilter = keeplist.AndListToExpr();
                        }
                        else
                        {
                            nodeAFilter = markerFilter;
                        }
                    }
                }
            }
            // make a mark join
            LogicMarkJoin markjoin;

            if (existExpr.hasNot_)
            {
                markjoin = new LogicMarkAntiSemiJoin(nodeA, nodeB);
            }
            else
            {
                markjoin = new LogicMarkSemiJoin(nodeA, nodeB);
            }

            // make a filter on top of the mark join collecting all filters
            Expr topfilter;

            if (nodeAIsOnMarkJoin)
            {
                topfilter = nodeAFilter.SearchReplace(existExpr, LiteralExpr.MakeLiteral("true", new BoolType()));
            }
            else
            {
                topfilter = nodeAFilter.SearchReplace(existExpr, markerFilter);
            }
            nodeBFilter.DeParameter(nodeA.InclusiveTableRefs());
            topfilter = topfilter.AddAndFilter(nodeBFilter);
            LogicFilter Filter = new LogicFilter(markjoin, topfilter);

            return(Filter);
        }