public override CGroupMember Apply(CGroupMember expr) { LogicScanTable log = expr.logic_ as LogicScanTable; var index = log.filter_.FilterCanUseIndex(log.tabref_); if (index is null) { return(expr); } else { var phy = new PhysicIndexSeek(log, index); return(new CGroupMember(phy, expr.group_)); } }
// This is an honest translation from logic to physical plan public PhysicNode DirectToPhysical(QueryOption option) { PhysicNode phy; switch (this) { case LogicScanTable ln: // if there are indexes can help filter, use them IndexDef index = null; if (ln.filter_ != null) { if (option.optimize_.enable_indexseek_) { index = ln.filter_.FilterCanUseIndex(ln.tabref_); } ln.filter_.SubqueryDirectToPhysic(); } if (index is null) { phy = new PhysicScanTable(ln); } else { phy = new PhysicIndexSeek(ln, index); } break; case LogicJoin lc: var l = l_(); var r = r_(); Debug.Assert(!l.LeftReferencesRight(r)); switch (lc) { case LogicSingleJoin lsmj: phy = new PhysicSingleJoin(lsmj, l.DirectToPhysical(option), r.DirectToPhysical(option)); break; case LogicMarkJoin lmj: phy = new PhysicMarkJoin(lmj, l.DirectToPhysical(option), r.DirectToPhysical(option)); break; default: // one restriction of HJ is that if build side has columns used by probe side // subquries, we need to use NLJ to pass variables. It is can be fixed by changing // the way we pass parameters though. bool lhasSubqCol = TableRef.HasColsUsedBySubquries(l.InclusiveTableRefs()); if (lc.filter_.FilterHashable() && !lhasSubqCol && (lc.type_ == JoinType.Inner || lc.type_ == JoinType.Left)) { phy = new PhysicHashJoin(lc, l.DirectToPhysical(option), r.DirectToPhysical(option)); } else { phy = new PhysicNLJoin(lc, l.DirectToPhysical(option), r.DirectToPhysical(option)); } break; } break; case LogicResult lr: phy = new PhysicResult(lr); break; case LogicFromQuery ls: phy = new PhysicFromQuery(ls, child_().DirectToPhysical(option)); break; case LogicFilter lf: phy = new PhysicFilter(lf, child_().DirectToPhysical(option)); if (lf.filter_ != null) { lf.filter_.SubqueryDirectToPhysic(); } break; case LogicInsert li: phy = new PhysicInsert(li, child_().DirectToPhysical(option)); break; case LogicScanFile le: phy = new PhysicScanFile(le); break; case LogicAgg la: phy = new PhysicHashAgg(la, child_().DirectToPhysical(option)); break; case LogicOrder lo: phy = new PhysicOrder(lo, child_().DirectToPhysical(option)); break; case LogicAnalyze lan: phy = new PhysicAnalyze(lan, child_().DirectToPhysical(option)); break; case LogicIndex lindex: phy = new PhysicIndex(lindex, child_().DirectToPhysical(option)); break; case LogicLimit limit: phy = new PhysicLimit(limit, child_().DirectToPhysical(option)); break; case LogicAppend append: phy = new PhysicAppend(append, l_().DirectToPhysical(option), r_().DirectToPhysical(option)); break; case LogicCteProducer cteproducer: phy = new PhysicCteProducer(cteproducer, child_().DirectToPhysical(option)); break; case LogicSequence sequence: List <PhysicNode> children = sequence.children_.Select(x => x.DirectToPhysical(option)).ToList(); phy = new PhysicSequence(sequence, children); break; default: throw new NotImplementedException(); } if (option.profile_.enabled_) { phy = new PhysicProfiling(phy); } return(phy); }