@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()); }
// 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; }