15 package com.cloudera.impala.planner;
17 import java.util.ArrayList;
18 import java.util.List;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
33 import com.cloudera.impala.common.TreeNode;
34 import com.cloudera.impala.thrift.TExecStats;
35 import com.cloudera.impala.thrift.TExplainLevel;
36 import com.cloudera.impala.thrift.TPlan;
37 import com.cloudera.impala.thrift.TPlanNode;
38 import com.cloudera.impala.thrift.TQueryOptions;
39 import com.google.common.base.Preconditions;
40 import com.google.common.collect.Lists;
41 import com.google.common.collect.Sets;
42 import com.google.common.math.LongMath;
59 abstract public class PlanNode extends TreeNode<PlanNode> {
60 private final static Logger
LOG = LoggerFactory.getLogger(PlanNode.class);
120 tupleIds_ = Lists.newArrayList(tupleIds);
155 tupleIds_ = Lists.newArrayList(node.tupleIds_);
156 tblRefIds_ = Lists.newArrayList(node.tblRefIds_);
166 Preconditions.checkState(
id_ == null);
197 Preconditions.checkState(
tupleIds_ != null);
210 if (conjuncts == null)
return;
211 conjuncts_.addAll(conjuncts);
226 return String.format(
"%s:%s", id_.toString(),
displayName_);
253 TExplainLevel detailLevel) {
254 StringBuilder expBuilder =
new StringBuilder();
255 String detailPrefix = prefix;
257 boolean printFiller = (detailLevel.ordinal() >= TExplainLevel.STANDARD.ordinal());
261 boolean traverseChildren = !children_.isEmpty() &&
262 !(
this instanceof
ExchangeNode && detailLevel == TExplainLevel.VERBOSE);
264 if (traverseChildren) {
265 detailPrefix +=
"| ";
266 filler = prefix +
"|";
277 if (detailLevel.ordinal() >= TExplainLevel.STANDARD.ordinal() &&
279 if (
limit_ != -1) expBuilder.append(detailPrefix +
"limit: " +
limit_ +
"\n");
285 if (detailLevel.ordinal() >= TExplainLevel.EXTENDED.ordinal()) {
287 expBuilder.append(PrintUtils.printHosts(detailPrefix,
numNodes_));
288 expBuilder.append(PrintUtils.printMemCost(
" ",
perHostMemCost_) +
"\n");
291 expBuilder.append(detailPrefix +
"tuple-ids=");
292 for (
int i = 0; i < tupleIds_.size(); ++i) {
293 TupleId tupleId = tupleIds_.get(i);
294 String nullIndicator = nullableTupleIds_.contains(tupleId) ?
"N" :
"";
295 expBuilder.append(tupleId.asInt() + nullIndicator);
296 if (i + 1 !=
tupleIds_.size()) expBuilder.append(
",");
298 expBuilder.append(
" row-size=" + PrintUtils.printBytes(Math.round(
avgRowSize_)));
299 expBuilder.append(PrintUtils.printCardinality(
" ",
cardinality_));
300 expBuilder.append(
"\n");
305 if (traverseChildren) {
306 if (printFiller) expBuilder.append(filler +
"\n");
307 String childHeadlinePrefix = prefix +
"|--";
308 String childDetailPrefix = prefix +
"| ";
309 for (
int i = children_.size() - 1; i >= 1; --i) {
313 if (printFiller) expBuilder.append(filler +
"\n");
315 expBuilder.append(children_.get(0).
getExplainString(prefix, prefix, detailLevel));
317 return expBuilder.toString();
326 TExplainLevel detailLevel) {
342 TPlan result =
new TPlan();
349 TPlanNode msg =
new TPlanNode();
350 msg.node_id = id_.asInt();
353 TExecStats estimatedStats =
new TExecStats();
358 msg.setEstimated_stats(estimatedStats);
360 msg.setRow_tuples(Lists.<Integer>newArrayListWithCapacity(
tupleIds_.size()));
361 msg.setNullable_tuples(Lists.<Boolean>newArrayListWithCapacity(
tupleIds_.size()));
363 msg.addToRow_tuples(tid.asInt());
364 msg.addToNullable_tuples(nullableTupleIds_.contains(tid));
367 msg.addToConjuncts(e.treeToThrift());
370 container.addToNodes(msg);
373 msg.num_children = 0;
376 msg.num_children = children_.size();
378 child.treeToThriftHelper(container);
402 List<Expr> unassigned = analyzer.getUnassignedConjuncts(
this);
403 conjuncts_.addAll(unassigned);
404 analyzer.markConjunctsAssigned(unassigned);
412 if (getChildren().size() == 1)
return getChild(0).getOutputSmap();
414 getChild(0).getOutputSmap(), getChild(1).getOutputSmap());
415 for (
int i = 2; i < getChildren().size(); ++i) {
416 result = ExprSubstitutionMap.combine(result, getChild(i).getOutputSmap());
428 ExprSubstitutionMap.compose(
outputSmap_, combinedChildSmap, analyzer);
447 if (!children_.isEmpty())
numNodes_ = getChild(0).numNodes_;
452 if (cardinality == -1) {
455 return Math.min(cardinality,
limit_);
465 List<SlotId> refdIdList = Lists.newArrayList();
466 for (
Expr expr: exprs) {
467 expr.getIds(null, refdIdList);
477 analyzer.getDescTbl().getTupleDesc(
id).computeMemLayout();
487 if (e.getSelectivity() < 0)
continue;
488 prod *= e.getSelectivity();
495 protected abstract void toThrift(TPlanNode msg);
500 StringBuilder output =
new StringBuilder();
501 output.append(
"preds=" + Expr.debugString(
conjuncts_));
502 output.append(
" limit=" + Long.toString(
limit_));
503 return output.toString();
507 if (exprs == null)
return "";
508 StringBuilder output =
new StringBuilder();
509 for (
int i = 0; i < exprs.size(); ++i) {
510 if (i > 0) output.append(
", ");
511 output.append(exprs.get(i).toSql());
513 return output.toString();
530 return LongMath.checkedAdd(a, b);
531 }
catch (ArithmeticException e) {
532 LOG.warn(
"overflow when adding cardinalities: " + a +
", " + b);
533 return Long.MAX_VALUE;
543 return LongMath.checkedMultiply(a, b);
544 }
catch (ArithmeticException e) {
545 LOG.warn(
"overflow when multiplying cardinalities: " + a +
", " + b);
546 return Long.MAX_VALUE;
573 long tmp = p.getCardinality();
574 if (tmp == -1)
return -1;
String getDisplayLabelDetail()
PlanNode(PlanNodeId id, String displayName)
void assignConjuncts(Analyzer analyzer)
ArrayList< TupleId > tupleIds_
static final int DEFAULT_BATCH_SIZE
ArrayList< TupleId > getTblRefIds()
ExprSubstitutionMap getCombinedChildSmap()
String getExplainString()
void setLimit(long limit)
void setTblRefIds(ArrayList< TupleId > ids)
Set< ExprId > getAssignedConjuncts()
Set< TupleId > getNullableTupleIds()
void setId(PlanNodeId id)
List< Expr > getConjuncts()
ArrayList< TupleId > getTupleIds()
void markSlotsMaterialized(Analyzer analyzer, List< Expr > exprs)
PlanNode(String displayName)
static long multiplyCardinalities(long a, long b)
PlanNode(PlanNodeId id, ArrayList< TupleId > tupleIds, String displayName)
void setFragment(PlanFragment fragment)
PlanFragment getFragment()
Set< TupleId > nullableTupleIds_
void transferConjuncts(PlanNode recipient)
abstract void toThrift(TPlanNode msg)
String getExplainString(List<?extends Expr > exprs)
String getNodeExplainString(String rootPrefix, String detailPrefix, TExplainLevel detailLevel)
PlanNode(PlanNodeId id, PlanNode node, String displayName)
void createDefaultSmap(Analyzer analyzer)
final String getExplainString(String rootPrefix, String prefix, TExplainLevel detailLevel)
void computeMemLayout(Analyzer analyzer)
ExprSubstitutionMap getOutputSmap()
long capAtLimit(long cardinality)
void computeCosts(TQueryOptions queryOptions)
void computeStats(Analyzer analyzer)
void setDisplayName(String s)
void init(Analyzer analyzer)
void setAssignedConjuncts(Set< ExprId > conjuncts)
double computeSelectivity()
void treeToThriftHelper(TPlan container)
long getInputCardinality()
String getOffsetExplainString(String prefix)
void setOutputSmap(ExprSubstitutionMap smap)
void addConjuncts(List< Expr > conjuncts)
ArrayList< TupleId > tblRefIds_
final String getDisplayLabel()
Set< ExprId > assignedConjuncts_
ExprSubstitutionMap outputSmap_
static long addCardinalities(long a, long b)