Beispiel #1
0
        Expr extractCurINExprFromNodeAFilter(LogicNode nodeA, InSubqueryExpr curInExpr, ExprRef markerFilter)
        {
            var nodeAFilter = nodeA.filter_;

            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(curInExpr))).ToList();
                andlist.RemoveAll(x => x.VisitEachExists(e => e.Equals(curInExpr)));
                if (andlist.Count == 0)
                {
                    nodeA.NullifyFilter();
                }
                else
                {
                    nodeA.filter_ = andlist.AndListToExpr();
                    if (keeplist.Count > 0)
                    {
                        nodeAFilter = keeplist.AndListToExpr();
                    }
                    else
                    {
                        nodeAFilter = markerFilter;
                    }
                }
            }
            return(nodeAFilter);
        }
Beispiel #2
0
        LogicNode inToMarkJoin(LogicNode planWithSubExpr, InSubqueryExpr inExpr)
        {
            LogicNode nodeA = planWithSubExpr;

            // nodeB contains the join filter
            var nodeB       = inExpr.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(nodeBFilter.tableRefs_, inExpr.subqueryid_), 0);
            var nodeAFilter  = extractCurINExprFromNodeAFilter(nodeA, inExpr, markerFilter);

            // consider SQL ...a1 in select b1 from...
            // a1 is outerExpr and b1 is selectExpr
            Expr outerExpr = inExpr.child_();

            Debug.Assert(inExpr.query_.selection_.Count == 1);
            Expr    selectExpr = inExpr.query_.selection_[0];
            BinExpr inToEqual  = BinExpr.MakeBooleanExpr(outerExpr, selectExpr, "=", true);

            // make a mark join
            LogicMarkJoin markjoin;

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

            // make a filter on top of the mark join collecting all filters
            Expr topfilter = nodeAFilter.SearchAndReplace(inExpr, markerFilter);

            nodeBFilter.DeParameter(nodeA.InclusiveTableRefs());
            topfilter = topfilter.AddAndFilter(nodeBFilter);
            // TODO mutiple nested insubquery subquery
            // seperate the overlapping code with existsToSubquery to a new method
            // when the PR in #support nestted exist subquery pass
            LogicFilter Filter = new LogicFilter(markjoin, topfilter);

            Filter = new LogicFilter(Filter, inToEqual);
            return(Filter);
        }