diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/ColumnStatsAdjustVisitor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/ColumnStatsAdjustVisitor.java new file mode 100644 index 0000000000..1f789f7deb --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/stats/ColumnStatsAdjustVisitor.java @@ -0,0 +1,64 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.doris.nereids.stats; + +import org.apache.doris.nereids.trees.expressions.Cast; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; +import org.apache.doris.statistics.ColumnStatistic; +import org.apache.doris.statistics.Statistics; + +/** + * table: T(A, B) + * T.stats = (rows=10, + * { + * A->ndv=10, rows=10 + * B->... + * } + * ) + * after node: filter(cast(A as double)=1.0) + * filter.stats = (rows = 1 + * { + * A->ndv=m, rows=1 + * B->ndv=m, rows=1 + * cast(A as double) -> ndv=1, rows=1 + * } + * ) + * + * m is computed by function computeNdv() + * + * filter.stats should be adjusted. + * A.columnStats should be equal to "cast(A as double)".columnStats + * for other expressions(except cast), we also need to adjust their input column stats. + * + */ +public class ColumnStatsAdjustVisitor extends ExpressionVisitor { + @Override + public ColumnStatistic visit(Expression expr, Statistics context) { + expr.children().forEach(child -> child.accept(this, context)); + return null; + } + + public ColumnStatistic visitCast(Cast cast, Statistics context) { + ColumnStatistic colStats = context.findColumnStatistics(cast); + if (colStats != null) { + context.addColumnStats(cast.child(), colStats); + } + return null; + } +} 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 93c20a986c..782609afd5 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 @@ -141,6 +141,10 @@ public class ExpressionEstimation extends ExpressionVisitor()); + stats.addColumnStats(a, builder.build()); + FilterEstimation filterEstimation = new FilterEstimation(); + Statistics result = filterEstimation.estimate(and, stats); + Assertions.assertEquals(result.getRowCount(), 10, 0.01); + ColumnStatistic colStats = result.findColumnStatistics(a); + Assertions.assertTrue(colStats != null); + Assertions.assertEquals(10, colStats.ndv, 0.1); + } }