Exemplo n.º 1
0
 public TDropFunctionParams toThrift() {
   TDropFunctionParams params = new TDropFunctionParams();
   params.setFn_name(desc_.getFunctionName().toThrift());
   params.setArg_types(PrimitiveType.toThrift(desc_.getArgs()));
   params.setIf_exists(getIfExists());
   return params;
 }
 protected CreateFunctionStmtBase(
     Function fn, HdfsURI location, boolean ifNotExists, HashMap<OptArg, String> optArgs) {
   fn_ = fn;
   fn_.setLocation(location);
   ifNotExists_ = ifNotExists;
   optArgs_ = optArgs;
 }
Exemplo n.º 3
0
 @Override
 public String toSql() {
   StringBuilder sb = new StringBuilder("DROP FUNCTION");
   if (ifExists_) sb.append(" IF EXISTS ");
   sb.append(desc_.signatureString());
   sb.append(")");
   return sb.toString();
 }
  @Override
  public void analyze(Analyzer analyzer) throws AnalysisException, AuthorizationException {
    // For now, if authorization is enabled, the user needs ALL on the server
    // to create functions.
    // TODO: this is not the right granularity but acceptable for now.
    analyzer.getCatalog().checkCreateDropFunctionAccess(analyzer.getUser());

    // Validate function name is legal
    fn_.getFunctionName().analyze(analyzer);

    // Validate DB is legal
    String dbName = analyzer.getTargetDbName(fn_.getFunctionName());
    fn_.getFunctionName().setDb(dbName);
    if (analyzer.getCatalog().getDb(dbName, analyzer.getUser(), Privilege.CREATE) == null) {
      throw new AnalysisException(Analyzer.DB_DOES_NOT_EXIST_ERROR_MSG + dbName);
    }
    Function existingFn =
        analyzer.getCatalog().getFunction(fn_, Function.CompareMode.IS_INDISTINGUISHABLE);
    if (existingFn != null && !ifNotExists_) {
      throw new AnalysisException(
          Analyzer.FN_ALREADY_EXISTS_ERROR_MSG + existingFn.signatureString());
    }

    fn_.getLocation().analyze(analyzer, Privilege.CREATE);

    // Check the file type from the binary type to infer the type of the UDA
    fn_.setBinaryType(getBinaryType());
  }
Exemplo n.º 5
0
  @Override
  public void analyze(Analyzer analyzer) throws AnalysisException, AuthorizationException {
    // For now, if authorization is enabled, the user needs ALL on the server
    // to drop functions.
    // TODO: this is not the right granularity but acceptable for now.
    analyzer.getCatalog().checkCreateDropFunctionAccess(analyzer.getUser());

    desc_.getFunctionName().analyze(analyzer);
    String dbName = analyzer.getTargetDbName(desc_.getFunctionName());
    desc_.getFunctionName().setDb(dbName);
    if (analyzer.getCatalog().getDb(dbName, analyzer.getUser(), Privilege.DROP) == null
        && !ifExists_) {
      throw new AnalysisException(Analyzer.DB_DOES_NOT_EXIST_ERROR_MSG + dbName);
    }

    if (analyzer.getCatalog().getFunction(desc_, Function.CompareMode.IS_IDENTICAL) == null
        && !ifExists_) {
      throw new AnalysisException(Analyzer.FN_DOES_NOT_EXIST_ERROR_MSG + desc_.signatureString());
    }
  }
  // Returns the resolved symbol in the binary. The BE will do a lookup of 'symbol'
  // in the binary and try to resolve unmangled names.
  // If this function is expecting a return argument, retArgType is that type. It should
  // be null if this function isn't expecting a return argument.
  protected String lookupSymbol(
      String symbol, ColumnType retArgType, boolean hasVarArgs, ColumnType... argTypes)
      throws AnalysisException {
    if (symbol.length() == 0) {
      throw new AnalysisException(
          "Could not find symbol '' in: " + fn_.getLocation().getLocation());
    }
    if (fn_.getBinaryType() == TFunctionBinaryType.HIVE) {
      // TODO: add this when hive udfs go in.
      return symbol;
    }
    Preconditions.checkState(
        fn_.getBinaryType() == TFunctionBinaryType.NATIVE
            || fn_.getBinaryType() == TFunctionBinaryType.IR);

    TSymbolLookupParams lookup = new TSymbolLookupParams();
    lookup.location = fn_.getLocation().toString();
    lookup.symbol = symbol;
    lookup.fn_binary_type = fn_.getBinaryType();
    lookup.arg_types = ColumnType.toThrift(argTypes);
    lookup.has_var_args = hasVarArgs;
    if (retArgType != null) lookup.setRet_arg_type(retArgType.toThrift());

    try {
      TSymbolLookupResult result = FeSupport.LookupSymbol(lookup);
      switch (result.result_code) {
        case SYMBOL_FOUND:
          return result.symbol;
        case BINARY_NOT_FOUND:
          throw new AnalysisException(
              "Could not load binary: "
                  + fn_.getLocation().getLocation()
                  + "\n"
                  + result.error_msg);
        case SYMBOL_NOT_FOUND:
          throw new AnalysisException(result.error_msg);
        default:
          // Should never get here.
          throw new AnalysisException("Internal Error");
      }
    } catch (InternalException e) {
      throw new AnalysisException("Could not find symbol.", e);
    }
  }
 // Returns the function's binary type based on the path extension.
 private TFunctionBinaryType getBinaryType() throws AnalysisException {
   TFunctionBinaryType binaryType = null;
   String binaryPath = fn_.getLocation().getLocation();
   int suffixIndex = binaryPath.lastIndexOf(".");
   if (suffixIndex != -1) {
     String suffix = binaryPath.substring(suffixIndex + 1);
     if (suffix.equalsIgnoreCase("jar")) {
       binaryType = TFunctionBinaryType.HIVE;
     } else if (suffix.equalsIgnoreCase("so")) {
       binaryType = TFunctionBinaryType.NATIVE;
     } else if (suffix.equalsIgnoreCase("ll")) {
       binaryType = TFunctionBinaryType.IR;
     }
   }
   if (binaryType == null) {
     throw new AnalysisException(
         "Unknown binary type: '" + binaryPath + "'. Binary must end in .jar, .so or .ll");
   }
   return binaryType;
 }
 protected TCreateFunctionParams toThrift() {
   TCreateFunctionParams params = new TCreateFunctionParams(fn_.toThrift());
   params.setIf_not_exists(getIfNotExists());
   return params;
 }
