use of org.apache.derby.catalog.types.AggregateAliasInfo in project derby by apache.
the class CreateAliasNode method bindAggregate.
/**
* Extra logic for binding user-defined aggregate definitions
*/
private void bindAggregate() throws StandardException {
String unqualifiedName = getRelativeName();
//
// A user-defined aggregate cannot have the name of a builtin function which takes 1 argument.
//
SchemaDescriptor sysfun = getSchemaDescriptor("SYSFUN", true);
List<AliasDescriptor> systemFunctions = getDataDictionary().getRoutineList(sysfun.getUUID().toString(), unqualifiedName, AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR);
for (int i = 0; i < systemFunctions.size(); i++) {
AliasDescriptor function = systemFunctions.get(i);
RoutineAliasInfo routineInfo = (RoutineAliasInfo) function.getAliasInfo();
int parameterCount = routineInfo.getParameterCount();
if (parameterCount == 1) {
throw illegalAggregate();
}
}
//
for (int i = 0; i < NON_RESERVED_FUNCTION_NAMES.length; i++) {
if (NON_RESERVED_FUNCTION_NAMES[i].equals(unqualifiedName)) {
throw illegalAggregate();
}
}
//
for (int i = 0; i < NON_RESERVED_AGGREGATES.length; i++) {
if (NON_RESERVED_AGGREGATES[i].equals(unqualifiedName)) {
throw illegalAggregate();
}
}
// now bind the input and return types
AggregateAliasInfo aai = (AggregateAliasInfo) aliasInfo;
aai.setCollationTypeForAllStringTypes(getSchemaDescriptor().getCollationType());
}
use of org.apache.derby.catalog.types.AggregateAliasInfo in project derby by apache.
the class DDLConstantAction method adjustUDTDependencies.
/**
* Add and drop dependencies of a routine on UDTs.
*
* @param lcc Interpreter's state variable for this session.
* @param dd Metadata
* @param ad Alias descriptor for the routine
* @param adding True if we are adding dependencies, false if we're dropping them
*/
protected void adjustUDTDependencies(LanguageConnectionContext lcc, DataDictionary dd, AliasDescriptor ad, boolean adding) throws StandardException {
RoutineAliasInfo routineInfo = null;
AggregateAliasInfo aggInfo = null;
// nothing to do if this is not a routine
switch(ad.getAliasType()) {
case AliasInfo.ALIAS_TYPE_AGGREGATE_AS_CHAR:
aggInfo = (AggregateAliasInfo) ad.getAliasInfo();
break;
case AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR:
case AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR:
routineInfo = (RoutineAliasInfo) ad.getAliasInfo();
break;
default:
return;
}
TransactionController tc = lcc.getTransactionExecute();
HashMap<String, AliasDescriptor> addUdtMap = new HashMap<String, AliasDescriptor>();
HashMap<String, AliasDescriptor> dropUdtMap = new HashMap<String, AliasDescriptor>();
HashMap<String, AliasDescriptor> udtMap = adding ? addUdtMap : dropUdtMap;
TypeDescriptor rawReturnType = aggInfo != null ? aggInfo.getReturnType() : routineInfo.getReturnType();
if (rawReturnType != null) {
AliasDescriptor returnTypeAD = dd.getAliasDescriptorForUDT(tc, DataTypeDescriptor.getType(rawReturnType));
if (returnTypeAD != null) {
udtMap.put(returnTypeAD.getObjectID().toString(), returnTypeAD);
}
}
// table functions can have udt columns. track those dependencies.
if ((rawReturnType != null) && rawReturnType.isRowMultiSet()) {
TypeDescriptor[] columnTypes = rawReturnType.getRowTypes();
int columnCount = columnTypes.length;
for (int i = 0; i < columnCount; i++) {
AliasDescriptor columnTypeAD = dd.getAliasDescriptorForUDT(tc, DataTypeDescriptor.getType(columnTypes[i]));
if (columnTypeAD != null) {
udtMap.put(columnTypeAD.getObjectID().toString(), columnTypeAD);
}
}
}
TypeDescriptor[] paramTypes = aggInfo != null ? new TypeDescriptor[] { aggInfo.getForType() } : routineInfo.getParameterTypes();
if (paramTypes != null) {
int paramCount = paramTypes.length;
for (int i = 0; i < paramCount; i++) {
AliasDescriptor paramType = dd.getAliasDescriptorForUDT(tc, DataTypeDescriptor.getType(paramTypes[i]));
if (paramType != null) {
udtMap.put(paramType.getObjectID().toString(), paramType);
}
}
}
adjustUDTDependencies(lcc, dd, ad, addUdtMap, dropUdtMap);
}
use of org.apache.derby.catalog.types.AggregateAliasInfo in project derby by apache.
the class UserAggregateDefinition method getAggregator.
/**
* Determines the result datatype and verifies that the input datatype is correct.
*
* @param inputType the input type
* @param aggregatorClass (Output arg) the name of the Derby execution-time class which wraps the aggregate logic
*
* @return the result type of the user-defined aggregator
*/
public final DataTypeDescriptor getAggregator(DataTypeDescriptor inputType, StringBuffer aggregatorClass) throws StandardException {
try {
CompilerContext cc = (CompilerContext) QueryTreeNode.getContext(CompilerContext.CONTEXT_ID);
ClassFactory classFactory = cc.getClassFactory();
TypeCompilerFactory tcf = cc.getTypeCompilerFactory();
Class<?> derbyAggregatorInterface = classFactory.loadApplicationClass("org.apache.derby.agg.Aggregator");
Class<?> userAggregatorClass = classFactory.loadApplicationClass(_alias.getJavaClassName());
Class[][] typeBounds = classFactory.getClassInspector().getTypeBounds(derbyAggregatorInterface, userAggregatorClass);
if ((typeBounds == null) || (typeBounds.length != AGGREGATOR_PARAM_COUNT) || (typeBounds[INPUT_TYPE] == null) || (typeBounds[RETURN_TYPE] == null)) {
throw StandardException.newException(SQLState.LANG_ILLEGAL_UDA_CLASS, _alias.getSchemaName(), _alias.getName(), userAggregatorClass.getName());
}
Class<?>[] genericParameterTypes = classFactory.getClassInspector().getGenericParameterTypes(derbyAggregatorInterface, userAggregatorClass);
if (genericParameterTypes == null) {
genericParameterTypes = new Class<?>[AGGREGATOR_PARAM_COUNT];
}
AggregateAliasInfo aai = (AggregateAliasInfo) _alias.getAliasInfo();
DataTypeDescriptor expectedInputType = DataTypeDescriptor.getType(aai.getForType());
DataTypeDescriptor expectedReturnType = DataTypeDescriptor.getType(aai.getReturnType());
Class<?> expectedInputClass = getJavaClass(classFactory, expectedInputType);
Class<?> expectedReturnClass = getJavaClass(classFactory, expectedReturnType);
// the input operand must be coercible to the expected input type of the aggregate
if (!tcf.getTypeCompiler(expectedInputType.getTypeId()).storable(inputType.getTypeId(), classFactory)) {
return null;
}
//
// Make sure that the declared input type of the UDA actually falls within
// the type bounds of the Aggregator implementation.
//
Class[] inputBounds = typeBounds[INPUT_TYPE];
for (int i = 0; i < inputBounds.length; i++) {
vetCompatibility((Class<?>) inputBounds[i], expectedInputClass, SQLState.LANG_UDA_WRONG_INPUT_TYPE);
}
if (genericParameterTypes[INPUT_TYPE] != null) {
vetCompatibility(genericParameterTypes[INPUT_TYPE], expectedInputClass, SQLState.LANG_UDA_WRONG_INPUT_TYPE);
}
//
// Make sure that the declared return type of the UDA actually falls within
// the type bounds of the Aggregator implementation.
//
Class[] returnBounds = typeBounds[RETURN_TYPE];
for (int i = 0; i < returnBounds.length; i++) {
vetCompatibility(returnBounds[i], expectedReturnClass, SQLState.LANG_UDA_WRONG_RETURN_TYPE);
}
if (genericParameterTypes[RETURN_TYPE] != null) {
vetCompatibility(genericParameterTypes[RETURN_TYPE], expectedReturnClass, SQLState.LANG_UDA_WRONG_RETURN_TYPE);
}
aggregatorClass.append(ClassName.UserDefinedAggregator);
return expectedReturnType;
} catch (ClassNotFoundException cnfe) {
throw aggregatorInstantiation(cnfe);
}
}
use of org.apache.derby.catalog.types.AggregateAliasInfo in project derby by apache.
the class UserAggregateDefinition method castInputValue.
/**
* Wrap the input operand in an implicit CAST node as necessary in order to
* coerce it the correct type for the aggregator. Return null if no cast is necessary.
*/
final ValueNode castInputValue(ValueNode inputValue, ContextManager cm) throws StandardException {
AggregateAliasInfo aai = (AggregateAliasInfo) _alias.getAliasInfo();
DataTypeDescriptor expectedInputType = DataTypeDescriptor.getType(aai.getForType());
DataTypeDescriptor actualInputType = inputValue.getTypeServices();
// no cast needed if the types match exactly
if (expectedInputType.isExactTypeAndLengthMatch(actualInputType)) {
return null;
} else {
return StaticMethodCallNode.makeCast(inputValue, expectedInputType, cm);
}
}
use of org.apache.derby.catalog.types.AggregateAliasInfo in project derby by apache.
the class AggregateNode method resolveBuiltinAggregate.
/**
* Construct an AliasDescriptor for a modern builtin aggregate.
*/
private static AliasDescriptor resolveBuiltinAggregate(DataDictionary dd, String rawName, boolean noSchema) throws StandardException {
// builtin aggregates may not be schema-qualified
if (!noSchema) {
return null;
}
BuiltinAggDescriptor bad = null;
for (BuiltinAggDescriptor aggDescriptor : BUILTIN_MODERN_AGGS) {
if (aggDescriptor.aggName.equals(rawName)) {
bad = aggDescriptor;
break;
}
}
if (bad == null) {
return null;
}
AliasInfo aliasInfo = new AggregateAliasInfo(bad.argType, bad.returnType);
return new AliasDescriptor(dd, null, rawName, dd.getSystemSchemaDescriptor().getUUID(), bad.aggClassName, AliasInfo.ALIAS_TYPE_AGGREGATE_AS_CHAR, AliasInfo.ALIAS_NAME_SPACE_AGGREGATE_AS_CHAR, false, aliasInfo, null);
}
Aggregations