Manya0407 commented on code in PR #6746:
URL: https://github.com/apache/hive/pull/6746#discussion_r4014072578


##########
ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/stats/FilterSelectivityEstimator.java:
##########
@@ -484,19 +484,261 @@ private Double 
computeRangePredicateSelectivity(Supplier<Double> defaultSelectiv
     }
 
     final List<ColStatistics> colStats = 
scan.getColStat(Collections.singletonList(inputRefIndex));
-    if (colStats.isEmpty() || !isHistogramAvailable(colStats.get(0))) {
+    if (colStats.isEmpty()) {
       return defaultSelectivity.get();
     }
 
-    final KllFloatsSketch kll = 
KllFloatsSketch.heapify(Memory.wrap(colStats.get(0).getHistogram()));
-    double rawSelectivity = rangedSelectivity(kll, boundaries);
+    final ColStatistics cs = colStats.get(0);
+    if (isHistogramAvailable(cs)) {
+      final KllFloatsSketch kll = 
KllFloatsSketch.heapify(Memory.wrap(cs.getHistogram()));
+      double rawSelectivity = rangedSelectivity(kll, boundaries);
+      if (inverseBool) {
+        // when inverseBool == true, this is a NOT_BETWEEN and selectivity 
must be inverted
+        // if there's a cast, the inversion is with respect to its codomain 
(range of the values of the cast)
+        double typeRangeSelectivity = rangedSelectivity(kll, typeRange);
+        rawSelectivity = typeRangeSelectivity - rawSelectivity;
+      }
+      return scaleSelectivityToNullableValues(kll, rawSelectivity, scan);
+    }
+
+    if (isUniformWithinRangeEnabled() && hasUsableMinMax(cs)) {
+      RelDataType columnType = 
scan.getRowType().getFieldList().get(inputRefIndex).getType();
+      Double uniformSelectivity = computeUniformRangeSelectivity(cs, 
boundaries, scan, inverseBool, typeRange,
+          columnType);
+      if (uniformSelectivity != null) {
+        return uniformSelectivity;
+      }
+    }
+
+    return defaultSelectivity.get();
+  }
+
+  private boolean isUniformWithinRangeEnabled() {
+    HiveConfPlannerContext ctx =
+        
childRel.getCluster().getPlanner().getContext().unwrap(HiveConfPlannerContext.class);
+    return ctx == null || ctx.isUniformWithinRange();
+  }
+
+  private static boolean hasUsableMinMax(ColStatistics cs) {
+    ColStatistics.Range range = cs.getRange();
+    return range != null && range.minValue != null && range.maxValue != null;
+  }
+
+  /**
+   * Converts column MIN/MAX statistics into the same numeric space used by 
{@link #extractLiteral}.
+   * DATE column stats from HMS are stored as days since epoch; literals use 
epoch seconds.
+   */
+  private static Optional<float[]> convertColRangeToFloatBounds(ColStatistics 
cs, RelDataType columnType) {
+    ColStatistics.Range range = cs.getRange();
+    if (range == null || range.minValue == null || range.maxValue == null) {
+      return Optional.empty();
+    }
+    final float min;
+    final float max;
+    switch (columnType.getSqlTypeName()) {
+    case DATE:
+      min = range.minValue.longValue() * 86400L;
+      max = range.maxValue.longValue() * 86400L;
+      break;
+    case TIMESTAMP:
+      min = range.minValue.longValue();
+      max = range.maxValue.longValue();
+      break;
+    case TINYINT:
+      min = range.minValue.byteValue();
+      max = range.maxValue.byteValue();
+      break;
+    case SMALLINT:
+      min = range.minValue.shortValue();
+      max = range.maxValue.shortValue();
+      break;
+    case INTEGER:
+      min = range.minValue.intValue();
+      max = range.maxValue.intValue();
+      break;
+    case BIGINT:
+      min = range.minValue.longValue();
+      max = range.maxValue.longValue();
+      break;
+    case FLOAT:
+      min = range.minValue.floatValue();
+      max = range.maxValue.floatValue();
+      break;
+    case DOUBLE:
+      min = (float) range.minValue.doubleValue();
+      max = (float) range.maxValue.doubleValue();
+      break;

Review Comment:
   Addressed and brought in the fix -The per-type branches (byteValue, 
intValue, longValue, etc.) are replaced with a single combined case using 
Number#floatValue() for TINYINT through TIMESTAMP/DECIMAL. DATE still has 
special handling (days×86400) to align with CBO literal extraction. Agreed that 
switching to double/Double is out of scope for this PR; we can consider that 
separately if needed.



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