public CteQueryPart(CteInfo cteInfo) { CteInfo = cteInfo; Columns = cteInfo.CteContentParts .OfType <ISelectableQueryPart>() .FirstOrDefault(e => !(e is JoinTableQueryPart))? .Columns; }
public LogicNode CreateSetOpPlan(CteInfo cteInfo, bool top = true) { if (top) { // traversal on top node is the time to examine the setop tree Debug.Assert(!IsLeaf()); VerifySelection(); } if (IsLeaf()) { stmt_.cteInfo_ = cteInfo; return(stmt_.CreatePlan()); } else { var lplan = left_.CreateSetOpPlan(cteInfo, false); var rplan = right_.CreateSetOpPlan(cteInfo, false); LogicNode plan; // try to reuse existing operators to implment because users may write // SQL code like this and this helps reduce optimizer search space // switch (op_) { case "unionall": // union all keeps all rows, including duplicates plan = new LogicAppend(lplan, rplan, this); break; case "union": // union collect rows from both sides, and remove duplicates plan = new LogicAppend(lplan, rplan, this); var groupby = new List <Expr>(first_.selection_.CloneList()); plan = new LogicAgg(plan, groupby, null, null); break; case "except": // except keeps left rows not found in right case "intersect": // intersect keeps rows found in both sides var filter = FilterHelper.MakeFullComparator( left_.first_.selection_, right_.first_.selection_); var join = new LogicJoin(lplan, rplan); if (op_.Contains("except")) { join.type_ = JoinType.AntiSemi; } if (op_.Contains("intersect")) { join.type_ = JoinType.Semi; } var logfilter = new LogicFilter(join, filter); groupby = new List <Expr>(first_.selection_.CloneList()); plan = new LogicAgg(logfilter, groupby, null, null); break; case "exceptall": case "intersectall": // the 'all' semantics is a bit confusing than intuition: // {1,1,1} exceptall {1,1} => {1} // {1,1,1} intersectall {1,1} => {1,1} // throw new NotImplementedException(); default: throw new InvalidProgramException(); } return(plan); } }
public ISelectableQueryPart AddCte(CteInfo cteInfo) { _cteInfos.Add(cteInfo); return(new CteQueryPart(cteInfo)); }