use of org.apache.calcite.rex.RexCall in project drill by apache.
the class DrillRelOptUtil method isProjectFlatten.
@SuppressWarnings("deprecation")
public static boolean isProjectFlatten(RelNode project) {
assert project instanceof Project : "Rel is NOT an instance of project!";
for (RexNode rex : project.getChildExps()) {
if (rex instanceof RexCall) {
RexCall function = (RexCall) rex;
String functionName = function.getOperator().getName();
if (functionName.equalsIgnoreCase("flatten")) {
return true;
}
}
}
return false;
}
use of org.apache.calcite.rex.RexCall in project drill by apache.
the class DrillRelMdSelectivity method getScanSelectivityInternal.
private double getScanSelectivityInternal(TableMetadata tableMetadata, RexNode predicate, List<SchemaPath> fieldNames, RexBuilder rexBuilder) {
double sel = 1.0;
if ((predicate == null) || predicate.isAlwaysTrue()) {
return sel;
}
List<RexNode> conjuncts1 = RelOptUtil.conjunctions(predicate);
// a Set that holds range predicates that are combined based on whether they are defined on the same column
Set<RexNode> combinedRangePredicates = new HashSet<>();
// pre-process the conjuncts such that predicates on the same column are grouped together
List<RexNode> conjuncts2 = preprocessRangePredicates(conjuncts1, fieldNames, rexBuilder, combinedRangePredicates);
for (RexNode pred : conjuncts2) {
double orSel = 0;
for (RexNode orPred : RelOptUtil.disjunctions(pred)) {
if (isMultiColumnPredicate(orPred) && !combinedRangePredicates.contains(orPred)) {
Set uniqueRefs = new HashSet<>();
uniqueRefs.add(DrillRelOptUtil.findAllRexInputRefs(orPred));
// If equality predicate involving single column - selectivity is 1.0
if (uniqueRefs.size() == 1) {
try {
RexVisitor<Void> visitor = new RexVisitorImpl<Void>(true) {
@Override
public Void visitCall(RexCall call) {
if (call.getKind() != SqlKind.EQUALS) {
throw new Util.FoundOne(call);
}
return super.visitCall(call);
}
};
pred.accept(visitor);
orSel += 1.0;
} catch (Util.FoundOne e) {
// CALCITE guess
orSel += RelMdUtil.guessSelectivity(orPred);
}
}
} else if (orPred.isA(SqlKind.EQUALS)) {
orSel += computeEqualsSelectivity(tableMetadata, orPred, fieldNames);
} else if (orPred.isA(RANGE_PREDICATE) || combinedRangePredicates.contains(orPred)) {
orSel += computeRangeSelectivity(tableMetadata, orPred, fieldNames);
} else if (orPred.isA(SqlKind.NOT_EQUALS)) {
orSel += 1.0 - computeEqualsSelectivity(tableMetadata, orPred, fieldNames);
} else if (orPred.isA(SqlKind.LIKE)) {
// LIKE selectivity is 5% more than a similar equality predicate, capped at CALCITE guess
orSel += Math.min(computeEqualsSelectivity(tableMetadata, orPred, fieldNames) + LIKE_PREDICATE_SELECTIVITY, guessSelectivity(orPred));
} else if (orPred.isA(SqlKind.NOT)) {
if (orPred instanceof RexCall) {
// LIKE selectivity is 5% more than a similar equality predicate, capped at CALCITE guess
RexNode childOp = ((RexCall) orPred).getOperands().get(0);
if (childOp.isA(SqlKind.LIKE)) {
orSel += 1.0 - Math.min(computeEqualsSelectivity(tableMetadata, childOp, fieldNames) + LIKE_PREDICATE_SELECTIVITY, guessSelectivity(childOp));
} else {
orSel += 1.0 - guessSelectivity(orPred);
}
}
} else if (orPred.isA(SqlKind.IS_NULL)) {
orSel += 1.0 - computeIsNotNullSelectivity(tableMetadata, orPred, fieldNames);
} else if (orPred.isA(SqlKind.IS_NOT_NULL)) {
orSel += computeIsNotNullSelectivity(tableMetadata, orPred, fieldNames);
} else {
// Use the CALCITE guess.
orSel += guessSelectivity(orPred);
}
}
sel *= orSel;
}
// Cap selectivity if it exceeds 1.0
return (sel > 1.0) ? 1.0 : sel;
}
use of org.apache.calcite.rex.RexCall in project drill by apache.
the class DrillRelMdSelectivity method findRexInputRef.
private static RexInputRef findRexInputRef(final RexNode node) {
try {
RexVisitor<Void> visitor = new RexVisitorImpl<Void>(true) {
@Override
public Void visitCall(RexCall call) {
for (RexNode child : call.getOperands()) {
child.accept(this);
}
return super.visitCall(call);
}
@Override
public Void visitInputRef(RexInputRef inputRef) {
throw new Util.FoundOne(inputRef);
}
};
node.accept(visitor);
return null;
} catch (Util.FoundOne e) {
Util.swallow(e, null);
return (RexInputRef) e.getNode();
}
}
use of org.apache.calcite.rex.RexCall in project drill by apache.
the class RexToMongoTranslator method visitCall.
@Override
public BsonValue visitCall(RexCall call) {
String name = isItem(call);
if (name != null) {
return new BsonString("'$" + name + "'");
}
List<BsonValue> strings = call.operands.stream().map(operand -> operand.accept(this)).collect(Collectors.toList());
if (call.getKind() == SqlKind.CAST) {
return strings.get(0);
}
String stdOperator = MONGO_OPERATORS.get(call.getOperator());
if (stdOperator != null) {
return new BsonDocument(stdOperator, new BsonArray(strings));
}
if (call.getOperator() == SqlStdOperatorTable.ITEM) {
RexNode op1 = call.operands.get(1);
if (op1 instanceof RexLiteral) {
if (op1.getType().getSqlTypeName() == SqlTypeName.INTEGER) {
return new BsonDocument("$arrayElemAt", new BsonArray(Arrays.asList(strings.get(0), new BsonInt32(((RexLiteral) op1).getValueAs(Integer.class)))));
} else if (op1.getType().getSqlTypeName() == SqlTypeName.CHAR) {
return new BsonString(strings.get(0).asString().getValue() + "." + ((RexLiteral) op1).getValueAs(String.class));
}
}
}
if (call.getOperator() == SqlStdOperatorTable.CASE) {
// case(a, b, c) -> $cond:[a, b, c]
// case(a, b, c, d) -> $cond:[a, b, $cond:[c, d, null]]
// case(a, b, c, d, e) -> $cond:[a, b, $cond:[c, d, e]]
BsonDocument result = new BsonDocument();
BsonArray args = new BsonArray();
result.put("$cond", args);
for (int i = 0; i < strings.size(); i += 2) {
args.add(strings.get(i));
args.add(strings.get(i + 1));
if (i == strings.size() - 3) {
args.add(strings.get(i + 2));
break;
}
if (i == strings.size() - 2) {
args.add(BsonNull.VALUE);
break;
}
BsonArray innerArgs = new BsonArray();
BsonDocument innerDocument = new BsonDocument();
innerDocument.put("$cond", innerArgs);
args.add(innerDocument);
args = innerArgs;
}
return result;
}
throw new IllegalArgumentException("Translation of " + call + " is not supported by MongoProject");
}
use of org.apache.calcite.rex.RexCall in project drill by apache.
the class DrillMergeProjectRule method simplifyCast.
public static List<RexNode> simplifyCast(List<RexNode> projectExprs) {
final List<RexNode> list = new ArrayList<>();
for (RexNode rex : projectExprs) {
if (rex.getKind() == SqlKind.CAST) {
RexNode operand = ((RexCall) rex).getOperands().get(0);
while (operand.getKind() == SqlKind.CAST && operand.getType().equals(rex.getType())) {
rex = operand;
operand = ((RexCall) rex).getOperands().get(0);
}
}
list.add(rex);
}
return list;
}
Aggregations