pick from #37235 the algorithm for computing stats for "expr1 and expr2" predicate is as following: 1. compute output stats of expr1 based on input stats. the result stats is denoted by leftStats 2. compute stats of expr2 based on leftStats after step1, leftStats should be normalized to avoid abnormal cases, such as ndv > rowCount or numNulls > rowCount Issue Number: close #xxx <!--Describe your changes.--> ## Proposed changes Issue Number: close #xxx <!--Describe your changes.-->
This commit is contained in:
@ -110,6 +110,7 @@ public class FilterEstimation extends ExpressionVisitor<Statistics, EstimationCo
|
||||
Expression leftExpr = predicate.child(0);
|
||||
Expression rightExpr = predicate.child(1);
|
||||
Statistics leftStats = leftExpr.accept(this, context);
|
||||
leftStats = leftStats.normalizeByRatio(context.statistics.getRowCount());
|
||||
Statistics andStats = rightExpr.accept(this,
|
||||
new EstimationContext(leftStats));
|
||||
if (predicate instanceof And) {
|
||||
|
||||
@ -204,4 +204,22 @@ public class Statistics {
|
||||
public int getWidthInJoinCluster() {
|
||||
return widthInJoinCluster;
|
||||
}
|
||||
|
||||
public Statistics normalizeByRatio(double originRowCount) {
|
||||
if (rowCount >= originRowCount || rowCount <= 0) {
|
||||
return this;
|
||||
}
|
||||
StatisticsBuilder builder = new StatisticsBuilder(this);
|
||||
double ratio = rowCount / originRowCount;
|
||||
for (Entry<Expression, ColumnStatistic> entry : expressionToColumnStats.entrySet()) {
|
||||
ColumnStatistic colStats = entry.getValue();
|
||||
if (colStats.numNulls != 0 || colStats.ndv > rowCount) {
|
||||
ColumnStatisticBuilder colStatsBuilder = new ColumnStatisticBuilder(colStats);
|
||||
colStatsBuilder.setNumNulls(colStats.numNulls * ratio);
|
||||
colStatsBuilder.setNdv(Math.min(rowCount - colStatsBuilder.getNumNulls(), colStats.ndv));
|
||||
builder.putColumnStatistics(entry.getKey(), colStatsBuilder.build());
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user