diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/stats/FilterSelectivityEstimator.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/stats/FilterSelectivityEstimator.java index ba07363..1e3a586 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/stats/FilterSelectivityEstimator.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/stats/FilterSelectivityEstimator.java @@ -18,6 +18,7 @@ package org.apache.hadoop.hive.ql.optimizer.optiq.stats; import java.util.BitSet; +import java.util.List; import org.apache.hadoop.hive.ql.optimizer.optiq.RelOptHiveTable; import org.apache.hadoop.hive.ql.optimizer.optiq.reloperators.HiveTableScanRel; @@ -32,6 +33,8 @@ import org.eigenbase.rex.RexNode; import org.eigenbase.rex.RexVisitorImpl; import org.eigenbase.sql.SqlKind; +import org.eigenbase.sql.SqlOperator; +import org.eigenbase.sql.type.SqlTypeUtil; public class FilterSelectivityEstimator extends RexVisitorImpl { private final RelNode childRel; @@ -61,7 +64,7 @@ public Double visitCall(RexCall call) { } Double selectivity = null; - SqlKind op = call.getKind(); + SqlKind op = getOp(call); switch (op) { case AND: { @@ -74,6 +77,7 @@ public Double visitCall(RexCall call) { break; } + case NOT: case NOT_EQUALS: { selectivity = computeNotEqualitySelectivity(call); break; @@ -88,7 +92,10 @@ public Double visitCall(RexCall call) { } case IN: { - selectivity = ((double) 1 / ((double) call.operands.size())); + double nDVInClause = call.operands.size() - 1; + if (nDVInClause <= 0) + nDVInClause = 1; + selectivity = ((double) 1 / nDVInClause); break; } @@ -225,4 +232,19 @@ private boolean isPartitionPredicate(RexNode expr, RelNode r) { } return false; } + + private SqlKind getOp(RexCall call) { + SqlKind op = call.getKind(); + + if (call.getKind().equals(SqlKind.OTHER_FUNCTION) + && SqlTypeUtil.inBooleanFamily(call.getType())) { + SqlOperator sqlOp = call.getOperator(); + String opName = (sqlOp != null) ? sqlOp.getName() : ""; + if (opName.equalsIgnoreCase("in")) { + op = SqlKind.IN; + } + } + + return op; + } } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/SqlFunctionConverter.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/SqlFunctionConverter.java index c6efff6..7f52c29 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/SqlFunctionConverter.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/optiq/translator/SqlFunctionConverter.java @@ -278,6 +278,7 @@ private static String getName(GenericUDF hiveUDF) { registerFunction(">=", SqlStdOperatorTable.GREATER_THAN_OR_EQUAL, hToken(HiveParser.GREATERTHANOREQUALTO, ">=")); registerFunction("!", SqlStdOperatorTable.NOT, hToken(HiveParser.KW_NOT, "not")); + registerFunction("<>", SqlStdOperatorTable.NOT_EQUALS, hToken(HiveParser.NOTEQUAL, "<>")); } private void registerFunction(String name, SqlOperator optiqFn, HiveToken hiveToken) {