Copilot commented on code in PR #6505:
URL: https://github.com/apache/hive/pull/6505#discussion_r4461508318


##########
ql/src/java/org/apache/hadoop/hive/ql/optimizer/stats/annotation/StatsRulesProcFactory.java:
##########
@@ -558,18 +558,25 @@ private long evaluateInExpr(Statistics stats, 
ExprNodeDesc pred, long currNumRow
         factor *= children.size() - 1;
       }
       for (int i = 0; i < columnStats.size(); i++) {
-        long dvs = columnStats.get(i) == null ? 0 : 
columnStats.get(i).getCountDistint();
+        ColStatistics cs = columnStats.get(i);
+        long dvs = cs == null ? -1L : cs.getCountDistint();
         if (dvs == 0) {
-          factor *= 0.5;
-          continue;
+          // verified zero distinct values: IN cannot match any row
+          factor = 0;
+          break;

Review Comment:
   Setting `factor` to 0 does not preserve the verified-zero estimate when 
`hive.stats.filter.in.min.ratio` is positive. For stats without a min/max 
range, such as an all-NULL string column, `allColsFilteredByStats` is false and 
the later minimum-ratio clamp raises it again (1,000 rows with a 0.1 minimum 
become 100 estimated matches). Return 0 immediately so a verified empty domain 
bypasses the fallback for uncertain statistics.



##########
ql/src/java/org/apache/hadoop/hive/ql/optimizer/stats/annotation/StatsRulesProcFactory.java:
##########
@@ -1381,6 +1384,16 @@ private long evaluateChildExpr(Statistics stats, 
ExprNodeDesc child,
       return numRows / 2;
     }
 
+    private static long rowsAfterEqualityFilter(long numRows, long dvs) {
+      if (dvs < 0) {
+        return numRows / 2;
+      }
+      if (dvs == 0) {
+        return 0;

Review Comment:
   `GenericUDFOPEqualNS` extends `GenericUDFOPEqual`, so null-safe comparisons 
also reach this helper. An all-NULL column has NDV 0, but `col IS NOT DISTINCT 
FROM NULL` matches every row; returning zero therefore severely underestimates 
this filter. Handle null-safe equality against NULL using `numNulls` before the 
NDV-only helper, and cover both operand orders.



##########
ql/src/java/org/apache/hadoop/hive/ql/optimizer/stats/annotation/StatsRulesProcFactory.java:
##########
@@ -1820,9 +1835,24 @@ private boolean checkMapSideAggregation(GroupByOperator 
gop,
 
         // estimate size of key from column statistics
         long avgKeySize = 0;
+        // lazily computed on first unknown NDV (null = not yet looked up)
+        Long parentNumRows = null;
         for (ColStatistics cs : colStats) {
           if (cs != null) {
-            numEstimatedRows = StatsUtils.safeMult(numEstimatedRows, 
cs.getCountDistint());
+            long ndv = cs.getCountDistint();
+            if (ndv < 0) {
+              if (parentNumRows == null) {
+                // unknown NDV: fall back to parentNumRows / 2, matching the 
heuristic
+                // used elsewhere in this file when GROUP BY cardinality 
cannot be computed
+                Statistics parentStats = 
gop.getParentOperators().get(0).getStatistics();
+                parentNumRows = (parentStats != null) ? 
parentStats.getNumRows() : -1L;
+              }
+              if (parentNumRows <= 0) {
+                return false;
+              }
+              ndv = parentNumRows / 2;
+            }
+            numEstimatedRows = StatsUtils.safeMult(numEstimatedRows, ndv);

Review Comment:
   Applying `parentNumRows / 2` separately to every unknown key estimates 
25,000,000 groups for 10,000 rows and two unknown-NDV keys. Without grouping 
sets, at most 10,000 groups can exist, so the inflated memory estimate can 
incorrectly send cardinality estimation through the no-hash-aggregation branch. 
Cap the combined estimate at the input-row count, accounting for grouping-set 
expansion when present.



-- 
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