org.apache.hadoop.hive.ql.exec.FunctionInfo Maven / Gradle / Ivy
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hive.ql.exec;
import org.apache.hadoop.hive.ql.session.SessionState;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFBridge;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFResolver;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDFBridge;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;
import org.apache.hadoop.hive.ql.udf.ptf.TableFunctionResolver;
import org.apache.hadoop.hive.ql.udf.ptf.WindowingTableFunction;
import org.apache.hive.common.util.AnnotationUtils;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* FunctionInfo.
*
*/
public class FunctionInfo {
public static enum FunctionType {
BUILTIN, PERSISTENT, TEMPORARY;
}
private final FunctionType functionType;
private final boolean isInternalTableFunction;
private final String displayName;
private final FunctionResource[] resources;
private String className;
private GenericUDF genericUDF;
private GenericUDTF genericUDTF;
private GenericUDAFResolver genericUDAFResolver;
private Class extends TableFunctionResolver> tableFunctionResolver;
private boolean blockedFunction;
// for persistent function
// if the function is dropped, all functions registered to sessions are needed to be reloaded
private AtomicBoolean discarded;
public FunctionInfo(String displayName, String className, FunctionResource... resources) {
this.functionType = FunctionType.PERSISTENT;
this.displayName = displayName;
this.className = className;
this.isInternalTableFunction = false;
this.resources = resources;
this.discarded = new AtomicBoolean(false); // shared to all session functions
}
public FunctionInfo(FunctionType functionType, String displayName,
GenericUDF genericUDF, FunctionResource... resources) {
this.functionType = functionType;
this.displayName = displayName;
this.genericUDF = genericUDF;
this.isInternalTableFunction = false;
this.resources = resources;
}
public FunctionInfo(FunctionType functionType, String displayName,
GenericUDAFResolver genericUDAFResolver, FunctionResource... resources) {
this.functionType = functionType;
this.displayName = displayName;
this.genericUDAFResolver = genericUDAFResolver;
this.isInternalTableFunction = false;
this.resources = resources;
}
public FunctionInfo(FunctionType functionType, String displayName,
GenericUDTF genericUDTF, FunctionResource... resources) {
this.functionType = functionType;
this.displayName = displayName;
this.genericUDTF = genericUDTF;
this.isInternalTableFunction = false;
this.resources = resources;
}
public FunctionInfo(FunctionType functionType, String displayName, Class extends TableFunctionResolver> tFnCls,
FunctionResource... resources) {
this.functionType = functionType;
this.displayName = displayName;
this.tableFunctionResolver = tFnCls;
PartitionTableFunctionDescription def = AnnotationUtils.getAnnotation(
tableFunctionResolver, PartitionTableFunctionDescription.class);
this.isInternalTableFunction = def != null && def.isInternal();
this.resources = resources;
}
/**
* Get a new GenericUDF object for the function.
*/
public GenericUDF getGenericUDF() {
// GenericUDF is stateful - we have to make a copy here
if (genericUDF == null) {
return null;
}
return FunctionRegistry.cloneGenericUDF(genericUDF);
}
/**
* Get a new GenericUDTF object for the function.
*/
public GenericUDTF getGenericUDTF() {
// GenericUDTF is stateful too, copy
if (genericUDTF == null) {
return null;
}
return FunctionRegistry.cloneGenericUDTF(genericUDTF);
}
/**
* Get the GenericUDAFResolver object for the function.
*/
public GenericUDAFResolver getGenericUDAFResolver() {
return genericUDAFResolver;
}
/**
* Get the Class of the UDF.
*/
public Class> getFunctionClass() {
if (isGenericUDF()) {
if (genericUDF instanceof GenericUDFBridge) {
return ((GenericUDFBridge) genericUDF).getUdfClass();
} else {
return genericUDF.getClass();
}
} else if (isGenericUDAF()) {
if (genericUDAFResolver instanceof GenericUDAFBridge) {
return ((GenericUDAFBridge) genericUDAFResolver).getUDAFClass();
} else {
return genericUDAFResolver.getClass();
}
} else if (isGenericUDTF()) {
return genericUDTF.getClass();
}
if(isTableFunction()) {
return this.tableFunctionResolver;
}
return null;
}
/**
* Get the display name for this function. This should be transferred into
* exprNodeGenericUDFDesc, and will be used as the first parameter to
* GenericUDF.getDisplayName() call, instead of hard-coding the function name.
* This will solve the problem of displaying only one name when a udf is
* registered under 2 names.
*/
public String getDisplayName() {
return displayName;
}
/**
* Native functions cannot be unregistered.
*/
public boolean isNative() {
return functionType == FunctionType.BUILTIN || functionType == FunctionType.PERSISTENT;
}
/**
* Internal table functions cannot be used in the language.
* {@link WindowingTableFunction}
*/
public boolean isInternalTableFunction() {
return isInternalTableFunction;
}
/**
* @return TRUE if the function is a GenericUDF
*/
public boolean isGenericUDF() {
return null != genericUDF;
}
/**
* @return TRUE if the function is a GenericUDAF
*/
public boolean isGenericUDAF() {
return null != genericUDAFResolver;
}
/**
* @return TRUE if the function is a GenericUDTF
*/
public boolean isGenericUDTF() {
return null != genericUDTF;
}
/**
* @return TRUE if the function is a Table Function
*/
public boolean isTableFunction() {
return null != tableFunctionResolver;
}
public boolean isBlockedFunction() {
return blockedFunction;
}
public void setBlockedFunction(boolean blockedFunction) {
this.blockedFunction = blockedFunction;
}
public boolean isBuiltIn() {
return functionType == FunctionType.BUILTIN;
}
public boolean isPersistent() {
return functionType == FunctionType.PERSISTENT;
}
public String getClassName() {
return className;
}
public FunctionResource[] getResources() {
return resources;
}
public void discarded() {
if (discarded != null) {
discarded.set(true);
}
}
// for persistent function
public boolean isDiscarded() {
return discarded != null && discarded.get();
}
// for persistent function
public void shareStateWith(FunctionInfo function) {
if (function != null) {
function.discarded = discarded;
}
}
public FunctionType getFunctionType() {
return functionType;
}
public static class FunctionResource {
private final SessionState.ResourceType resourceType;
private final String resourceURI;
public FunctionResource(SessionState.ResourceType resourceType, String resourceURI) {
this.resourceType = resourceType;
this.resourceURI = resourceURI;
}
public SessionState.ResourceType getResourceType() {
return resourceType;
}
public String getResourceURI() {
return resourceURI;
}
@Override
public String toString() {
return resourceType + ":" + resourceURI;
}
}
}