morrySnow commented on code in PR #35610:
URL: https://github.com/apache/doris/pull/35610#discussion_r1618730000


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/stats/FilterEstimation.java:
##########
@@ -210,14 +217,109 @@ private Statistics 
calculateWhenLiteralRight(ComparisonPredicate cp,
         if (cp instanceof EqualPredicate) {
             return estimateEqualTo(cp, statsForLeft, statsForRight, context);
         } else {
+            // literal Map used to covert dateLiteral back to stringLiteral
+            Map<DateLiteral, StringLiteral> literalMap = new HashMap<>();
+            DataType compareType = cp.left().getDataType();
+            ColumnStatistic statsForLeftMayConverted = 
tryConvertStringColStatsToDateColStats(statsForLeft, literalMap);
+            ColumnStatistic statsForRightMayConverted = null;
+            if (statsForLeftMayConverted != null) {
+                statsForRightMayConverted = 
tryConvertStringColStatsToDateColStats(statsForRight, literalMap);
+            }
+            boolean converted = false;
+            if (statsForLeftMayConverted == null || statsForRightMayConverted 
== null
+                    || statsForRightMayConverted.minExpr.getType() != 
statsForLeftMayConverted.minExpr.getType()) {
+                // do not convert str -> date
+                statsForLeftMayConverted = statsForLeft;
+                statsForRightMayConverted = statsForRight;
+            } else {
+                // converted
+                converted = true;
+                compareType = DateTimeType.INSTANCE;
+            }
+            Statistics result = null;
             if (cp instanceof LessThan || cp instanceof LessThanEqual) {
-                return updateLessThanLiteral(cp.left(), statsForLeft, 
statsForRight, context);
+                result = updateLessThanLiteral(cp.left(), compareType, 
statsForLeftMayConverted,
+                        statsForRightMayConverted, context);
             } else if (cp instanceof GreaterThan || cp instanceof 
GreaterThanEqual) {
-                return updateGreaterThanLiteral(cp.left(), statsForLeft, 
statsForRight, context);
+                result = updateGreaterThanLiteral(cp.left(), compareType, 
statsForLeftMayConverted,
+                        statsForRightMayConverted, context);
             } else {
                 throw new RuntimeException(String.format("Unexpected 
expression : %s", cp.toSql()));
             }
+            if (converted) {
+                // convert min/max of left.colStats back to string type
+                ColumnStatistic newLeftStats = 
result.findColumnStatistics(cp.left());
+                result.addColumnStats(cp.left(), 
convertDateColStatsToStringColStats(newLeftStats, literalMap));
+            }
+            return result;
+        }
+    }
+
+    private ColumnStatistic 
convertDateColStatsToStringColStats(ColumnStatistic colStats,
+            Map<DateLiteral, StringLiteral> literalMap) {
+        if (colStats.minExpr == null && colStats.maxExpr == null) {
+            // when sel=0, minExpr and maxExpr are both null
+            return colStats;
+        }
+        Preconditions.checkArgument(colStats.minExpr instanceof DateLiteral
+                        && colStats.maxExpr instanceof DateLiteral,
+                "cannot convert colStats back to stringType %s", 
colStats.toString());
+        ColumnStatisticBuilder builder = new ColumnStatisticBuilder(colStats);
+        StringLiteral newMinLiteral = new 
StringLiteral(colStats.maxExpr.toString());
+        return builder.setMaxExpr(newMinLiteral)
+                .setMaxExpr(literalMap.get(colStats.maxExpr))
+                
.setMaxValue(StringLikeLiteral.getDouble(colStats.maxExpr.toString()))
+                .setMinExpr(literalMap.get(colStats.minExpr))
+                
.setMinValue(StringLikeLiteral.getDouble(colStats.minExpr.getStringValue()))
+                .build();
+    }
+
+    private ColumnStatistic 
tryConvertStringColStatsToDateColStats(ColumnStatistic colStats,
+            Map<DateLiteral, StringLiteral> literalMap) {
+        if (colStats.minExpr == null || colStats.maxExpr == null) {
+            return null;

Review Comment:
   nit: use Optional if we maybe return null



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/stats/FilterEstimation.java:
##########
@@ -17,7 +17,9 @@
 
 package org.apache.doris.nereids.stats;
 
+import org.apache.doris.analysis.DateLiteral;

Review Comment:
   why use legacy planner's DateLiteral? because ColumnStatistic' expr is 
legacy literal? i think we need to update Expr in ColumnStatistic to Nereids' 
literal in future



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/stats/FilterEstimation.java:
##########
@@ -183,22 +190,22 @@ public Statistics 
visitComparisonPredicate(ComparisonPredicate cp, EstimationCon
         }
     }
 
-    private Statistics updateLessThanLiteral(Expression leftExpr, 
ColumnStatistic statsForLeft,
+    private Statistics updateLessThanLiteral(Expression leftExpr, DataType 
dataType, ColumnStatistic statsForLeft,
             ColumnStatistic statsForRight, EstimationContext context) {
         StatisticRange rightRange = new StatisticRange(statsForLeft.minValue, 
statsForLeft.minExpr,
                 statsForRight.maxValue, statsForRight.maxExpr,
-                statsForLeft.ndv, leftExpr.getDataType());
-        return estimateBinaryComparisonFilter(leftExpr,
+                statsForLeft.ndv, dataType);
+        return estimateBinaryComparisonFilter(leftExpr, dataType,
                 statsForLeft,
                 rightRange, context);
     }
 
-    private Statistics updateGreaterThanLiteral(Expression leftExpr, 
ColumnStatistic statsForLeft,
+    private Statistics updateGreaterThanLiteral(Expression leftExpr, DataType 
dataTyp, ColumnStatistic statsForLeft,

Review Comment:
   ```suggestion
       private Statistics updateGreaterThanLiteral(Expression leftExpr, 
DataType dataType, ColumnStatistic statsForLeft,
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to