/** Translates a call to a binary operator. Returns whether successful. */ private boolean translateBinary2(String op, RexNode left, RexNode right) { switch (right.getKind()) { case LITERAL: break; default: return false; } final RexLiteral rightLiteral = (RexLiteral) right; switch (left.getKind()) { case INPUT_REF: final RexInputRef left1 = (RexInputRef) left; String name = fieldNames.get(left1.getIndex()); translateOp2(op, name, rightLiteral); return true; case CAST: return translateBinary2(op, ((RexCall) left).operands.get(0), right); case OTHER_FUNCTION: String itemName = MongoRules.isItem((RexCall) left); if (itemName != null) { translateOp2(op, itemName, rightLiteral); return true; } // fall through default: return false; } }
/** * Returns whether a condition is supported by {@link JdbcJoin}. * * <p>Corresponds to the capabilities of {@link SqlImplementor#convertConditionToSqlNode}. * * @param node Condition * @return Whether condition is supported */ private boolean canJoinOnCondition(RexNode node) { final List<RexNode> operands; switch (node.getKind()) { case AND: case OR: operands = ((RexCall) node).getOperands(); for (RexNode operand : operands) { if (!canJoinOnCondition(operand)) { return false; } } return true; case EQUALS: case IS_NOT_DISTINCT_FROM: case NOT_EQUALS: case GREATER_THAN: case GREATER_THAN_OR_EQUAL: case LESS_THAN: case LESS_THAN_OR_EQUAL: operands = ((RexCall) node).getOperands(); if ((operands.get(0) instanceof RexInputRef) && (operands.get(1) instanceof RexInputRef)) { return true; } // fall through default: return false; } }
private Void translateMatch2(RexNode node) { switch (node.getKind()) { case EQUALS: return translateBinary(null, null, (RexCall) node); case LESS_THAN: return translateBinary("$lt", "$gt", (RexCall) node); case LESS_THAN_OR_EQUAL: return translateBinary("$lte", "$gte", (RexCall) node); case NOT_EQUALS: return translateBinary("$ne", "$ne", (RexCall) node); case GREATER_THAN: return translateBinary("$gt", "$lt", (RexCall) node); case GREATER_THAN_OR_EQUAL: return translateBinary("$gte", "$lte", (RexCall) node); default: throw new AssertionError("cannot translate " + node); } }
public Double averageRexSize(RexNode node, List<Double> inputColumnSizes) { switch (node.getKind()) { case INPUT_REF: return inputColumnSizes.get(((RexInputRef) node).getIndex()); case LITERAL: return typeValueSize(node.getType(), ((RexLiteral) node).getValue()); default: if (node instanceof RexCall) { RexCall call = (RexCall) node; for (RexNode operand : call.getOperands()) { // It's a reasonable assumption that a function's result will have // similar size to its argument of a similar type. For example, // UPPER(c) has the same average size as c. if (operand.getType().getSqlTypeName() == node.getType().getSqlTypeName()) { return averageRexSize(operand, inputColumnSizes); } } } return averageTypeValueSize(node.getType()); } }
// We create the join predicate info object. The object contains the join condition, // split accordingly. If the join condition is not part of the equi-join predicate, // the returned object will be typed as SQLKind.OTHER. private static JoinLeafPredicateInfo constructJoinLeafPredicateInfo( List<RelNode> inputs, List<RelDataTypeField> systemFieldList, RexNode pe) throws CalciteSemanticException { JoinLeafPredicateInfo jlpi = null; List<Integer> filterNulls = new ArrayList<Integer>(); List<List<RexNode>> joinExprs = new ArrayList<List<RexNode>>(); for (int i = 0; i < inputs.size(); i++) { joinExprs.add(new ArrayList<RexNode>()); } // 1. Split leaf join predicate to expressions from left, right RexNode otherConditions = HiveRelOptUtil.splitHiveJoinCondition( systemFieldList, inputs, pe, joinExprs, filterNulls, null); if (otherConditions.isAlwaysTrue()) { // 2. Collect child projection indexes used List<Set<Integer>> projsJoinKeysInChildSchema = new ArrayList<Set<Integer>>(); for (int i = 0; i < inputs.size(); i++) { ImmutableSet.Builder<Integer> projsFromInputJoinKeysInChildSchema = ImmutableSet.builder(); InputReferencedVisitor irvLeft = new InputReferencedVisitor(); irvLeft.apply(joinExprs.get(i)); projsFromInputJoinKeysInChildSchema.addAll(irvLeft.inputPosReferenced); projsJoinKeysInChildSchema.add(projsFromInputJoinKeysInChildSchema.build()); } // 3. Translate projection indexes to join schema, by adding offset. List<Set<Integer>> projsJoinKeysInJoinSchema = new ArrayList<Set<Integer>>(); // The offset of the first input does not need to change. projsJoinKeysInJoinSchema.add(projsJoinKeysInChildSchema.get(0)); for (int i = 1; i < inputs.size(); i++) { int offSet = inputs.get(i - 1).getRowType().getFieldCount(); ImmutableSet.Builder<Integer> projsFromInputJoinKeysInJoinSchema = ImmutableSet.builder(); for (Integer indx : projsJoinKeysInChildSchema.get(i)) { projsFromInputJoinKeysInJoinSchema.add(indx + offSet); } projsJoinKeysInJoinSchema.add(projsFromInputJoinKeysInJoinSchema.build()); } // 4. Construct JoinLeafPredicateInfo jlpi = new JoinLeafPredicateInfo( pe.getKind(), joinExprs, projsJoinKeysInChildSchema, projsJoinKeysInJoinSchema); } else { // 2. Construct JoinLeafPredicateInfo ImmutableBitSet refCols = InputFinder.bits(pe); int count = 0; for (int i = 0; i < inputs.size(); i++) { final int length = inputs.get(i).getRowType().getFieldCount(); ImmutableBitSet inputRange = ImmutableBitSet.range(count, count + length); if (inputRange.contains(refCols)) { joinExprs.get(i).add(pe); } count += length; } jlpi = new JoinLeafPredicateInfo( SqlKind.OTHER, joinExprs, new ArrayList<Set<Integer>>(), new ArrayList<Set<Integer>>()); } return jlpi; }