From 4af3fd2a2e29696d0350d834b29a528c7a5a40ad Mon Sep 17 00:00:00 2001 From: minghong Date: Tue, 23 Jan 2024 19:07:28 +0800 Subject: [PATCH] [fix](Nereids) fix bug in case-when/if stats estimation (#30265) --- .../nereids/stats/ExpressionEstimation.java | 68 ++++++++++++++----- .../stats/ExpressionEstimationTest.java | 63 +++++++++++++++++ 2 files changed, 114 insertions(+), 17 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 acf6bddfe5..874f47a50a 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 @@ -39,6 +39,7 @@ import org.apache.doris.nereids.trees.expressions.SlotReference; import org.apache.doris.nereids.trees.expressions.Subtract; import org.apache.doris.nereids.trees.expressions.TimestampArithmetic; import org.apache.doris.nereids.trees.expressions.VirtualSlotReference; +import org.apache.doris.nereids.trees.expressions.WhenClause; import org.apache.doris.nereids.trees.expressions.functions.BoundFunction; import org.apache.doris.nereids.trees.expressions.functions.agg.Avg; import org.apache.doris.nereids.trees.expressions.functions.agg.Count; @@ -137,21 +138,37 @@ public class ExpressionEstimation extends ExpressionVisitor slotToColumnStat = new HashMap<>(); + ColumnStatisticBuilder builder = new ColumnStatisticBuilder() + .setNdv(100) + .setMinExpr(new StringLiteral("2020-01-01")) + .setMinValue(20200101000000.0) + .setMaxExpr(new StringLiteral("2021abcdefg")) + .setMaxValue(20210101000000.0); + slotToColumnStat.put(a, builder.build()); + SlotReference b = new SlotReference("b", StringType.INSTANCE); + builder = new ColumnStatisticBuilder() + .setNdv(10) + .setMinExpr(new StringLiteral("2020-01-01")) + .setMinValue(20200101000000.0) + .setMaxExpr(new StringLiteral("2021abcdefg")) + .setMaxValue(20210101000000.0); + slotToColumnStat.put(b, builder.build()); + Statistics stats = new Statistics(1000, slotToColumnStat); + + WhenClause when1 = new WhenClause(BooleanLiteral.TRUE, a); + WhenClause when2 = new WhenClause(BooleanLiteral.FALSE, b); + List whens = new ArrayList<>(); + whens.add(when1); + whens.add(when2); + CaseWhen caseWhen = new CaseWhen(whens); + ColumnStatistic est = ExpressionEstimation.estimate(caseWhen, stats); + Assertions.assertEquals(est.ndv, 100); + } + + @Test + public void testIf() { + SlotReference a = new SlotReference("a", StringType.INSTANCE); + Map slotToColumnStat = new HashMap<>(); + ColumnStatisticBuilder builder = new ColumnStatisticBuilder() + .setNdv(100) + .setMinExpr(new StringLiteral("2020-01-01")) + .setMinValue(20200101000000.0) + .setMaxExpr(new StringLiteral("2021abcdefg")) + .setMaxValue(20210101000000.0); + slotToColumnStat.put(a, builder.build()); + SlotReference b = new SlotReference("b", StringType.INSTANCE); + builder = new ColumnStatisticBuilder() + .setNdv(10) + .setMinExpr(new StringLiteral("2020-01-01")) + .setMinValue(20200101000000.0) + .setMaxExpr(new StringLiteral("2021abcdefg")) + .setMaxValue(20210101000000.0); + slotToColumnStat.put(b, builder.build()); + Statistics stats = new Statistics(1000, slotToColumnStat); + + If ifClause = new If(BooleanLiteral.TRUE, a, b); + ColumnStatistic est = ExpressionEstimation.estimate(ifClause, stats); + Assertions.assertEquals(est.ndv, 100); + } }