diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/CountDistinctRewriteProc.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/CountDistinctRewriteProc.java index 6450cb3821..058a5079f1 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/CountDistinctRewriteProc.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/CountDistinctRewriteProc.java @@ -52,7 +52,6 @@ import org.apache.hadoop.hive.ql.parse.SemanticException; import org.apache.hadoop.hive.ql.plan.AggregationDesc; import org.apache.hadoop.hive.ql.plan.ExprNodeColumnDesc; -import org.apache.hadoop.hive.ql.plan.ExprNodeConstantDesc; import org.apache.hadoop.hive.ql.plan.ExprNodeDesc; import org.apache.hadoop.hive.ql.plan.GroupByDesc; import org.apache.hadoop.hive.ql.plan.OperatorDesc; @@ -137,12 +136,12 @@ public CountDistinctProcessor(ParseContext pGraphContext) { this.pGraphContext = pGraphContext; } - // Position of distinct column in aggregator list of map Gby before rewrite. - int indexOfDist = -1; - // Check if we can process it or not - protected boolean checkCountDistinct(GroupByOperator mGby, ReduceSinkOperator rs, + // Check if we can process it or not by the index of distinct + protected int checkCountDistinct(GroupByOperator mGby, ReduceSinkOperator rs, GroupByOperator rGby) { + // Position of distinct column in aggregator list of map Gby before rewrite. + int indexOfDist = -1; ArrayList keys = mGby.getConf().getKeys(); if (!(mGby.getConf().getMode() == GroupByDesc.Mode.HASH && !mGby.getConf().isGroupingSetsPresent() && rs.getConf().getKeyCols().size() == 1 @@ -151,7 +150,7 @@ protected boolean checkCountDistinct(GroupByOperator mGby, ReduceSinkOperator rs && rGby.getConf().getMode() == GroupByDesc.Mode.MERGEPARTIAL && keys.size() == 1 && rGby.getConf().getKeys().size() == 0 && mGby.getConf().getOutputColumnNames().size() == mGby .getConf().getAggregators().size() + 1)) { - return false; + return -1; } for (int pos = 0; pos < mGby.getConf().getAggregators().size(); pos++) { AggregationDesc aggr = mGby.getConf().getAggregators().get(pos); @@ -160,24 +159,24 @@ protected boolean checkCountDistinct(GroupByOperator mGby, ReduceSinkOperator rs // there are 2 or more distincts, or distinct is not on count // TODO: may be the same count(distinct key), count(distinct key) // TODO: deal with duplicate count distinct key - return false; + return -1; } indexOfDist = pos; if (!(aggr.getParameters().size() == 1 && aggr.getParameters().get(0) instanceof ExprNodeColumnDesc && mGby.getConf() .getKeys().get(0) instanceof ExprNodeColumnDesc)) { - return false; + return -1; } else { ExprNodeColumnDesc agg = (ExprNodeColumnDesc) aggr.getParameters().get(0); ExprNodeColumnDesc key = (ExprNodeColumnDesc) mGby.getConf().getKeys().get(0); if (!agg.isSame(key)) { - return false; + return -1; } } } } if (indexOfDist == -1) { - return false; + return -1; } // check if it is potential to trigger nullscan if (pGraphContext.getConf().getBoolVar(HiveConf.ConfVars.HIVEMETADATAONLYQUERIES)) { @@ -185,24 +184,23 @@ protected boolean checkCountDistinct(GroupByOperator mGby, ReduceSinkOperator rs List colIDs = tsOp.getNeededColumnIDs(); TableScanDesc desc = tsOp.getConf(); boolean noColNeeded = (colIDs == null) || (colIDs.isEmpty()); - // VC is still here and it will be pruned by column pruner - // boolean noVCneeded = (desc == null) || (desc.getVirtualCols() == null) - // || (desc.getVirtualCols().isEmpty()); + boolean noVCneeded = (desc == null) || (desc.getVirtualCols() == null) + || (desc.getVirtualCols().isEmpty()); boolean isSkipHF = desc.isNeedSkipHeaderFooters(); - if (noColNeeded && !isSkipHF) { + if (noColNeeded && noVCneeded && !isSkipHF) { // it is possible that nullscan can fire, we skip this rule. - return false; + return -1; } } } - return true; + return indexOfDist; } /* * We will transform GB-RS-GBY to mGby1-rs1-mGby2-mGby3-rs2-rGby1 */ @SuppressWarnings("unchecked") - protected void processGroupBy(GroupByOperator mGby, ReduceSinkOperator rs, GroupByOperator rGby) + protected void processGroupBy(GroupByOperator mGby, ReduceSinkOperator rs, GroupByOperator rGby, int indexOfDist) throws SemanticException, CloneNotSupportedException { // remove count(distinct) in map-side gby List> parents = mGby.getParentOperators(); @@ -213,8 +211,8 @@ protected void processGroupBy(GroupByOperator mGby, ReduceSinkOperator rs, Group GroupByOperator mGby1 = genMapGroupby1(mGby, indexOfDist); ReduceSinkOperator rs1 = genReducesink1(mGby1, rs, indexOfDist); - GroupByOperator mGby2 = genMapGroupby2(rs1, mGby); - GroupByOperator mGby3 = genMapGroupby3(mGby2, mGby); + GroupByOperator mGby2 = genMapGroupby2(rs1, mGby, indexOfDist); + GroupByOperator mGby3 = genMapGroupby3(mGby2, mGby, indexOfDist); ReduceSinkOperator rs2 = genReducesink2(mGby3, rs); GroupByOperator rGby1 = genReduceGroupby(rs2, rGby, indexOfDist); for (Operator parent : parents) { @@ -257,6 +255,8 @@ private ReduceSinkOperator genReducesink1(GroupByOperator mGby1, ArrayList outputValueColumnNames = new ArrayList(); ArrayList reduceKeys = new ArrayList(); ArrayList reduceValues = new ArrayList(); + ArrayList rowSchema = new ArrayList<>(); + List internalNames = new ArrayList<>(); for (int index = 0; index < mGby1.getSchema().getSignature().size(); index++) { ColumnInfo paraExprInfo = mGby1.getSchema().getSignature().get(index); @@ -272,6 +272,7 @@ private ReduceSinkOperator genReducesink1(GroupByOperator mGby1, String internalName = Utilities.ReduceField.KEY.toString() + "." + outputColName; colExprMap.put(internalName, exprDesc); internalNames.add(internalName); + rowSchema.add(new ColumnInfo(internalName, mGby1.getSchema().getSignature().get(index).getType(), "", false)); } else { reduceValues.add(exprDesc); String outputColName = SemanticAnalyzer.getColumnInternalName(index - 1); @@ -279,6 +280,7 @@ private ReduceSinkOperator genReducesink1(GroupByOperator mGby1, String internalName = Utilities.ReduceField.VALUE.toString() + "." + outputColName; colExprMap.put(internalName, exprDesc); internalNames.add(internalName); + rowSchema.add(new ColumnInfo(internalName, mGby1.getSchema().getSignature().get(index).getType(), "", false)); } } List> distinctColIndices = new ArrayList<>(); @@ -286,21 +288,14 @@ private ReduceSinkOperator genReducesink1(GroupByOperator mGby1, outputKeyColumnNames, outputValueColumnNames, true, -1, 1, -1, AcidUtils.Operation.NOT_ACID)); rs1.setColumnExprMap(colExprMap); - - rs1.getSchema().getColumnNames().remove(indexOfDist + 1); - rs1.getSchema().getSignature().remove(indexOfDist + 1); - // KEY._col0:0._col0 => KEY._col0 - - for (int i = 0; i < rs1.getSchema().getSignature().size(); i++) { - rs1.getSchema().getSignature().get(i).setInternalName(internalNames.get(i)); - rs1.getSchema().getColumnNames().set(i, internalNames.get(i)); - } + + rs1.setSchema(new RowSchema(rowSchema)); return rs1; } // mGby2 ---already contains key, remove distinct and change all the others private GroupByOperator genMapGroupby2(ReduceSinkOperator rs1, - Operator mGby) throws CloneNotSupportedException, SemanticException { + Operator mGby, int indexOfDist) throws CloneNotSupportedException, SemanticException { GroupByOperator mGby2 = (GroupByOperator) mGby.clone(); ArrayList rowSchema = new ArrayList<>(); ArrayList groupByKeys = new ArrayList(); @@ -361,7 +356,7 @@ private GroupByOperator genMapGroupby2(ReduceSinkOperator rs1, // mGby3 is a follow up of mGby2. Here we start to count(key). private GroupByOperator genMapGroupby3(GroupByOperator mGby2, - Operator mGby) throws CloneNotSupportedException, SemanticException { + Operator mGby, int indexOfDist) throws CloneNotSupportedException, SemanticException { GroupByOperator mGby3 = (GroupByOperator) mGby.clone(); ArrayList rowSchema = new ArrayList<>(); ArrayList outputColumnNames = new ArrayList(); @@ -436,6 +431,7 @@ private ReduceSinkOperator genReducesink2(GroupByOperator mGby2, ArrayList outputKeyColumnNames = new ArrayList(); ArrayList outputValueColumnNames = new ArrayList(); ArrayList reduceValues = new ArrayList(); + ArrayList rowSchema = new ArrayList<>(); for (int index = 0; index < mGby2.getSchema().getSignature().size(); index++) { ColumnInfo paraExprInfo = mGby2.getSchema().getSignature().get(index); String paraExpression = paraExprInfo.getInternalName(); @@ -447,6 +443,7 @@ private ReduceSinkOperator genReducesink2(GroupByOperator mGby2, outputValueColumnNames.add(outputColName); String internalName = Utilities.ReduceField.VALUE.toString() + "." + outputColName; colExprMap.put(internalName, exprDesc); + rowSchema.add(new ColumnInfo(internalName, paraExprInfo.getType(), "", false)); } List> distinctColIndices = new ArrayList<>(); ArrayList reduceKeys = new ArrayList<>(); @@ -454,7 +451,7 @@ private ReduceSinkOperator genReducesink2(GroupByOperator mGby2, outputKeyColumnNames, outputValueColumnNames, false, -1, 0, 1, AcidUtils.Operation.NOT_ACID)); rs2.setColumnExprMap(colExprMap); - rs2.getSchema().getSignature().remove(0); + rs2.setSchema(new RowSchema(rowSchema)); return rs2; } @@ -488,10 +485,11 @@ public Object process(Node nd, Stack stack, NodeProcessorCtx procCtx, GroupByOperator mGby = (GroupByOperator) stack.get(stack.size() - 3); ReduceSinkOperator rs = (ReduceSinkOperator) stack.get(stack.size() - 2); GroupByOperator rGby = (GroupByOperator) stack.get(stack.size() - 1); - if (checkCountDistinct(mGby, rs, rGby)) { + int applicableDistPos = checkCountDistinct(mGby, rs, rGby); + if (applicableDistPos != -1) { LOG.info("trigger count distinct rewrite"); try { - processGroupBy(mGby, rs, rGby); + processGroupBy(mGby, rs, rGby, applicableDistPos); } catch (CloneNotSupportedException e) { throw new SemanticException(e.getMessage()); } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/Optimizer.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/Optimizer.java index 781e088b88..3e4584db8d 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/Optimizer.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/Optimizer.java @@ -143,11 +143,11 @@ public void initialize(HiveConf hiveConf) { HiveConf.getBoolVar(hiveConf, HiveConf.ConfVars.HIVE_MAP_GROUPBY_SORT)) { transformations.add(new GroupByOptimizer()); } + transformations.add(new ColumnPruner()); if (HiveConf.getBoolVar(hiveConf, HiveConf.ConfVars.HIVECOUNTDISTINCTOPTIMIZER) && (HiveConf.getBoolVar(hiveConf, HiveConf.ConfVars.HIVE_IN_TEST) || isTezExecEngine)) { transformations.add(new CountDistinctRewriteProc()); } - transformations.add(new ColumnPruner()); if (HiveConf.getBoolVar(hiveConf, HiveConf.ConfVars.HIVE_OPTIMIZE_SKEWJOIN_COMPILETIME)) { if (!isTezExecEngine) { transformations.add(new SkewJoinOptimizer()); diff --git a/ql/src/test/queries/clientpositive/count_dist_rewrite.q b/ql/src/test/queries/clientpositive/count_dist_rewrite.q index 0b1bc66521..4bb25cccdd 100644 --- a/ql/src/test/queries/clientpositive/count_dist_rewrite.q +++ b/ql/src/test/queries/clientpositive/count_dist_rewrite.q @@ -1,3 +1,5 @@ +set hive.optimize.metadataonly=true; + explain select count(distinct key) from src; select count(distinct key) from src; diff --git a/ql/src/test/results/clientpositive/perf/query28.q.out b/ql/src/test/results/clientpositive/perf/query28.q.out index d2978a55fb..48e3dc5310 100644 --- a/ql/src/test/results/clientpositive/perf/query28.q.out +++ b/ql/src/test/results/clientpositive/perf/query28.q.out @@ -1,4 +1,4 @@ -Warning: Shuffle Join MERGEJOIN[64][tables = [$hdt$_0, $hdt$_1, $hdt$_2, $hdt$_3, $hdt$_4, $hdt$_5]] in Stage 'Reducer 4' is a cross product +Warning: Shuffle Join MERGEJOIN[94][tables = [$hdt$_0, $hdt$_1, $hdt$_2, $hdt$_3, $hdt$_4, $hdt$_5]] in Stage 'Reducer 4' is a cross product PREHOOK: query: explain select * from (select avg(ss_list_price) B1_LP @@ -106,13 +106,18 @@ POSTHOOK: type: QUERY Plan optimized by CBO. Vertex dependency in root stage +Reducer 10 <- Reducer 9 (CUSTOM_SIMPLE_EDGE) +Reducer 11 <- Map 1 (SIMPLE_EDGE) +Reducer 12 <- Reducer 11 (CUSTOM_SIMPLE_EDGE) +Reducer 13 <- Map 1 (SIMPLE_EDGE) +Reducer 14 <- Reducer 13 (CUSTOM_SIMPLE_EDGE) Reducer 2 <- Map 1 (SIMPLE_EDGE) Reducer 3 <- Reducer 2 (CUSTOM_SIMPLE_EDGE) -Reducer 4 <- Reducer 3 (CUSTOM_SIMPLE_EDGE), Reducer 5 (CUSTOM_SIMPLE_EDGE), Reducer 6 (CUSTOM_SIMPLE_EDGE), Reducer 7 (CUSTOM_SIMPLE_EDGE), Reducer 8 (CUSTOM_SIMPLE_EDGE), Reducer 9 (CUSTOM_SIMPLE_EDGE) +Reducer 4 <- Reducer 10 (CUSTOM_SIMPLE_EDGE), Reducer 12 (CUSTOM_SIMPLE_EDGE), Reducer 14 (CUSTOM_SIMPLE_EDGE), Reducer 3 (CUSTOM_SIMPLE_EDGE), Reducer 6 (CUSTOM_SIMPLE_EDGE), Reducer 8 (CUSTOM_SIMPLE_EDGE) Reducer 5 <- Map 1 (SIMPLE_EDGE) -Reducer 6 <- Map 1 (SIMPLE_EDGE) +Reducer 6 <- Reducer 5 (CUSTOM_SIMPLE_EDGE) Reducer 7 <- Map 1 (SIMPLE_EDGE) -Reducer 8 <- Map 1 (SIMPLE_EDGE) +Reducer 8 <- Reducer 7 (CUSTOM_SIMPLE_EDGE) Reducer 9 <- Map 1 (SIMPLE_EDGE) Stage-0 @@ -121,12 +126,73 @@ Stage-0 Stage-1 Reducer 4 File Output Operator [FS_51] - Limit [LIM_50] (rows=1 width=2665) + Limit [LIM_50] (rows=1 width=3505) Number of rows:100 - Select Operator [SEL_49] (rows=1 width=2665) + Select Operator [SEL_49] (rows=1 width=3505) Output:["_col0","_col1","_col2","_col3","_col4","_col5","_col6","_col7","_col8","_col9","_col10","_col11","_col12","_col13","_col14","_col15","_col16","_col17"] - Merge Join Operator [MERGEJOIN_64] (rows=1 width=2665) + Merge Join Operator [MERGEJOIN_94] (rows=1 width=3505) Conds:(Inner),(Inner),(Inner),(Inner),(Inner),Output:["_col0","_col1","_col2","_col3","_col4","_col5","_col6","_col7","_col8","_col9","_col10","_col11","_col12","_col13","_col14","_col15","_col16","_col17"] + <-Reducer 10 [CUSTOM_SIMPLE_EDGE] + PARTITION_ONLY_SHUFFLE [RS_45] + Group By Operator [GBY_81] (rows=1 width=584) + Output:["_col0","_col1","_col2"],aggregations:["avg(VALUE._col0)","count(VALUE._col1)","count(VALUE._col2)"] + <-Reducer 9 [CUSTOM_SIMPLE_EDGE] + PARTITION_ONLY_SHUFFLE [RS_80] + Group By Operator [GBY_79] (rows=1 width=584) + Output:["_col0","_col1","_col2"],aggregations:["avg(_col1)","count(_col2)","count(_col0)"] + Group By Operator [GBY_78] (rows=21333171 width=88) + Output:["_col0","_col1","_col2"],aggregations:["avg(VALUE._col0)","count(VALUE._col1)"],keys:KEY._col0 + <-Map 1 [SIMPLE_EDGE] + SHUFFLE [RS_77] + PartitionCols:_col0 + Group By Operator [GBY_76] (rows=21333171 width=88) + Output:["_col0","_col1","_col2"],aggregations:["avg(ss_list_price)","count(ss_list_price)"],keys:ss_list_price + Select Operator [SEL_23] (rows=21333171 width=88) + Output:["ss_list_price"] + Filter Operator [FIL_55] (rows=21333171 width=88) + predicate:(ss_quantity BETWEEN 16 AND 20 and (ss_list_price BETWEEN 142 AND 152 or ss_coupon_amt BETWEEN 3054 AND 4054 or ss_wholesale_cost BETWEEN 80 AND 100)) + TableScan [TS_0] (rows=575995635 width=88) + default@store_sales,store_sales,Tbl:COMPLETE,Col:NONE,Output:["ss_quantity","ss_wholesale_cost","ss_list_price","ss_coupon_amt"] + <-Reducer 12 [CUSTOM_SIMPLE_EDGE] + PARTITION_ONLY_SHUFFLE [RS_46] + Group By Operator [GBY_87] (rows=1 width=584) + Output:["_col0","_col1","_col2"],aggregations:["avg(VALUE._col0)","count(VALUE._col1)","count(VALUE._col2)"] + <-Reducer 11 [CUSTOM_SIMPLE_EDGE] + PARTITION_ONLY_SHUFFLE [RS_86] + Group By Operator [GBY_85] (rows=1 width=584) + Output:["_col0","_col1","_col2"],aggregations:["avg(_col1)","count(_col2)","count(_col0)"] + Group By Operator [GBY_84] (rows=21333171 width=88) + Output:["_col0","_col1","_col2"],aggregations:["avg(VALUE._col0)","count(VALUE._col1)"],keys:KEY._col0 + <-Map 1 [SIMPLE_EDGE] + SHUFFLE [RS_83] + PartitionCols:_col0 + Group By Operator [GBY_82] (rows=21333171 width=88) + Output:["_col0","_col1","_col2"],aggregations:["avg(ss_list_price)","count(ss_list_price)"],keys:ss_list_price + Select Operator [SEL_30] (rows=21333171 width=88) + Output:["ss_list_price"] + Filter Operator [FIL_56] (rows=21333171 width=88) + predicate:(ss_quantity BETWEEN 11 AND 15 and (ss_list_price BETWEEN 66 AND 76 or ss_coupon_amt BETWEEN 920 AND 1920 or ss_wholesale_cost BETWEEN 4 AND 24)) + Please refer to the previous TableScan [TS_0] + <-Reducer 14 [CUSTOM_SIMPLE_EDGE] + PARTITION_ONLY_SHUFFLE [RS_47] + Group By Operator [GBY_93] (rows=1 width=584) + Output:["_col0","_col1","_col2"],aggregations:["avg(VALUE._col0)","count(VALUE._col1)","count(VALUE._col2)"] + <-Reducer 13 [CUSTOM_SIMPLE_EDGE] + PARTITION_ONLY_SHUFFLE [RS_92] + Group By Operator [GBY_91] (rows=1 width=584) + Output:["_col0","_col1","_col2"],aggregations:["avg(_col1)","count(_col2)","count(_col0)"] + Group By Operator [GBY_90] (rows=21333171 width=88) + Output:["_col0","_col1","_col2"],aggregations:["avg(VALUE._col0)","count(VALUE._col1)"],keys:KEY._col0 + <-Map 1 [SIMPLE_EDGE] + SHUFFLE [RS_89] + PartitionCols:_col0 + Group By Operator [GBY_88] (rows=21333171 width=88) + Output:["_col0","_col1","_col2"],aggregations:["avg(ss_list_price)","count(ss_list_price)"],keys:ss_list_price + Select Operator [SEL_37] (rows=21333171 width=88) + Output:["ss_list_price"] + Filter Operator [FIL_57] (rows=21333171 width=88) + predicate:(ss_quantity BETWEEN 6 AND 10 and (ss_list_price BETWEEN 91 AND 101 or ss_coupon_amt BETWEEN 1430 AND 2430 or ss_wholesale_cost BETWEEN 32 AND 52)) + Please refer to the previous TableScan [TS_0] <-Reducer 3 [CUSTOM_SIMPLE_EDGE] PARTITION_ONLY_SHUFFLE [RS_42] Group By Operator [GBY_63] (rows=1 width=584) @@ -146,71 +212,45 @@ Stage-0 Output:["ss_list_price"] Filter Operator [FIL_52] (rows=21333171 width=88) predicate:(ss_quantity BETWEEN 0 AND 5 and (ss_list_price BETWEEN 11 AND 21 or ss_coupon_amt BETWEEN 460 AND 1460 or ss_wholesale_cost BETWEEN 14 AND 34)) - TableScan [TS_0] (rows=575995635 width=88) - default@store_sales,store_sales,Tbl:COMPLETE,Col:NONE,Output:["ss_quantity","ss_wholesale_cost","ss_list_price","ss_coupon_amt"] - <-Reducer 5 [CUSTOM_SIMPLE_EDGE] - PARTITION_ONLY_SHUFFLE [RS_43] - Group By Operator [GBY_12] (rows=1 width=416) - Output:["_col0","_col1","_col2"],aggregations:["avg(VALUE._col0)","count(VALUE._col1)","count(DISTINCT KEY._col0:0._col0)"] - <-Map 1 [SIMPLE_EDGE] - SHUFFLE [RS_11] - Group By Operator [GBY_10] (rows=21333171 width=88) - Output:["_col0","_col1","_col2","_col3"],aggregations:["avg(ss_list_price)","count(ss_list_price)","count(DISTINCT ss_list_price)"],keys:ss_list_price - Select Operator [SEL_9] (rows=21333171 width=88) - Output:["ss_list_price"] - Filter Operator [FIL_53] (rows=21333171 width=88) - predicate:(ss_quantity BETWEEN 26 AND 30 and (ss_list_price BETWEEN 28 AND 38 or ss_coupon_amt BETWEEN 2513 AND 3513 or ss_wholesale_cost BETWEEN 42 AND 62)) - Please refer to the previous TableScan [TS_0] + Please refer to the previous TableScan [TS_0] <-Reducer 6 [CUSTOM_SIMPLE_EDGE] - PARTITION_ONLY_SHUFFLE [RS_44] - Group By Operator [GBY_19] (rows=1 width=416) - Output:["_col0","_col1","_col2"],aggregations:["avg(VALUE._col0)","count(VALUE._col1)","count(DISTINCT KEY._col0:0._col0)"] - <-Map 1 [SIMPLE_EDGE] - SHUFFLE [RS_18] - Group By Operator [GBY_17] (rows=21333171 width=88) - Output:["_col0","_col1","_col2","_col3"],aggregations:["avg(ss_list_price)","count(ss_list_price)","count(DISTINCT ss_list_price)"],keys:ss_list_price - Select Operator [SEL_16] (rows=21333171 width=88) - Output:["ss_list_price"] - Filter Operator [FIL_54] (rows=21333171 width=88) - predicate:(ss_quantity BETWEEN 21 AND 25 and (ss_list_price BETWEEN 135 AND 145 or ss_coupon_amt BETWEEN 14180 AND 15180 or ss_wholesale_cost BETWEEN 38 AND 58)) - Please refer to the previous TableScan [TS_0] - <-Reducer 7 [CUSTOM_SIMPLE_EDGE] - PARTITION_ONLY_SHUFFLE [RS_45] - Group By Operator [GBY_26] (rows=1 width=416) - Output:["_col0","_col1","_col2"],aggregations:["avg(VALUE._col0)","count(VALUE._col1)","count(DISTINCT KEY._col0:0._col0)"] - <-Map 1 [SIMPLE_EDGE] - SHUFFLE [RS_25] - Group By Operator [GBY_24] (rows=21333171 width=88) - Output:["_col0","_col1","_col2","_col3"],aggregations:["avg(ss_list_price)","count(ss_list_price)","count(DISTINCT ss_list_price)"],keys:ss_list_price - Select Operator [SEL_23] (rows=21333171 width=88) - Output:["ss_list_price"] - Filter Operator [FIL_55] (rows=21333171 width=88) - predicate:(ss_quantity BETWEEN 16 AND 20 and (ss_list_price BETWEEN 142 AND 152 or ss_coupon_amt BETWEEN 3054 AND 4054 or ss_wholesale_cost BETWEEN 80 AND 100)) - Please refer to the previous TableScan [TS_0] + PARTITION_ONLY_SHUFFLE [RS_43] + Group By Operator [GBY_69] (rows=1 width=584) + Output:["_col0","_col1","_col2"],aggregations:["avg(VALUE._col0)","count(VALUE._col1)","count(VALUE._col2)"] + <-Reducer 5 [CUSTOM_SIMPLE_EDGE] + PARTITION_ONLY_SHUFFLE [RS_68] + Group By Operator [GBY_67] (rows=1 width=584) + Output:["_col0","_col1","_col2"],aggregations:["avg(_col1)","count(_col2)","count(_col0)"] + Group By Operator [GBY_66] (rows=21333171 width=88) + Output:["_col0","_col1","_col2"],aggregations:["avg(VALUE._col0)","count(VALUE._col1)"],keys:KEY._col0 + <-Map 1 [SIMPLE_EDGE] + SHUFFLE [RS_65] + PartitionCols:_col0 + Group By Operator [GBY_64] (rows=21333171 width=88) + Output:["_col0","_col1","_col2"],aggregations:["avg(ss_list_price)","count(ss_list_price)"],keys:ss_list_price + Select Operator [SEL_9] (rows=21333171 width=88) + Output:["ss_list_price"] + Filter Operator [FIL_53] (rows=21333171 width=88) + predicate:(ss_quantity BETWEEN 26 AND 30 and (ss_list_price BETWEEN 28 AND 38 or ss_coupon_amt BETWEEN 2513 AND 3513 or ss_wholesale_cost BETWEEN 42 AND 62)) + Please refer to the previous TableScan [TS_0] <-Reducer 8 [CUSTOM_SIMPLE_EDGE] - PARTITION_ONLY_SHUFFLE [RS_46] - Group By Operator [GBY_33] (rows=1 width=416) - Output:["_col0","_col1","_col2"],aggregations:["avg(VALUE._col0)","count(VALUE._col1)","count(DISTINCT KEY._col0:0._col0)"] - <-Map 1 [SIMPLE_EDGE] - SHUFFLE [RS_32] - Group By Operator [GBY_31] (rows=21333171 width=88) - Output:["_col0","_col1","_col2","_col3"],aggregations:["avg(ss_list_price)","count(ss_list_price)","count(DISTINCT ss_list_price)"],keys:ss_list_price - Select Operator [SEL_30] (rows=21333171 width=88) - Output:["ss_list_price"] - Filter Operator [FIL_56] (rows=21333171 width=88) - predicate:(ss_quantity BETWEEN 11 AND 15 and (ss_list_price BETWEEN 66 AND 76 or ss_coupon_amt BETWEEN 920 AND 1920 or ss_wholesale_cost BETWEEN 4 AND 24)) - Please refer to the previous TableScan [TS_0] - <-Reducer 9 [CUSTOM_SIMPLE_EDGE] - PARTITION_ONLY_SHUFFLE [RS_47] - Group By Operator [GBY_40] (rows=1 width=416) - Output:["_col0","_col1","_col2"],aggregations:["avg(VALUE._col0)","count(VALUE._col1)","count(DISTINCT KEY._col0:0._col0)"] - <-Map 1 [SIMPLE_EDGE] - SHUFFLE [RS_39] - Group By Operator [GBY_38] (rows=21333171 width=88) - Output:["_col0","_col1","_col2","_col3"],aggregations:["avg(ss_list_price)","count(ss_list_price)","count(DISTINCT ss_list_price)"],keys:ss_list_price - Select Operator [SEL_37] (rows=21333171 width=88) - Output:["ss_list_price"] - Filter Operator [FIL_57] (rows=21333171 width=88) - predicate:(ss_quantity BETWEEN 6 AND 10 and (ss_list_price BETWEEN 91 AND 101 or ss_coupon_amt BETWEEN 1430 AND 2430 or ss_wholesale_cost BETWEEN 32 AND 52)) - Please refer to the previous TableScan [TS_0] + PARTITION_ONLY_SHUFFLE [RS_44] + Group By Operator [GBY_75] (rows=1 width=584) + Output:["_col0","_col1","_col2"],aggregations:["avg(VALUE._col0)","count(VALUE._col1)","count(VALUE._col2)"] + <-Reducer 7 [CUSTOM_SIMPLE_EDGE] + PARTITION_ONLY_SHUFFLE [RS_74] + Group By Operator [GBY_73] (rows=1 width=584) + Output:["_col0","_col1","_col2"],aggregations:["avg(_col1)","count(_col2)","count(_col0)"] + Group By Operator [GBY_72] (rows=21333171 width=88) + Output:["_col0","_col1","_col2"],aggregations:["avg(VALUE._col0)","count(VALUE._col1)"],keys:KEY._col0 + <-Map 1 [SIMPLE_EDGE] + SHUFFLE [RS_71] + PartitionCols:_col0 + Group By Operator [GBY_70] (rows=21333171 width=88) + Output:["_col0","_col1","_col2"],aggregations:["avg(ss_list_price)","count(ss_list_price)"],keys:ss_list_price + Select Operator [SEL_16] (rows=21333171 width=88) + Output:["ss_list_price"] + Filter Operator [FIL_54] (rows=21333171 width=88) + predicate:(ss_quantity BETWEEN 21 AND 25 and (ss_list_price BETWEEN 135 AND 145 or ss_coupon_amt BETWEEN 14180 AND 15180 or ss_wholesale_cost BETWEEN 38 AND 58)) + Please refer to the previous TableScan [TS_0]