Exemplo n.º 9
0
 public FunctionName getFunction() {
   return desc_.getFunctionName();
 }
Exemplo n.º 10
0
 public static void initBuiltins(Db db) {
   for (Type fromType : Type.getSupportedTypes()) {
     if (fromType.isNull()) continue;
     for (Type toType : Type.getSupportedTypes()) {
       if (toType.isNull()) continue;
       // Disable casting from string to boolean
       if (fromType.isStringType() && toType.isBoolean()) continue;
       // Disable casting from boolean/timestamp to decimal
       if ((fromType.isBoolean() || fromType.isDateType()) && toType.isDecimal()) {
         continue;
       }
       if (fromType.getPrimitiveType() == PrimitiveType.STRING
           && toType.getPrimitiveType() == PrimitiveType.CHAR) {
         // Allow casting from String to Char(N)
         String beSymbol = "impala::CastFunctions::CastToChar";
         db.addBuiltin(
             ScalarFunction.createBuiltin(
                 getFnName(ScalarType.CHAR),
                 Lists.newArrayList((Type) ScalarType.STRING),
                 false,
                 ScalarType.CHAR,
                 beSymbol,
                 null,
                 null,
                 true));
         continue;
       }
       if (fromType.getPrimitiveType() == PrimitiveType.CHAR
           && toType.getPrimitiveType() == PrimitiveType.CHAR) {
         // Allow casting from CHAR(N) to Char(N)
         String beSymbol = "impala::CastFunctions::CastToChar";
         db.addBuiltin(
             ScalarFunction.createBuiltin(
                 getFnName(ScalarType.CHAR),
                 Lists.newArrayList((Type) ScalarType.createCharType(-1)),
                 false,
                 ScalarType.CHAR,
                 beSymbol,
                 null,
                 null,
                 true));
         continue;
       }
       if (fromType.getPrimitiveType() == PrimitiveType.VARCHAR
           && toType.getPrimitiveType() == PrimitiveType.VARCHAR) {
         // Allow casting from VARCHAR(N) to VARCHAR(M)
         String beSymbol = "impala::CastFunctions::CastToStringVal";
         db.addBuiltin(
             ScalarFunction.createBuiltin(
                 getFnName(ScalarType.VARCHAR),
                 Lists.newArrayList((Type) ScalarType.VARCHAR),
                 false,
                 ScalarType.VARCHAR,
                 beSymbol,
                 null,
                 null,
                 true));
         continue;
       }
       if (fromType.getPrimitiveType() == PrimitiveType.VARCHAR
           && toType.getPrimitiveType() == PrimitiveType.CHAR) {
         // Allow casting from VARCHAR(N) to CHAR(M)
         String beSymbol = "impala::CastFunctions::CastToChar";
         db.addBuiltin(
             ScalarFunction.createBuiltin(
                 getFnName(ScalarType.CHAR),
                 Lists.newArrayList((Type) ScalarType.VARCHAR),
                 false,
                 ScalarType.CHAR,
                 beSymbol,
                 null,
                 null,
                 true));
         continue;
       }
       if (fromType.getPrimitiveType() == PrimitiveType.CHAR
           && toType.getPrimitiveType() == PrimitiveType.VARCHAR) {
         // Allow casting from CHAR(N) to VARCHAR(M)
         String beSymbol = "impala::CastFunctions::CastToStringVal";
         db.addBuiltin(
             ScalarFunction.createBuiltin(
                 getFnName(ScalarType.VARCHAR),
                 Lists.newArrayList((Type) ScalarType.CHAR),
                 false,
                 ScalarType.VARCHAR,
                 beSymbol,
                 null,
                 null,
                 true));
         continue;
       }
       // Disable no-op casts
       if (fromType.equals(toType) && !fromType.isDecimal()) continue;
       String beClass =
           toType.isDecimal() || fromType.isDecimal() ? "DecimalOperators" : "CastFunctions";
       String beSymbol = "impala::" + beClass + "::CastTo" + Function.getUdfType(toType);
       db.addBuiltin(
           ScalarFunction.createBuiltin(
               getFnName(toType),
               Lists.newArrayList(fromType),
               false,
               toType,
               beSymbol,
               null,
               null,
               true));
     }
   }
 }
Exemplo n.º 11
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_;
  }