예제 #1
0
 /** 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;
   }
 }
예제 #2
0
    /**
     * 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;
      }
    }
예제 #3
0
 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);
   }
 }
예제 #4
0
 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());
   }
 }
예제 #5
0
    // 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;
    }