Beispiel #1
0
  private void analyze() throws AnalysisException {
    targetType_.analyze();
    if (targetType_.isComplexType()) {
      throw new AnalysisException("Unsupported cast to complex type: " + targetType_.toSql());
    }

    boolean readyForCharCast =
        children_.get(0).getType().getPrimitiveType() == PrimitiveType.STRING
            || children_.get(0).getType().getPrimitiveType() == PrimitiveType.CHAR;
    if (targetType_.getPrimitiveType() == PrimitiveType.CHAR && !readyForCharCast) {
      // Back end functions only exist to cast string types to CHAR, there is not a cast
      // for every type since it is redundant with STRING. Casts to go through 2 casts:
      // (1) cast to string, to stringify the value
      // (2) cast to CHAR, to truncate or pad with spaces
      CastExpr tostring = new CastExpr(ScalarType.STRING, children_.get(0), true);
      tostring.analyze();
      children_.set(0, tostring);
    }

    if (children_.get(0) instanceof NumericLiteral && targetType_.isFloatingPointType()) {
      // Special case casting a decimal literal to a floating point number. The
      // decimal literal can be interpreted as either and we want to avoid casts
      // since that can result in loss of accuracy.
      ((NumericLiteral) children_.get(0)).explicitlyCastToFloat(targetType_);
    }

    if (children_.get(0).getType().isNull()) {
      // Make sure BE never sees TYPE_NULL
      uncheckedCastChild(targetType_, 0);
    }

    // Ensure child has non-null type (even if it's a null literal). This is required
    // for the UDF interface.
    if (children_.get(0) instanceof NullLiteral) {
      NullLiteral nullChild = (NullLiteral) (children_.get(0));
      nullChild.uncheckedCastTo(targetType_);
    }

    Type childType = children_.get(0).type_;
    Preconditions.checkState(!childType.isNull());
    if (childType.equals(targetType_)) {
      noOp_ = true;
      type_ = targetType_;
      return;
    }

    FunctionName fnName = new FunctionName(Catalog.BUILTINS_DB, getFnName(targetType_));
    Type[] args = {childType};
    Function searchDesc = new Function(fnName, args, Type.INVALID, false);
    if (isImplicit_) {
      fn_ = Catalog.getBuiltin(searchDesc, CompareMode.IS_SUPERTYPE_OF);
      Preconditions.checkState(fn_ != null);
    } else {
      fn_ = Catalog.getBuiltin(searchDesc, CompareMode.IS_IDENTICAL);
      if (fn_ == null) {
        // allow for promotion from CHAR to STRING; only if no exact match is found
        fn_ = Catalog.getBuiltin(searchDesc.promoteCharsToStrings(), CompareMode.IS_IDENTICAL);
      }
    }
    if (fn_ == null) {
      throw new AnalysisException(
          "Invalid type cast of "
              + getChild(0).toSql()
              + " from "
              + childType
              + " to "
              + targetType_);
    }

    Preconditions.checkState(
        targetType_.matchesType(fn_.getReturnType()), targetType_ + " != " + fn_.getReturnType());
    type_ = targetType_;
  }