korlov42 commented on a change in pull request #9276:
URL: https://github.com/apache/ignite/pull/9276#discussion_r695151322



##########
File path: 
modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdSelectivity.java
##########
@@ -110,6 +121,646 @@ public Double getSelectivity(IgniteSortedIndexSpool rel, 
RelMetadataQuery mq, Re
     }
 
     /** */
+    public Double getSelectivity(RelSubset rel, RelMetadataQuery mq, RexNode 
predicate) {
+        RelNode best = rel.getBest();
+        if (best == null)
+            return super.getSelectivity(rel, mq, predicate);
+
+        return getSelectivity(best, mq, predicate);
+    }
+
+    /**
+     * Convert specified value into comparable type: BigDecimal,
+     *
+     * @param val Value to convert to comparable form.
+     * @return Comparable form of value.
+     */
+    private BigDecimal toComparableValue(RexLiteral val) {
+        RelDataType type = val.getType();
+
+        if (type instanceof BasicSqlType) {
+            BasicSqlType bType = (BasicSqlType)type;
+
+            switch ((SqlTypeFamily)bType.getFamily()) {
+                case NULL:
+                    return null;
+
+                case NUMERIC:
+                    return val.getValueAs(BigDecimal.class);
+
+                case DATE:
+                    return new 
BigDecimal(val.getValueAs(DateString.class).getMillisSinceEpoch());
+
+                case TIME:
+                    return new 
BigDecimal(val.getValueAs(TimeString.class).getMillisOfDay());
+
+                case TIMESTAMP:
+                    return new 
BigDecimal(val.getValueAs(TimestampString.class).getMillisSinceEpoch());
+
+                case BOOLEAN:
+                    return (val.getValueAs(Boolean.class)) ? BigDecimal.ONE : 
BigDecimal.ZERO;
+
+                default:
+                    return null;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Convert specified value into comparable type: BigDecimal,
+     *
+     * @param val Value to convert to comparable form.
+     * @return Comparable form of value.
+     */
+    private BigDecimal toComparableValue(Value val) {
+        if (val == null)
+            return null;
+
+        switch (val.getType()) {
+            case Value.NULL:
+                throw new IllegalArgumentException("Can't compare null 
values");
+
+            case Value.BOOLEAN:
+                return (val.getBoolean()) ? BigDecimal.ONE : BigDecimal.ZERO;
+
+            case Value.BYTE:
+                return new BigDecimal(val.getByte());
+
+            case Value.SHORT:
+                return new BigDecimal(val.getShort());
+
+            case Value.INT:
+                return new BigDecimal(val.getInt());
+
+            case Value.LONG:
+                return new BigDecimal(val.getLong());
+
+            case Value.DECIMAL:
+                return val.getBigDecimal();
+
+            case Value.DOUBLE:
+                return BigDecimal.valueOf(val.getDouble());
+
+            case Value.FLOAT:
+                return BigDecimal.valueOf(val.getFloat());
+
+            case Value.DATE:
+                return BigDecimal.valueOf(val.getDate().getTime());
+
+            case Value.TIME:
+                return BigDecimal.valueOf(val.getTime().getTime());
+
+            case Value.TIMESTAMP:
+                return BigDecimal.valueOf(val.getTimestamp().getTime());
+
+            case Value.BYTES:
+                BigInteger bigInteger = new BigInteger(1, val.getBytes());
+                return new BigDecimal(bigInteger);
+
+            case Value.STRING:
+            case Value.STRING_FIXED:
+            case Value.STRING_IGNORECASE:
+            case Value.ARRAY:
+            case Value.JAVA_OBJECT:
+            case Value.GEOMETRY:
+                return null;
+
+            case Value.UUID:
+                BigInteger bigInt = new BigInteger(1, val.getBytes());
+                return new BigDecimal(bigInt);
+
+            default:
+                throw new IllegalStateException("Unsupported H2 type: " + 
val.getType());
+        }
+    }
+
+    /**
+     * Predicate based selectivity for table. Estimate condition on each 
column taking in comparison it's statistics.
+     *
+     * @param rel Original rel node to fallback calculation by.
+     * @param tbl Underlying IgniteTable.
+     * @param mq RelMetadataQuery.
+     * @param predicate Predicate to estimate selectivity by.
+     * @return Selectivity.
+     */
+    private double getTablePredicateBasedSelectivity(
+        RelNode rel,
+        IgniteTable tbl,
+        RelMetadataQuery mq,
+        RexNode predicate
+    ) {
+        if (tbl == null)
+            return RelMdUtil.guessSelectivity(predicate);
+
+        double sel = 1.0;
+
+        Map<RexSlot, Boolean> addNotNull = new HashMap<>();
+
+        for (RexNode pred : RelOptUtil.conjunctions(predicate)) {
+            SqlKind predKind = pred.getKind();
+            RexLocalRef op = getOperand(pred, RexLocalRef.class);
+
+            if (predKind == SqlKind.OR) {
+                double orSelTotal = 1;
+
+                for (RexNode orPred : RelOptUtil.disjunctions(pred))
+                    orSelTotal *= 1 - getTablePredicateBasedSelectivity(rel, 
tbl, mq, orPred);
+

Review comment:
       empty line




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


Reply via email to