Beispiel #1
0
 /**
  * Replaces the operands of a call. The new operands' types must match the old operands' types.
  */
 public static RexCall replaceOperands(RexCall call, RexNode[] operands) {
   if (call.operands == operands) {
     return call;
   }
   for (int i = 0; i < operands.length; i++) {
     RelDataType oldType = call.operands[i].getType();
     RelDataType newType = operands[i].getType();
     if (!oldType.isNullable() && newType.isNullable()) {
       throw Util.newInternal("invalid nullability");
     }
     assert (oldType.toString().equals(newType.toString()));
   }
   return new RexCall(call.getType(), call.getOperator(), operands);
 }
Beispiel #2
0
 /**
  * Returns whether a list of expressions contains complex expressions, that is, a call whose
  * arguments are not {@link RexVariable} (or a subtype such as {@link RexInputRef}) or {@link
  * RexLiteral}.
  */
 public static boolean containComplexExprs(List<RexNode> exprs) {
   for (RexNode expr : exprs) {
     if (expr instanceof RexCall) {
       RexCall rexCall = (RexCall) expr;
       final RexNode[] operands = rexCall.getOperands();
       for (int j = 0; j < operands.length; j++) {
         RexNode operand = operands[j];
         if (!isAtomic(operand)) {
           return true;
         }
       }
     }
   }
   return false;
 }
Beispiel #3
0
 public RexNode visitCall(RexCall call) {
   List<RexNode> normalizedOperands = new ArrayList<RexNode>();
   int diffCount = 0;
   for (RexNode operand : call.getOperands()) {
     operand.accept(this);
     final RexNode normalizedOperand = lookup(operand);
     normalizedOperands.add(normalizedOperand);
     if (normalizedOperand != operand) {
       ++diffCount;
     }
   }
   if (diffCount > 0) {
     call = call.clone(call.getType(), normalizedOperands);
   }
   return register(call);
 }
Beispiel #4
0
 public Void visitCall(RexCall call) {
   final RexNode[] operands = call.getOperands();
   for (int i = 0; i < operands.length; i++) {
     RexNode operand = operands[i];
     operand.accept(this);
   }
   return null;
 }
Beispiel #5
0
 /**
  * Returns whether an array of exp contains aggregate function calls whose arguments are not
  * {@link RexInputRef}.s
  *
  * @param exprs Expressions
  * @param fail Whether to assert if there is such a function call
  */
 static boolean containNonTrivialAggs(RexNode[] exprs, boolean fail) {
   for (int i = 0; i < exprs.length; i++) {
     RexNode expr = exprs[i];
     if (expr instanceof RexCall) {
       RexCall rexCall = (RexCall) expr;
       if (rexCall.getOperator() instanceof SqlAggFunction) {
         final RexNode[] operands = rexCall.getOperands();
         for (int j = 0; j < operands.length; j++) {
           RexNode operand = operands[j];
           if (!(operand instanceof RexLocalRef)) {
             assert !fail : "contains non trivial agg";
             return true;
           }
         }
       }
     }
   }
   return false;
 }
Beispiel #6
0
  /**
   * Determines whether a {@link RexCall} requires decimal expansion. It usually requires expansion
   * if it has decimal operands.
   *
   * <p>Exceptions to this rule are:
   *
   * <ul>
   *   <li>isNull doesn't require expansion
   *   <li>It's okay to cast decimals to and from char types
   *   <li>It's okay to cast nulls as decimals
   *   <li>Casts require expansion if their return type is decimal
   *   <li>Reinterpret casts can handle a decimal operand
   * </ul>
   *
   * @param expr expression possibly in need of expansion
   * @param recurse whether to check nested calls
   * @return whether the expression requires expansion
   */
  public static boolean requiresDecimalExpansion(RexNode expr, boolean recurse) {
    if (!(expr instanceof RexCall)) {
      return false;
    }
    RexCall call = (RexCall) expr;

    boolean localCheck = true;
    switch (call.getKind()) {
      case Reinterpret:
      case IsNull:
        localCheck = false;
        break;
      case Cast:
        RelDataType lhsType = call.getType();
        RelDataType rhsType = call.operands[0].getType();
        if (rhsType.getSqlTypeName() == SqlTypeName.NULL) {
          return false;
        }
        if (SqlTypeUtil.inCharFamily(lhsType) || SqlTypeUtil.inCharFamily(rhsType)) {
          localCheck = false;
        } else if (SqlTypeUtil.isDecimal(lhsType) && (lhsType != rhsType)) {
          return true;
        }
        break;
      default:
        localCheck = call.getOperator().requiresDecimalExpansion();
    }

    if (localCheck) {
      if (SqlTypeUtil.isDecimal(call.getType())) {
        // NOTE jvs 27-Mar-2007: Depending on the type factory, the
        // result of a division may be decimal, even though both inputs
        // are integer.
        return true;
      }
      for (int i = 0; i < call.operands.length; i++) {
        if (SqlTypeUtil.isDecimal(call.operands[i].getType())) {
          return true;
        }
      }
    }
    return (recurse && requiresDecimalExpansion(call.operands, recurse));
  }
Beispiel #7
0
 public static boolean canReinterpretOverflow(RexCall call) {
   assert (call.isA(RexKind.Reinterpret)) : "call is not a reinterpret";
   return call.operands.length > 1;
 }