Пример #1
0
        public override CGroupMember Apply(CGroupMember expr)
        {
            LogicJoin a_bc     = expr.logic_ as LogicJoin;
            LogicNode a        = (a_bc.l_() as LogicMemoRef).Deref <LogicNode>();
            LogicJoin bc       = (a_bc.r_() as LogicMemoRef).Deref <LogicJoin>();
            Expr      bcfilter = bc.filter_;
            var       ab       = new LogicJoin(a_bc.l_(), bc.l_());
            var       c        = bc.r_();
            var       ab_c     = new LogicJoin(ab, c);

            Debug.Assert(!a.LeftReferencesRight(bc));
            if (ab.LeftReferencesRight(c))
            {
                return(expr);
            }

            // pull up all join filters and re-push them back
            Expr allfilters = bcfilter;

            if (a_bc.filter_ != null)
            {
                allfilters = allfilters.AddAndFilter(a_bc.filter_);
            }
            if (allfilters != null)
            {
                var andlist = allfilters.FilterToAndList();
                andlist.RemoveAll(e => ab_c.PushJoinFilter(e));
                if (andlist.Count > 0)
                {
                    ab_c.filter_ = andlist.AndListToExpr();
                }
            }

            // Ideally if there is no cross join in the given plan but cross join
            // in the new plan, we shall return the original plan. However, stop
            // exploration now will prevent generating other promising plans. So
            // we have to return the new plan.
            //
            if (expr.QueryOption().optimize_.memo_disable_crossjoin_)
            {
                if (a_bc.filter_ != null && bcfilter != null)
                {
                    if (ab_c.filter_ is null || ab.filter_ is null)
                    {
                        return(expr);
                    }
                }
            }


            return(new CGroupMember(ab_c, expr.group_));
        }