blob: a5263adf69e1af4de659cf4b7039b9d10dce7691 [file] [log] [blame]
/*
* 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.phoenix.parse;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.util.ByteStringer;
import org.apache.phoenix.coprocessor.generated.PFunctionProtos;
import org.apache.phoenix.coprocessor.generated.PFunctionProtos.PFunctionArg;
import org.apache.phoenix.expression.LiteralExpression;
import org.apache.phoenix.schema.PMetaDataEntity;
import org.apache.phoenix.schema.PName;
import org.apache.phoenix.schema.PNameFactory;
import org.apache.phoenix.schema.PTableKey;
import org.apache.phoenix.schema.types.PDataType;
import org.apache.phoenix.util.SchemaUtil;
import org.apache.phoenix.util.SizedUtil;
public class PFunction implements PMetaDataEntity {
private PName tenantId = null;
private final PName functionName;
private List<FunctionArgument> args;
private PName className;
private PName jarPath;
private PName returnType;
private PTableKey functionKey;
private long timeStamp;
private int estimatedSize;
private boolean temporary;
private boolean replace;
public PFunction(long timeStamp) { // For index delete marker
this.timeStamp = timeStamp;
this.args = Collections.emptyList();
this.functionName = null;
}
public PFunction(String functionName, List<FunctionArgument> args, String returnType,
String className, String jarPath) {
this(functionName,args,returnType,className, jarPath, HConstants.LATEST_TIMESTAMP);
}
public PFunction(String functionName, List<FunctionArgument> args, String returnType,
String className, String jarPath, long timeStamp) {
this(null, functionName, args, returnType, className, jarPath, timeStamp);
}
public PFunction(PName tenantId, String functionName, List<FunctionArgument> args, String returnType,
String className, String jarPath, long timeStamp) {
this(tenantId, functionName, args, returnType, className, jarPath, timeStamp, false);
}
public PFunction(PFunction function, boolean temporary) {
this(function.getTenantId(), function.getFunctionName(), function.getFunctionArguments(),
function.getReturnType(), function.getClassName(), function.getJarPath(), function
.getTimeStamp(), temporary, function.isReplace());
}
public PFunction(PFunction function, boolean temporary, boolean isReplace) {
this(function.getTenantId(), function.getFunctionName(), function.getFunctionArguments(),
function.getReturnType(), function.getClassName(), function.getJarPath(), function
.getTimeStamp(), temporary, isReplace);
}
public PFunction(PName tenantId, String functionName, List<FunctionArgument> args,
String returnType, String className, String jarPath, long timeStamp, boolean temporary) {
this(tenantId, functionName, args, returnType, className, jarPath, timeStamp, temporary,
false);
}
public PFunction(PName tenantId, String functionName, List<FunctionArgument> args, String returnType,
String className, String jarPath, long timeStamp, boolean temporary, boolean replace) {
this.tenantId = tenantId;
this.functionName = PNameFactory.newName(functionName);
if (args == null){
this.args = new ArrayList<FunctionArgument>();
} else {
this.args = args;
}
this.className = PNameFactory.newName(className);
this.jarPath = jarPath == null ? null : PNameFactory.newName(jarPath);
this.returnType = PNameFactory.newName(returnType);
this.functionKey = new PTableKey(this.tenantId, this.functionName.getString());
this.timeStamp = timeStamp;
int estimatedSize = SizedUtil.OBJECT_SIZE * 2 + 23 * SizedUtil.POINTER_SIZE + 4 * SizedUtil.INT_SIZE + 2 * SizedUtil.LONG_SIZE + 2 * SizedUtil.INT_OBJECT_SIZE +
PNameFactory.getEstimatedSize(tenantId) +
PNameFactory.getEstimatedSize(this.functionName) +
PNameFactory.getEstimatedSize(this.className) +
(jarPath==null?0:PNameFactory.getEstimatedSize(this.jarPath));
this.temporary = temporary;
this.replace = replace;
}
public PFunction(PFunction function) {
this(function, function.isTemporaryFunction());
}
public String getFunctionName() {
return functionName == null ? null : functionName.getString();
}
public List<FunctionArgument> getFunctionArguments() {
return args;
}
public String getClassName() {
return className.getString();
}
public String getJarPath() {
return jarPath == null ? null : jarPath.getString();
}
public String getReturnType() {
return returnType.getString();
}
public PTableKey getKey() {
return this.functionKey;
}
public long getTimeStamp() {
return this.timeStamp;
}
public PName getTenantId() {
return this.tenantId;
}
public boolean isTemporaryFunction() {
return temporary;
}
public static class FunctionArgument {
private final PName argumentType;
private final boolean isArrayType;
private final boolean isConstant;
private final LiteralExpression defaultValue;
private final LiteralExpression minValue;
private final LiteralExpression maxValue;
private short argPosition;
public FunctionArgument(String argumentType, boolean isArrayType, boolean isConstant, LiteralExpression defaultValue,
LiteralExpression minValue, LiteralExpression maxValue) {
this.argumentType = PNameFactory.newName(argumentType);
this.isArrayType = isArrayType;
this.isConstant = isConstant;
this.defaultValue = defaultValue;
this.minValue = minValue;
this.maxValue = maxValue;
}
public FunctionArgument(String argumentType, boolean isArrayType, boolean isConstant, LiteralExpression defaultValue,
LiteralExpression minValue, LiteralExpression maxValue, short argPosition) {
this(argumentType, isArrayType, isConstant, defaultValue, minValue, maxValue);
this.argPosition = argPosition;
}
public String getArgumentType() {
return argumentType.getString();
}
public boolean isConstant() {
return isConstant;
}
public boolean isArrayType() {
return isArrayType;
}
public LiteralExpression getDefaultValue() {
return defaultValue;
}
public LiteralExpression getMinValue() {
return minValue;
}
public LiteralExpression getMaxValue() {
return maxValue;
}
public short getArgPosition() {
return argPosition;
}
}
public static PFunctionProtos.PFunction toProto(PFunction function) {
PFunctionProtos.PFunction.Builder builder = PFunctionProtos.PFunction.newBuilder();
if(function.getTenantId() != null){
builder.setTenantId(ByteStringer.wrap(function.getTenantId().getBytes()));
}
builder.setFunctionName(function.getFunctionName());
builder.setClassname(function.getClassName());
if (function.getJarPath() != null) {
builder.setJarPath(function.getJarPath());
}
builder.setReturnType(function.getReturnType());
builder.setTimeStamp(function.getTimeStamp());
for(FunctionArgument arg: function.getFunctionArguments()) {
PFunctionProtos.PFunctionArg.Builder argBuilder = PFunctionProtos.PFunctionArg.newBuilder();
argBuilder.setArgumentType(arg.getArgumentType());
argBuilder.setIsArrayType(arg.isArrayType);
argBuilder.setIsConstant(arg.isConstant);
if(arg.getDefaultValue() != null) {
argBuilder.setDefaultValue((String)arg.getDefaultValue().getValue());
}
if(arg.getMinValue() != null) {
argBuilder.setMinValue((String)arg.getMinValue().getValue());
}
if(arg.getMaxValue() != null) {
argBuilder.setMaxValue((String)arg.getMaxValue().getValue());
}
builder.addArguments(argBuilder.build());
}
if(builder.hasIsReplace()) {
builder.setIsReplace(function.isReplace());
}
return builder.build();
}
public static PFunction createFromProto(
org.apache.phoenix.coprocessor.generated.PFunctionProtos.PFunction function) {
PName tenantId = null;
if(function.hasTenantId()){
tenantId = PNameFactory.newName(function.getTenantId().toByteArray());
}
String functionName = function.getFunctionName();
long timeStamp = function.getTimeStamp();
String className = function.getClassname();
String jarPath = function.getJarPath();
String returnType = function.getReturnType();
List<FunctionArgument> args = new ArrayList<FunctionArgument>(function.getArgumentsCount());
for(PFunctionArg arg: function.getArgumentsList()) {
String argType = arg.getArgumentType();
boolean isArrayType = arg.hasIsArrayType()?arg.getIsArrayType():false;
PDataType dataType = isArrayType ? PDataType.fromTypeId(PDataType
.sqlArrayType(SchemaUtil.normalizeIdentifier(SchemaUtil
.normalizeIdentifier(argType)))) : PDataType
.fromSqlTypeName(SchemaUtil.normalizeIdentifier(argType));
boolean isConstant = arg.hasIsConstant()?arg.getIsConstant():false;
String defaultValue = arg.hasDefaultValue()?arg.getDefaultValue():null;
String minValue = arg.hasMinValue()?arg.getMinValue():null;
String maxValue = arg.hasMaxValue()?arg.getMaxValue():null;
args.add(new FunctionArgument(argType, isArrayType, isConstant,
defaultValue == null ? null : LiteralExpression.newConstant((new LiteralParseNode(dataType.toObject(defaultValue))).getValue()),
minValue == null ? null : LiteralExpression.newConstant((new LiteralParseNode(dataType.toObject(minValue))).getValue()),
maxValue == null ? null : LiteralExpression.newConstant((new LiteralParseNode(dataType.toObject(maxValue))).getValue())));
}
return new PFunction(tenantId, functionName, args, returnType, className, jarPath,
timeStamp, false, function.hasIsReplace() ? true : false);
}
public int getEstimatedSize() {
return estimatedSize;
}
public boolean isReplace() {
return this.replace;
}
}