diff --git a/fe/src/com/baidu/palo/analysis/Analyzer.java b/fe/src/com/baidu/palo/analysis/Analyzer.java
index 5b071819b87f99..457962ba8476ed 100644
--- a/fe/src/com/baidu/palo/analysis/Analyzer.java
+++ b/fe/src/com/baidu/palo/analysis/Analyzer.java
@@ -59,6 +59,7 @@
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
@@ -1543,4 +1544,53 @@ public boolean isOuterJoined(TupleId tid) {
public boolean containSubquery() {
return globalState.containsSubquery;
}
+
+ /**
+ * Mark slots that are being referenced by the plan tree itself or by the outputExprs exprs as materialized. If the
+ * latter is null, mark all slots in planRoot's tupleIds() as being referenced. All aggregate slots are
+ * materialized.
+ *
+ * TODO: instead of materializing everything produced by the plan root, derived referenced slots from destination
+ * fragment and add a materialization node if not all output is needed by destination fragment TODO 2: should the
+ * materialization decision be cost-based?
+ */
+ public void markRefdSlots(Analyzer analyzer, PlanNode planRoot,
+ List outputExprs, AnalyticInfo analyticInfo) {
+ if (planRoot == null) {
+ return;
+ }
+ List refdIdList = Lists.newArrayList();
+ planRoot.getMaterializedIds(analyzer, refdIdList);
+ if (outputExprs != null) {
+ Expr.getIds(outputExprs, null, refdIdList);
+ }
+
+ HashSet refdIds = Sets.newHashSet(refdIdList);
+ for (TupleDescriptor tupleDesc : analyzer.getDescTbl().getTupleDescs()) {
+ for (SlotDescriptor slotDesc : tupleDesc.getSlots()) {
+ if (refdIds.contains(slotDesc.getId())) {
+ slotDesc.setIsMaterialized(true);
+ }
+ }
+ }
+ if (analyticInfo != null) {
+ ArrayList list = analyticInfo.getOutputTupleDesc().getSlots();
+
+ for (SlotDescriptor slotDesc : list) {
+ if (refdIds.contains(slotDesc.getId())) {
+ slotDesc.setIsMaterialized(true);
+ }
+ }
+ }
+ if (outputExprs == null) {
+ // mark all slots in planRoot.getTupleIds() as materialized
+ ArrayList tids = planRoot.getTupleIds();
+ for (TupleId tid : tids) {
+ TupleDescriptor tupleDesc = analyzer.getDescTbl().getTupleDesc(tid);
+ for (SlotDescriptor slotDesc : tupleDesc.getSlots()) {
+ slotDesc.setIsMaterialized(true);
+ }
+ }
+ }
+ }
}
diff --git a/fe/src/com/baidu/palo/planner/Planner.java b/fe/src/com/baidu/palo/planner/Planner.java
index 94980159103ae8..85cc5c529ad2fa 100644
--- a/fe/src/com/baidu/palo/planner/Planner.java
+++ b/fe/src/com/baidu/palo/planner/Planner.java
@@ -107,55 +107,6 @@ private void setResultExprScale(Analyzer analyzer, ArrayList outputExprs)
}
}
- /**
- * Mark slots that are being referenced by the plan tree itself or by the outputExprs exprs as materialized. If the
- * latter is null, mark all slots in planRoot's tupleIds() as being referenced. All aggregate slots are
- * materialized.
- *
- * TODO: instead of materializing everything produced by the plan root, derived referenced slots from destination
- * fragment and add a materialization node if not all output is needed by destination fragment TODO 2: should the
- * materialization decision be cost-based?
- */
- private void markRefdSlots(Analyzer analyzer, PlanNode planRoot,
- List outputExprs, AnalyticInfo analyticInfo) {
- if (planRoot == null) {
- return;
- }
- List refdIdList = Lists.newArrayList();
- planRoot.getMaterializedIds(analyzer, refdIdList);
- if (outputExprs != null) {
- Expr.getIds(outputExprs, null, refdIdList);
- }
-
- HashSet refdIds = Sets.newHashSet(refdIdList);
- for (TupleDescriptor tupleDesc : analyzer.getDescTbl().getTupleDescs()) {
- for (SlotDescriptor slotDesc : tupleDesc.getSlots()) {
- if (refdIds.contains(slotDesc.getId())) {
- slotDesc.setIsMaterialized(true);
- }
- }
- }
- if (analyticInfo != null) {
- ArrayList list = analyticInfo.getOutputTupleDesc().getSlots();
-
- for (SlotDescriptor slotDesc : list) {
- if (refdIds.contains(slotDesc.getId())) {
- slotDesc.setIsMaterialized(true);
- }
- }
- }
- if (outputExprs == null) {
- // mark all slots in planRoot.getTupleIds() as materialized
- ArrayList tids = planRoot.getTupleIds();
- for (TupleId tid : tids) {
- TupleDescriptor tupleDesc = analyzer.getDescTbl().getTupleDesc(tid);
- for (SlotDescriptor slotDesc : tupleDesc.getSlots()) {
- slotDesc.setIsMaterialized(true);
- }
- }
- }
- }
-
/**
* Return combined explain string for all plan fragments.
*/
@@ -201,7 +152,7 @@ public void createPlanFragments(StatementBase statment, Analyzer analyzer, TQuer
}
// compute referenced slots before calling computeMemLayout()
- markRefdSlots(analyzer, singleNodePlan, resultExprs, null);
+ analyzer.markRefdSlots(analyzer, singleNodePlan, resultExprs, null);
setResultExprScale(analyzer, queryStmt.getResultExprs());
diff --git a/fe/src/com/baidu/palo/planner/SingleNodePlanner.java b/fe/src/com/baidu/palo/planner/SingleNodePlanner.java
index 8736e176eeb6de..a3ac1e914f865c 100644
--- a/fe/src/com/baidu/palo/planner/SingleNodePlanner.java
+++ b/fe/src/com/baidu/palo/planner/SingleNodePlanner.java
@@ -651,26 +651,23 @@ private PlanNode createSelectPlan(SelectStmt selectStmt, Analyzer analyzer, long
// add aggregate node here
AggregateInfo aggInfo = selectStmt.getAggInfo();
- /*
+
// for case: select count(*) from (select col from table) t
// for simple, we just materialize sub tree if has count star
if (aggInfo != null) {
for (FunctionCallExpr aggExpr : aggInfo.getAggregateExprs()) {
if (aggExpr.isCountStar()) {
- LOG.debug("count(*) to {}", root.debugString());
- markRefdSlots(analyzer, root, null, null);
+ analyzer.markRefdSlots(analyzer, root, null, null);
break;
}
}
for (Expr groupExpr : aggInfo.getGroupingExprs()) {
if (groupExpr.isConstant()) {
- LOG.debug("count(distinct 1) to {}", root.debugString());
- markRefdSlots(analyzer, root, null, null);
+ analyzer.markRefdSlots(analyzer, root, null, null);
break;
}
}
}
- */
turnOffPreAgg(aggInfo, selectStmt, analyzer, root);