This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch opt_memtable_speed
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/opt_memtable_speed by this
push:
new 4f2bd01992 Revert "[fix](nereids) partitionTopN & Window estimation
(#22953)" (#23136)
4f2bd01992 is described below
commit 4f2bd019928bf8bfd77646f6ac525e9646c0af20
Author: xzj7019 <[email protected]>
AuthorDate: Thu Aug 17 21:55:59 2023 +0800
Revert "[fix](nereids) partitionTopN & Window estimation (#22953)" (#23136)
This reverts commit 423002b20a3ae9da74898051835b3514a7f87db2.
Co-authored-by: zhongjian.xzj
<[email protected]>
---
.../doris/nereids/stats/ExpressionEstimation.java | 18 ++--
.../doris/nereids/stats/StatsCalculator.java | 109 +++++++--------------
.../plans/physical/PhysicalPartitionTopN.java | 3 +-
.../trees/plans/physical/PhysicalQuickSort.java | 2 +-
.../trees/plans/physical/PhysicalWindow.java | 2 +-
.../nereids_tpcds_shape_sf100_p0/shape/query44.out | 62 ++++++------
.../nereids_tpcds_shape_sf100_p0/shape/query47.out | 19 ++--
.../nereids_tpcds_shape_sf100_p0/shape/query57.out | 20 ++--
8 files changed, 100 insertions(+), 135 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/ExpressionEstimation.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/ExpressionEstimation.java
index 5324fce9e6..03e4be4d63 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/ExpressionEstimation.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/ExpressionEstimation.java
@@ -290,12 +290,13 @@ public class ExpressionEstimation extends
ExpressionVisitor<ColumnStatistic, Sta
}
/*
we keep columnStat.min and columnStat.max, but set ndv=1.
- if there is group-by keys, we will update count when visiting group
clause
+ if there is group-by keys, we will update ndv when visiting group
clause
*/
double width = min.child().getDataType().width();
- return new
ColumnStatisticBuilder().setCount(1).setNdv(1).setAvgSizeByte(width)
-
.setMinValue(columnStat.minValue).setMinExpr(columnStat.minExpr)
-
.setMaxValue(columnStat.maxValue).setMaxExpr(columnStat.maxExpr).build();
+ return new
ColumnStatisticBuilder().setCount(1).setNdv(1).setAvgSizeByte(width).setNumNulls(width)
+
.setDataSize(child.getDataType().width()).setMinValue(columnStat.minValue)
+ .setMaxValue(columnStat.maxValue).setSelectivity(1.0)
+ .setMinExpr(null).build();
}
@Override
@@ -307,13 +308,12 @@ public class ExpressionEstimation extends
ExpressionVisitor<ColumnStatistic, Sta
}
/*
we keep columnStat.min and columnStat.max, but set ndv=1.
- if there is group-by keys, we will update count when visiting group
clause
+ if there is group-by keys, we will update ndv when visiting group
clause
*/
int width = max.child().getDataType().width();
- return new
ColumnStatisticBuilder().setCount(1D).setNdv(1D).setAvgSizeByte(width)
-
.setMinValue(columnStat.minValue).setMinExpr(columnStat.minExpr)
-
.setMaxValue(columnStat.maxValue).setMaxExpr(columnStat.maxExpr)
- .build();
+ return new
ColumnStatisticBuilder().setCount(1D).setNdv(1D).setAvgSizeByte(width).setNumNulls(0)
+
.setDataSize(width).setMinValue(columnStat.minValue).setMaxValue(columnStat.maxValue)
+ .setSelectivity(1.0).setMaxExpr(null).setMinExpr(null).build();
}
@Override
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java
index 380d34dd1d..5f7b4cc3de 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/StatsCalculator.java
@@ -17,7 +17,6 @@
package org.apache.doris.nereids.stats;
-import org.apache.doris.analysis.IntLiteral;
import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.OlapTable;
@@ -39,9 +38,7 @@ import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.SlotReference;
import org.apache.doris.nereids.trees.expressions.WindowExpression;
import
org.apache.doris.nereids.trees.expressions.functions.agg.AggregateFunction;
-import org.apache.doris.nereids.trees.expressions.functions.agg.Count;
-import org.apache.doris.nereids.trees.expressions.functions.agg.Max;
-import org.apache.doris.nereids.trees.expressions.functions.agg.Min;
+import org.apache.doris.nereids.trees.expressions.functions.window.Rank;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.algebra.Aggregate;
import org.apache.doris.nereids.trees.plans.algebra.CatalogRelation;
@@ -684,20 +681,16 @@ public class StatsCalculator extends
DefaultPlanVisitor<Statistics, Void> {
}
private Statistics computePartitionTopN(PartitionTopN partitionTopN) {
- Statistics childStats = groupExpression.childStatistics(0);
- double rowCount = childStats.getRowCount();
+ Statistics stats = groupExpression.childStatistics(0);
+ double rowCount = stats.getRowCount();
List<Expression> partitionKeys = partitionTopN.getPartitionKeys();
if (!partitionTopN.hasGlobalLimit() && !partitionKeys.isEmpty()) {
// If there is no global limit. So result for the cardinality
estimation is:
// NDV(partition key) * partitionLimit
+ Map<Expression, ColumnStatistic> childSlotToColumnStats =
stats.columnStatistics();
List<ColumnStatistic> partitionByKeyStats = partitionKeys.stream()
- .map(partitionKey -> {
- ColumnStatistic partitionKeyStats =
childStats.findColumnStatistics(partitionKey);
- if (partitionKeyStats == null) {
- partitionKeyStats = new
ExpressionEstimation().visit(partitionKey, childStats);
- }
- return partitionKeyStats;
- })
+ .filter(childSlotToColumnStats::containsKey)
+ .map(childSlotToColumnStats::get)
.filter(s -> !s.isUnKnown)
.collect(Collectors.toList());
if (partitionByKeyStats.isEmpty()) {
@@ -705,7 +698,7 @@ public class StatsCalculator extends
DefaultPlanVisitor<Statistics, Void> {
rowCount = rowCount * DEFAULT_COLUMN_NDV_RATIO;
} else {
rowCount = Math.min(rowCount,
partitionByKeyStats.stream().map(s -> s.ndv)
- .max(Double::compare).get() *
partitionTopN.getPartitionLimit());
+ .max(Double::compare).get());
}
} else {
rowCount = Math.min(rowCount, partitionTopN.getPartitionLimit());
@@ -713,7 +706,7 @@ public class StatsCalculator extends
DefaultPlanVisitor<Statistics, Void> {
// TODO: for the filter push down window situation, we will prune the
row count twice
// because we keep the pushed down filter. And it will be calculated
twice, one of them in 'PartitionTopN'
// and the other is in 'Filter'. It's hard to dismiss.
- return childStats.updateRowCountOnly(rowCount);
+ return stats.updateRowCountOnly(rowCount);
}
private Statistics computeLimit(Limit limit) {
@@ -968,72 +961,42 @@ public class StatsCalculator extends
DefaultPlanVisitor<Statistics, Void> {
}
private Statistics computeWindow(Window windowOperator) {
- Statistics childStats = groupExpression.childStatistics(0);
- Map<Expression, ColumnStatistic> childColumnStats =
childStats.columnStatistics();
+ Statistics stats = groupExpression.childStatistics(0);
+ Map<Expression, ColumnStatistic> childColumnStats =
stats.columnStatistics();
Map<Expression, ColumnStatistic> columnStatisticMap =
windowOperator.getWindowExpressions().stream()
.map(expr -> {
- Preconditions.checkArgument(expr instanceof Alias
- && expr.child(0) instanceof WindowExpression,
- "need WindowExpression, but we meet " + expr);
- WindowExpression windExpr = (WindowExpression)
expr.child(0);
- ColumnStatisticBuilder colStatsBuilder = new
ColumnStatisticBuilder();
- colStatsBuilder.setCount(childStats.getRowCount())
- .setOriginal(null);
-
- Double partitionCount =
windExpr.getPartitionKeys().stream().map(key -> {
- ColumnStatistic keyStats =
childStats.findColumnStatistics(key);
- if (keyStats == null) {
- keyStats = new ExpressionEstimation().visit(key,
childStats);
- }
- return keyStats;
- })
- .filter(columnStatistic ->
!columnStatistic.isUnKnown)
- .map(colStats -> colStats.ndv).max(Double::compare)
- .orElseGet(() -> -1.0);
-
- if (partitionCount == -1.0) {
- // partition key stats are all unknown
- colStatsBuilder.setCount(childStats.getRowCount())
- .setNdv(1)
- .setMinValue(Double.NEGATIVE_INFINITY)
- .setMaxValue(Double.POSITIVE_INFINITY);
+ //estimate rank()
+ if (expr instanceof Alias && expr.child(0) instanceof
WindowExpression
+ && ((WindowExpression)
expr.child(0)).getFunction() instanceof Rank) {
+ ColumnStatisticBuilder colBuilder = new
ColumnStatisticBuilder();
+ colBuilder.setNdv(stats.getRowCount())
+ .setOriginal(null)
+ .setCount(stats.getRowCount())
+ .setMinValue(0)
+ .setMaxValue(stats.getRowCount());
+ return Pair.of(expr.toSlot(), colBuilder.build());
+ }
+ //estimate other expressions
+ ColumnStatistic value = null;
+ Set<Slot> slots = expr.getInputSlots();
+ if (slots.isEmpty()) {
+ value = ColumnStatistic.UNKNOWN;
} else {
- partitionCount = Math.max(1, partitionCount);
- if (windExpr.getFunction() instanceof
AggregateFunction) {
- if (windExpr.getFunction() instanceof Count) {
- colStatsBuilder.setNdv(1)
- .setMinValue(0)
- .setMinExpr(new IntLiteral(0))
- .setMaxValue(childStats.getRowCount())
- .setMaxExpr(new IntLiteral((long)
childStats.getRowCount()));
- } else if (windExpr.getFunction() instanceof Min
- || windExpr.getFunction() instanceof Max) {
- Expression minmaxChild =
windExpr.getFunction().child(0);
- ColumnStatistic minChildStats = new
ExpressionEstimation()
- .visit(minmaxChild, childStats);
- colStatsBuilder.setNdv(1)
- .setMinValue(minChildStats.minValue)
- .setMinExpr(minChildStats.minExpr)
- .setMaxValue(minChildStats.maxValue)
- .setMaxExpr(minChildStats.maxExpr);
- } else {
- // sum/avg
-
colStatsBuilder.setNdv(1).setMinValue(Double.NEGATIVE_INFINITY)
- .setMaxValue(Double.POSITIVE_INFINITY);
+ for (Slot slot : slots) {
+ if (childColumnStats.containsKey(slot)) {
+ value = childColumnStats.get(slot);
+ break;
}
- } else {
- // rank/dense_rank/row_num ...
- colStatsBuilder.setNdv(childStats.getRowCount() /
partitionCount)
- .setMinValue(0)
- .setMinExpr(new IntLiteral(0))
- .setMaxValue(childStats.getRowCount())
- .setMaxExpr(new IntLiteral((long)
childStats.getRowCount()));
+ }
+ if (value == null) {
+ // todo: how to set stats?
+ value = ColumnStatistic.UNKNOWN;
}
}
- return Pair.of(expr.toSlot(), colStatsBuilder.build());
+ return Pair.of(expr.toSlot(), value);
}).collect(Collectors.toMap(Pair::key, Pair::value));
columnStatisticMap.putAll(childColumnStats);
- return new Statistics(childStats.getRowCount(), columnStatisticMap);
+ return new Statistics(stats.getRowCount(), columnStatisticMap);
}
private ColumnStatistic unionColumn(ColumnStatistic leftStats, double
leftRowCount, ColumnStatistic rightStats,
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalPartitionTopN.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalPartitionTopN.java
index 4166e7d903..ce57ad0782 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalPartitionTopN.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalPartitionTopN.java
@@ -183,8 +183,7 @@ public class PhysicalPartitionTopN<CHILD_TYPE extends Plan>
extends PhysicalUnar
"partitionKeys", partitionKeys,
"orderKeys", orderKeys,
"hasGlobalLimit", hasGlobalLimit,
- "partitionLimit", partitionLimit,
- "stats", statistics
+ "partitionLimit", partitionLimit
);
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalQuickSort.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalQuickSort.java
index 57c77cc4fb..5981c8e538 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalQuickSort.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalQuickSort.java
@@ -103,7 +103,7 @@ public class PhysicalQuickSort<CHILD_TYPE extends Plan>
extends AbstractPhysical
public String toString() {
return Utils.toSqlString("PhysicalQuickSort[" + id.asInt() + "]" +
getGroupIdWithPrefix(),
"orderKeys", orderKeys,
- "phase", phase.toString(), "stats", statistics
+ "phase", phase.toString()
);
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalWindow.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalWindow.java
index b1703f4749..5632e970a3 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalWindow.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/physical/PhysicalWindow.java
@@ -106,7 +106,7 @@ public class PhysicalWindow<CHILD_TYPE extends Plan>
extends PhysicalUnary<CHILD
public String toString() {
return Utils.toSqlString("PhysicalWindow[" + id.asInt() + "]" +
getGroupIdWithPrefix(),
"windowFrameGroup", windowFrameGroup,
- "requiredProperties", requireProperties, "stats", statistics
+ "requiredProperties", requireProperties
);
}
diff --git
a/regression-test/data/nereids_tpcds_shape_sf100_p0/shape/query44.out
b/regression-test/data/nereids_tpcds_shape_sf100_p0/shape/query44.out
index 8028e752fd..ef988f8e86 100644
--- a/regression-test/data/nereids_tpcds_shape_sf100_p0/shape/query44.out
+++ b/regression-test/data/nereids_tpcds_shape_sf100_p0/shape/query44.out
@@ -5,11 +5,11 @@ PhysicalResultSink
----PhysicalDistribute
------PhysicalTopN
--------PhysicalProject
-----------hashJoin[INNER_JOIN](asceding.rnk = descending.rnk)
+----------hashJoin[INNER_JOIN](i1.i_item_sk = asceding.item_sk)
+------------PhysicalProject
+--------------PhysicalOlapScan[item]
------------PhysicalDistribute
---------------hashJoin[INNER_JOIN](i1.i_item_sk = asceding.item_sk)
-----------------PhysicalProject
-------------------PhysicalOlapScan[item]
+--------------hashJoin[INNER_JOIN](asceding.rnk = descending.rnk)
----------------PhysicalDistribute
------------------PhysicalProject
--------------------filter((rnk < 11))
@@ -36,34 +36,34 @@ PhysicalResultSink
--------------------------------------------------PhysicalProject
----------------------------------------------------filter(ss_addr_sk IS
NULL(store_sales.ss_store_sk = 146))
------------------------------------------------------PhysicalOlapScan[store_sales]
-------------PhysicalDistribute
---------------hashJoin[INNER_JOIN](i2.i_item_sk = descending.item_sk)
-----------------PhysicalProject
-------------------PhysicalOlapScan[item]
----------------PhysicalDistribute
-------------------PhysicalProject
---------------------filter((rnk < 11))
-----------------------PhysicalWindow
-------------------------PhysicalQuickSort
---------------------------PhysicalDistribute
+------------------hashJoin[INNER_JOIN](i2.i_item_sk = descending.item_sk)
+--------------------PhysicalProject
+----------------------PhysicalOlapScan[item]
+--------------------PhysicalDistribute
+----------------------PhysicalProject
+------------------------filter((rnk < 11))
+--------------------------PhysicalWindow
----------------------------PhysicalQuickSort
-------------------------------PhysicalPartitionTopN
---------------------------------PhysicalProject
-----------------------------------NestedLoopJoin[INNER_JOIN](cast(rank_col as
DOUBLE) > cast((0.9 * rank_col) as DOUBLE))
-------------------------------------hashAgg[GLOBAL]
---------------------------------------PhysicalDistribute
-----------------------------------------hashAgg[LOCAL]
-------------------------------------------PhysicalProject
---------------------------------------------filter((ss1.ss_store_sk = 146))
-----------------------------------------------PhysicalOlapScan[store_sales]
-------------------------------------PhysicalDistribute
---------------------------------------PhysicalAssertNumRows
+------------------------------PhysicalDistribute
+--------------------------------PhysicalQuickSort
+----------------------------------PhysicalPartitionTopN
+------------------------------------PhysicalProject
+--------------------------------------NestedLoopJoin[INNER_JOIN](cast(rank_col
as DOUBLE) > cast((0.9 * rank_col) as DOUBLE))
+----------------------------------------hashAgg[GLOBAL]
+------------------------------------------PhysicalDistribute
+--------------------------------------------hashAgg[LOCAL]
+----------------------------------------------PhysicalProject
+------------------------------------------------filter((ss1.ss_store_sk = 146))
+--------------------------------------------------PhysicalOlapScan[store_sales]
----------------------------------------PhysicalDistribute
-------------------------------------------PhysicalProject
---------------------------------------------hashAgg[GLOBAL]
-----------------------------------------------PhysicalDistribute
-------------------------------------------------hashAgg[LOCAL]
---------------------------------------------------PhysicalProject
-----------------------------------------------------filter(ss_addr_sk IS
NULL(store_sales.ss_store_sk = 146))
-------------------------------------------------------PhysicalOlapScan[store_sales]
+------------------------------------------PhysicalAssertNumRows
+--------------------------------------------PhysicalDistribute
+----------------------------------------------PhysicalProject
+------------------------------------------------hashAgg[GLOBAL]
+--------------------------------------------------PhysicalDistribute
+----------------------------------------------------hashAgg[LOCAL]
+------------------------------------------------------PhysicalProject
+--------------------------------------------------------filter(ss_addr_sk IS
NULL(store_sales.ss_store_sk = 146))
+----------------------------------------------------------PhysicalOlapScan[store_sales]
diff --git
a/regression-test/data/nereids_tpcds_shape_sf100_p0/shape/query47.out
b/regression-test/data/nereids_tpcds_shape_sf100_p0/shape/query47.out
index 3c6bf21b99..b705f7a2cb 100644
--- a/regression-test/data/nereids_tpcds_shape_sf100_p0/shape/query47.out
+++ b/regression-test/data/nereids_tpcds_shape_sf100_p0/shape/query47.out
@@ -36,16 +36,17 @@ PhysicalCteAnchor ( cteId=CTEId#0 )
----------PhysicalTopN
------------PhysicalProject
--------------hashJoin[INNER_JOIN](v1.i_category =
v1_lead.i_category)(v1.i_brand = v1_lead.i_brand)(v1.s_store_name =
v1_lead.s_store_name)(v1.s_company_name = v1_lead.s_company_name)(v1.rn =
expr_(rn - 1))
-----------------PhysicalProject
-------------------hashJoin[INNER_JOIN](v1.i_category =
v1_lag.i_category)(v1.i_brand = v1_lag.i_brand)(v1.s_store_name =
v1_lag.s_store_name)(v1.s_company_name = v1_lag.s_company_name)(v1.rn =
expr_(rn + 1))
---------------------PhysicalDistribute
-----------------------PhysicalProject
-------------------------PhysicalCteConsumer ( cteId=CTEId#0 )
---------------------PhysicalDistribute
-----------------------PhysicalProject
-------------------------filter((CASE WHEN (avg_monthly_sales > 0.0000) THEN
(abs((cast(sum_sales as DOUBLE) - cast(avg_monthly_sales as DOUBLE))) /
cast(avg_monthly_sales as DOUBLE)) ELSE NULL END > 0.1)(v2.d_year =
2001)(v2.avg_monthly_sales > 0.0000))
---------------------------PhysicalCteConsumer ( cteId=CTEId#0 )
----------------PhysicalDistribute
------------------PhysicalProject
--------------------PhysicalCteConsumer ( cteId=CTEId#0 )
+----------------PhysicalDistribute
+------------------PhysicalProject
+--------------------hashJoin[INNER_JOIN](v1.i_category =
v1_lag.i_category)(v1.i_brand = v1_lag.i_brand)(v1.s_store_name =
v1_lag.s_store_name)(v1.s_company_name = v1_lag.s_company_name)(v1.rn =
expr_(rn + 1))
+----------------------PhysicalDistribute
+------------------------PhysicalProject
+--------------------------PhysicalCteConsumer ( cteId=CTEId#0 )
+----------------------PhysicalDistribute
+------------------------PhysicalProject
+--------------------------filter((CASE WHEN (avg_monthly_sales > 0.0000) THEN
(abs((cast(sum_sales as DOUBLE) - cast(avg_monthly_sales as DOUBLE))) /
cast(avg_monthly_sales as DOUBLE)) ELSE NULL END > 0.1)(v2.d_year =
2001)(v2.avg_monthly_sales > 0.0000))
+----------------------------PhysicalCteConsumer ( cteId=CTEId#0 )
diff --git
a/regression-test/data/nereids_tpcds_shape_sf100_p0/shape/query57.out
b/regression-test/data/nereids_tpcds_shape_sf100_p0/shape/query57.out
index 71c2cdd060..2e7f06968a 100644
--- a/regression-test/data/nereids_tpcds_shape_sf100_p0/shape/query57.out
+++ b/regression-test/data/nereids_tpcds_shape_sf100_p0/shape/query57.out
@@ -36,16 +36,18 @@ PhysicalCteAnchor ( cteId=CTEId#0 )
--------PhysicalDistribute
----------PhysicalTopN
------------PhysicalProject
---------------hashJoin[INNER_JOIN](v1.i_category =
v1_lag.i_category)(v1.i_brand = v1_lag.i_brand)(v1.cc_name =
v1_lag.cc_name)(v1.rn = expr_(rn + 1))
-----------------hashJoin[INNER_JOIN](v1.i_category =
v1_lead.i_category)(v1.i_brand = v1_lead.i_brand)(v1.cc_name =
v1_lead.cc_name)(v1.rn = expr_(rn - 1))
-------------------PhysicalDistribute
---------------------PhysicalProject
-----------------------PhysicalCteConsumer ( cteId=CTEId#0 )
-------------------PhysicalDistribute
---------------------PhysicalProject
-----------------------filter((CASE WHEN (avg_monthly_sales > 0.0000) THEN
(abs((cast(sum_sales as DOUBLE) - cast(avg_monthly_sales as DOUBLE))) /
cast(avg_monthly_sales as DOUBLE)) ELSE NULL END > 0.1)(v2.d_year =
1999)(v2.avg_monthly_sales > 0.0000))
-------------------------PhysicalCteConsumer ( cteId=CTEId#0 )
+--------------hashJoin[INNER_JOIN](v1.i_category =
v1_lead.i_category)(v1.i_brand = v1_lead.i_brand)(v1.cc_name =
v1_lead.cc_name)(v1.rn = expr_(rn - 1))
----------------PhysicalDistribute
------------------PhysicalProject
--------------------PhysicalCteConsumer ( cteId=CTEId#0 )
+----------------PhysicalDistribute
+------------------PhysicalProject
+--------------------hashJoin[INNER_JOIN](v1.i_category =
v1_lag.i_category)(v1.i_brand = v1_lag.i_brand)(v1.cc_name =
v1_lag.cc_name)(v1.rn = expr_(rn + 1))
+----------------------PhysicalDistribute
+------------------------PhysicalProject
+--------------------------PhysicalCteConsumer ( cteId=CTEId#0 )
+----------------------PhysicalDistribute
+------------------------PhysicalProject
+--------------------------filter((CASE WHEN (avg_monthly_sales > 0.0000) THEN
(abs((cast(sum_sales as DOUBLE) - cast(avg_monthly_sales as DOUBLE))) /
cast(avg_monthly_sales as DOUBLE)) ELSE NULL END > 0.1)(v2.d_year =
1999)(v2.avg_monthly_sales > 0.0000))
+----------------------------PhysicalCteConsumer ( cteId=CTEId#0 )
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]