use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class AggregateNode method bindExpression.
/**
* Bind this operator. Determine the type of the subexpression,
* and pass that into the UserAggregate.
*
* @param fromList The query's FROM list
* @param subqueryList The subquery list being built as we find SubqueryNodes
* @param aggregates The aggregate list being built as we find AggregateNodes
*
* @return The new top of the expression tree.
*
* @exception StandardException Thrown on error
*/
@Override
ValueNode bindExpression(FromList fromList, SubqueryList subqueryList, List<AggregateNode> aggregates) throws StandardException {
DataDictionary dd = getDataDictionary();
DataTypeDescriptor dts = null;
ClassFactory cf;
cf = getClassFactory();
classInspector = cf.getClassInspector();
boolean noSchema = true;
if (userAggregateName != null) {
noSchema = (userAggregateName.getSchemaName() == null);
userAggregateName.bind();
}
// bind it now.
if (userAggregateName != null && uad == null) {
String schemaName = userAggregateName.getSchemaName();
AliasDescriptor ad = resolveAggregate(dd, getSchemaDescriptor(schemaName, true), userAggregateName.getTableName(), noSchema);
if (ad == null) {
throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, AliasDescriptor.getAliasType(AliasInfo.ALIAS_TYPE_AGGREGATE_AS_CHAR), userAggregateName.getTableName());
}
setUserDefinedAggregate(new UserAggregateDefinition(ad));
aggregateName = ad.getJavaClassName();
}
instantiateAggDef();
// if this is a user-defined aggregate
if (isUserDefinedAggregate()) {
AliasDescriptor ad = ((UserAggregateDefinition) uad).getAliasDescriptor();
boolean isModernBuiltinAggregate = SchemaDescriptor.STD_SYSTEM_SCHEMA_NAME.equals(ad.getSchemaName());
if (distinct && isModernBuiltinAggregate) {
throw StandardException.newException(SQLState.LANG_BAD_DISTINCT_AGG);
}
// set up dependency on the user-defined aggregate and compile a check for USAGE
// priv if needed
getCompilerContext().createDependency(ad);
if (isPrivilegeCollectionRequired()) {
//
if (!isModernBuiltinAggregate) {
getCompilerContext().addRequiredUsagePriv(ad);
}
}
}
// Add ourselves to the list of aggregates before we do anything else.
aggregates.add(this);
CompilerContext cc = getCompilerContext();
// operand being null means a count(*)
if (operand != null) {
int previousReliability = orReliability(CompilerContext.AGGREGATE_RESTRICTION);
bindOperand(fromList, subqueryList, aggregates);
cc.setReliability(previousReliability);
/*
** Make sure that we don't have an aggregate
** IMMEDIATELY below us. Don't search below
** any ResultSetNodes.
*/
HasNodeVisitor visitor = new HasNodeVisitor(this.getClass(), ResultSetNode.class);
operand.accept(visitor);
if (visitor.hasNode()) {
throw StandardException.newException(SQLState.LANG_USER_AGGREGATE_CONTAINS_AGGREGATE, getSQLName());
}
// Also forbid any window function inside an aggregate unless in
// subquery, cf. SQL 2003, section 10.9, SR 7 a).
SelectNode.checkNoWindowFunctions(operand, aggregateName);
/*
** Check the type of the operand. Make sure that the user
** defined aggregate can handle the operand datatype.
*/
dts = operand.getTypeServices();
/* Convert count(nonNullableColumn) to count(*) */
if (uad instanceof CountAggregateDefinition && !dts.isNullable()) {
setOperator(aggregateName);
setMethodName(aggregateName);
}
/*
** If we have a distinct, then the value expression
** MUST implement Orderable because we are going
** to process it using it as part of a sort.
*/
if (distinct) {
/*
** For now, we check to see if orderable() returns
** true for this type. In the future we may need
** to check to see if the type implements Orderable
**
*/
if (!operand.getTypeId().orderable(cf)) {
throw StandardException.newException(SQLState.LANG_COLUMN_NOT_ORDERABLE_DURING_EXECUTION, dts.getTypeId().getSQLTypeName());
}
}
/*
** Don't allow an untyped null
*/
if (operand instanceof UntypedNullConstantNode) {
throw StandardException.newException(SQLState.LANG_USER_AGGREGATE_BAD_TYPE_NULL, getSQLName());
}
}
/*
** Ask the aggregate definition whether it can handle
** the input datatype.
*/
aggregatorClassName = new StringBuffer();
DataTypeDescriptor resultType = uad.getAggregator(dts, aggregatorClassName);
if (resultType == null) {
throw StandardException.newException(SQLState.LANG_USER_AGGREGATE_BAD_TYPE, getSQLName(), operand.getTypeId().getSQLTypeName());
}
// coerced to the expected input type of the aggregator.
if (isUserDefinedAggregate()) {
ValueNode castNode = ((UserAggregateDefinition) uad).castInputValue(operand, getContextManager());
if (castNode != null) {
operand = castNode.bindExpression(fromList, subqueryList, aggregates);
}
}
checkAggregatorClassName(aggregatorClassName.toString());
setType(resultType);
return this;
}
use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class QueryTreeNode method bindOffsetFetch.
/**
* Bind the parameters of OFFSET n ROWS and FETCH FIRST n ROWS ONLY, if
* any.
*
* @param offset the OFFSET parameter, if any
* @param fetchFirst the FETCH parameter, if any
*
* @exception StandardException Thrown on error
*/
public static void bindOffsetFetch(ValueNode offset, ValueNode fetchFirst) throws StandardException {
if (offset instanceof ConstantNode) {
DataValueDescriptor dvd = ((ConstantNode) offset).getValue();
long val = dvd.getLong();
if (val < 0) {
throw StandardException.newException(SQLState.LANG_INVALID_ROW_COUNT_OFFSET, Long.toString(val));
}
} else if (offset instanceof ParameterNode) {
offset.setType(new DataTypeDescriptor(TypeId.getBuiltInTypeId(Types.BIGINT), false));
}
if (fetchFirst instanceof ConstantNode) {
DataValueDescriptor dvd = ((ConstantNode) fetchFirst).getValue();
long val = dvd.getLong();
if (val < 1) {
throw StandardException.newException(SQLState.LANG_INVALID_ROW_COUNT_FIRST, Long.toString(val));
}
} else if (fetchFirst instanceof ParameterNode) {
fetchFirst.setType(new DataTypeDescriptor(TypeId.getBuiltInTypeId(Types.BIGINT), false));
}
}
use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class QueryTreeNode method bindUserType.
/**
* Bind a UDT. This involves looking it up in the DataDictionary and filling
* in its class name.
*
* @param originalDTD A datatype: might be an unbound UDT and might not be
*
* @return The bound UDT if originalDTD was an unbound UDT; otherwise returns originalDTD.
*/
public DataTypeDescriptor bindUserType(DataTypeDescriptor originalDTD) throws StandardException {
// if the type is a table type, then we need to bind its user-typed columns
if (originalDTD.getCatalogType().isRowMultiSet()) {
return bindRowMultiSet(originalDTD);
}
// nothing to do if this is not a user defined type
if (!originalDTD.getTypeId().userType()) {
return originalDTD;
}
UserDefinedTypeIdImpl userTypeID = (UserDefinedTypeIdImpl) originalDTD.getTypeId().getBaseTypeId();
// also nothing to do if the type has already been resolved
if (userTypeID.isBound()) {
return originalDTD;
}
// ok, we have an unbound UDT. lookup this type in the data dictionary
DataDictionary dd = getDataDictionary();
SchemaDescriptor typeSchema = getSchemaDescriptor(userTypeID.getSchemaName());
char udtNameSpace = AliasInfo.ALIAS_NAME_SPACE_UDT_AS_CHAR;
String unqualifiedTypeName = userTypeID.getUnqualifiedName();
AliasDescriptor ad = dd.getAliasDescriptor(typeSchema.getUUID().toString(), unqualifiedTypeName, udtNameSpace);
if (ad == null) {
throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, AliasDescriptor.getAliasType(udtNameSpace), unqualifiedTypeName);
}
createTypeDependency(ad);
DataTypeDescriptor result = new DataTypeDescriptor(TypeId.getUserDefinedTypeId(typeSchema.getSchemaName(), unqualifiedTypeName, ad.getJavaClassName()), originalDTD.isNullable());
return result;
}
use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class QueryTreeNode method addUDTUsagePriv.
/**
* Add USAGE privilege for a single UDT.
*/
void addUDTUsagePriv(ValueNode val) throws StandardException {
if (!isPrivilegeCollectionRequired()) {
return;
}
DataTypeDescriptor dtd = val.getTypeServices();
if ((dtd != null) && dtd.getTypeId().userType()) {
AliasDescriptor ad = getUDTDesc(dtd);
getCompilerContext().addRequiredUsagePriv(ad);
}
}
use of org.apache.derby.iapi.types.DataTypeDescriptor in project derby by apache.
the class QueryTreeNode method bindRowMultiSet.
/**
* Bind the UDTs in a table type.
*
* @param originalDTD A datatype: might be an unbound UDT and might not be
*
* @return The bound table type if originalDTD was an unbound table type; otherwise returns originalDTD.
*/
public DataTypeDescriptor bindRowMultiSet(DataTypeDescriptor originalDTD) throws StandardException {
if (!originalDTD.getCatalogType().isRowMultiSet()) {
return originalDTD;
}
RowMultiSetImpl originalMultiSet = (RowMultiSetImpl) originalDTD.getTypeId().getBaseTypeId();
TypeDescriptor[] columnTypes = originalMultiSet.getTypes();
int columnCount = columnTypes.length;
for (int i = 0; i < columnCount; i++) {
columnTypes[i] = bindUserCatalogType(columnTypes[i]);
}
originalMultiSet.setTypes(columnTypes);
return originalDTD;
}
Aggregations