blob: 1ad791b556e2c26dd5e3f70caa82b79485b57e6f [file] [log] [blame]
/*
* Copyright 2009-2012 by The Regents of the University of California
* Licensed 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 from
*
* 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 edu.uci.ics.asterix.metadata.functions;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import edu.uci.ics.asterix.external.library.AsterixExternalScalarFunctionInfo;
import edu.uci.ics.asterix.metadata.MetadataException;
import edu.uci.ics.asterix.metadata.MetadataManager;
import edu.uci.ics.asterix.metadata.MetadataTransactionContext;
import edu.uci.ics.asterix.metadata.entities.Datatype;
import edu.uci.ics.asterix.metadata.entities.Function;
import edu.uci.ics.asterix.om.functions.AsterixFunction;
import edu.uci.ics.asterix.om.typecomputer.base.IResultTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.ADoubleTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.AFloatTypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.AInt32TypeComputer;
import edu.uci.ics.asterix.om.typecomputer.impl.AStringTypeComputer;
import edu.uci.ics.asterix.om.types.AOrderedListType;
import edu.uci.ics.asterix.om.types.AUnorderedListType;
import edu.uci.ics.asterix.om.types.BuiltinType;
import edu.uci.ics.asterix.om.types.IAType;
import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression.FunctionKind;
import edu.uci.ics.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
import edu.uci.ics.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import edu.uci.ics.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
import edu.uci.ics.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
public class ExternalFunctionCompilerUtil implements Serializable {
private static Pattern orderedListPattern = Pattern.compile("\\[*\\]");
private static Pattern unorderedListPattern = Pattern.compile("[{{*}}]");
public static IFunctionInfo getExternalFunctionInfo(MetadataTransactionContext txnCtx, Function function)
throws MetadataException {
String functionKind = function.getKind();
IFunctionInfo finfo = null;
if (FunctionKind.SCALAR.toString().equalsIgnoreCase(functionKind)) {
finfo = getScalarFunctionInfo(txnCtx, function);
} else if (FunctionKind.AGGREGATE.toString().equalsIgnoreCase(functionKind)) {
finfo = getAggregateFunctionInfo(txnCtx, function);
} else if (FunctionKind.STATEFUL.toString().equalsIgnoreCase(functionKind)) {
finfo = getStatefulFunctionInfo(txnCtx, function);
} else if (FunctionKind.UNNEST.toString().equalsIgnoreCase(functionKind)) {
finfo = getUnnestFunctionInfo(txnCtx, function);
}
return finfo;
}
private static IFunctionInfo getScalarFunctionInfo(MetadataTransactionContext txnCtx, Function function)
throws MetadataException {
FunctionIdentifier fid = new FunctionIdentifier(function.getDataverseName(), function.getName(),
function.getArity());
IResultTypeComputer typeComputer = getResultTypeComputer(txnCtx, function);
List<IAType> arguments = new ArrayList<IAType>();
IAType returnType = null;
List<String> paramTypes = function.getParams();
for (String paramType : paramTypes) {
arguments.add(getTypeInfo(paramType, txnCtx, function));
}
returnType = getTypeInfo(function.getReturnType(), txnCtx, function);
AsterixExternalScalarFunctionInfo scalarFunctionInfo = new AsterixExternalScalarFunctionInfo(
fid.getNamespace(), new AsterixFunction(fid.getName(), fid.getArity()), returnType,
function.getFunctionBody(), function.getLanguage(), arguments, typeComputer);
return scalarFunctionInfo;
}
private static IAType getTypeInfo(String paramType, MetadataTransactionContext txnCtx, Function function)
throws MetadataException {
if (paramType.equalsIgnoreCase(BuiltinType.AINT32.getDisplayName())) {
return (BuiltinType.AINT32);
} else if (paramType.equalsIgnoreCase(BuiltinType.AFLOAT.getDisplayName())) {
return (BuiltinType.AFLOAT);
} else if (paramType.equalsIgnoreCase(BuiltinType.ASTRING.getDisplayName())) {
return (BuiltinType.ASTRING);
} else if (paramType.equalsIgnoreCase(BuiltinType.ADOUBLE.getDisplayName())) {
return (BuiltinType.ADOUBLE);
} else {
IAType collection = getCollectionType(paramType, txnCtx, function);
if (collection != null) {
return collection;
} else {
Datatype datatype;
datatype = MetadataManager.INSTANCE.getDatatype(txnCtx, function.getDataverseName(), paramType);
if (datatype == null) {
throw new MetadataException(" Type " + paramType + " not defined");
}
return (datatype.getDatatype());
}
}
}
private static IAType getCollectionType(String paramType, MetadataTransactionContext txnCtx, Function function)
throws MetadataException {
Matcher matcher = orderedListPattern.matcher(paramType);
if (matcher.find()) {
String subType = paramType.substring(paramType.indexOf('[') + 1, paramType.lastIndexOf(']'));
return new AOrderedListType(getTypeInfo(subType, txnCtx, function), "AOrderedList");
} else {
matcher = unorderedListPattern.matcher(paramType);
if (matcher.find()) {
String subType = paramType.substring(paramType.indexOf("{{") + 2, paramType.lastIndexOf("}}"));
return new AUnorderedListType(getTypeInfo(subType, txnCtx, function), "AUnorderedList");
}
}
return null;
}
private static IResultTypeComputer getResultTypeComputer(final MetadataTransactionContext txnCtx,
final Function function) throws MetadataException {
final IAType type = getTypeInfo(function.getReturnType(), txnCtx, function);
switch (type.getTypeTag()) {
case INT32:
return AInt32TypeComputer.INSTANCE;
case FLOAT:
return AFloatTypeComputer.INSTANCE;
case DOUBLE:
return ADoubleTypeComputer.INSTANCE;
case STRING:
return AStringTypeComputer.INSTANCE;
case ORDEREDLIST:
return new IResultTypeComputer() {
@Override
public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
return new AOrderedListType(((AOrderedListType) type).getItemType(), ((AOrderedListType) type)
.getItemType().getTypeName());
}
};
case UNORDEREDLIST:
return new IResultTypeComputer() {
@Override
public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException {
return new AUnorderedListType(type, type.getTypeName());
}
};
default:
IResultTypeComputer typeComputer = new IResultTypeComputer() {
@Override
public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env,
IMetadataProvider<?, ?> mp) throws AlgebricksException {
return type;
}
};
return typeComputer;
}
}
private static IAType getType(Function function, MetadataTransactionContext txnCtx) throws AlgebricksException {
IAType collectionType = null;
try {
collectionType = getCollectionType(function.getReturnType(), txnCtx, function);
if (collectionType != null) {
return collectionType;
} else {
Datatype datatype;
datatype = MetadataManager.INSTANCE.getDatatype(txnCtx, function.getDataverseName(),
function.getReturnType());
return datatype.getDatatype();
}
} catch (MetadataException me) {
throw new AlgebricksException(me);
}
}
private static IFunctionInfo getUnnestFunctionInfo(MetadataTransactionContext txnCtx, Function function) {
// TODO Auto-generated method stub
return null;
}
private static IFunctionInfo getStatefulFunctionInfo(MetadataTransactionContext txnCtx, Function function) {
// TODO Auto-generated method stub
return null;
}
private static IFunctionInfo getAggregateFunctionInfo(MetadataTransactionContext txnCtx, Function function) {
// TODO Auto-generated method stub
return null;
}
public static void main(String args[]) throws FileNotFoundException, IOException {
ExternalFunctionCompilerUtil obj = new ExternalFunctionCompilerUtil();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/tmp/ecu.obj"));
oos.writeObject(obj);
}
}