use of org.apache.derby.iapi.sql.dictionary.AliasDescriptor 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.sql.dictionary.AliasDescriptor in project derby by apache.
the class PrivilegeNode method bind.
/**
* Bind this GrantNode. Resolve all table, column, and routine references. Register
* a dependency on the object of the privilege if it has not already been done
*
* @param dependencies The list of privilege objects that this statement has already seen.
* If the object of this privilege is not in the list then this statement is registered
* as dependent on the object.
* @param grantees The list of grantees
* @param isGrant grant if true; revoke if false
* @return the bound node
*
* @exception StandardException Standard error policy.
*/
public QueryTreeNode bind(HashMap<Provider, Provider> dependencies, List<String> grantees, boolean isGrant) throws StandardException {
// The below code handles the case where objectName.getSchemaName()
// returns null, in which case we'll fetch the schema descriptor for
// the current compilation schema (see getSchemaDescriptor).
SchemaDescriptor sd = getSchemaDescriptor(objectName.getSchemaName(), true);
objectName.setSchemaName(sd.getSchemaName());
// Can not grant/revoke permissions from self
if (grantees.contains(sd.getAuthorizationId())) {
throw StandardException.newException(SQLState.AUTH_GRANT_REVOKE_NOT_ALLOWED, objectName.getFullTableName());
}
switch(objectType) {
case TABLE_PRIVILEGES:
// can't grant/revoke privileges on system tables
if (sd.isSystemSchema()) {
throw StandardException.newException(SQLState.AUTH_GRANT_REVOKE_NOT_ALLOWED, objectName.getFullTableName());
}
TableDescriptor td = getTableDescriptor(objectName.getTableName(), sd);
if (td == null) {
throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND, objectName);
}
// a temporary table is created later with same name.
if (isSessionSchema(sd.getSchemaName())) {
throw StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES);
}
if (td.getTableType() != TableDescriptor.BASE_TABLE_TYPE && td.getTableType() != TableDescriptor.VIEW_TYPE) {
throw StandardException.newException(SQLState.AUTH_GRANT_REVOKE_NOT_ALLOWED, objectName.getFullTableName());
}
specificPrivileges.bind(td, isGrant);
dependencyProvider = td;
break;
case ROUTINE_PRIVILEGES:
if (!sd.isSchemaWithGrantableRoutines()) {
throw StandardException.newException(SQLState.AUTH_GRANT_REVOKE_NOT_ALLOWED, objectName.getFullTableName());
}
AliasDescriptor proc = null;
List<AliasDescriptor> list = getDataDictionary().getRoutineList(sd.getUUID().toString(), objectName.getTableName(), routineDesignator.isFunction ? AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR : AliasInfo.ALIAS_NAME_SPACE_PROCEDURE_AS_CHAR);
if (routineDesignator.paramTypeList == null) {
// No signature was specified. Make sure that there is exactly one routine with that name.
if (list.size() > 1) {
throw StandardException.newException((routineDesignator.isFunction ? SQLState.LANG_AMBIGUOUS_FUNCTION_NAME : SQLState.LANG_AMBIGUOUS_PROCEDURE_NAME), objectName.getFullTableName());
}
if (list.size() != 1) {
if (routineDesignator.isFunction) {
throw StandardException.newException(SQLState.LANG_NO_SUCH_FUNCTION, objectName.getFullTableName());
} else {
throw StandardException.newException(SQLState.LANG_NO_SUCH_PROCEDURE, objectName.getFullTableName());
}
}
proc = list.get(0);
} else {
// The full signature was specified
boolean found = false;
for (int i = list.size() - 1; (!found) && i >= 0; i--) {
proc = list.get(i);
RoutineAliasInfo routineInfo = (RoutineAliasInfo) proc.getAliasInfo();
int parameterCount = routineInfo.getParameterCount();
if (parameterCount != routineDesignator.paramTypeList.size())
continue;
TypeDescriptor[] parameterTypes = routineInfo.getParameterTypes();
found = true;
for (int parmIdx = 0; parmIdx < parameterCount; parmIdx++) {
if (!parameterTypes[parmIdx].equals(routineDesignator.paramTypeList.get(parmIdx))) {
found = false;
break;
}
}
}
if (!found) {
// reconstruct the signature for the error message
StringBuilder sb = new StringBuilder(objectName.getFullTableName());
sb.append("(");
for (int i = 0; i < routineDesignator.paramTypeList.size(); i++) {
if (i > 0)
sb.append(",");
sb.append(routineDesignator.paramTypeList.get(i).toString());
}
throw StandardException.newException(SQLState.LANG_NO_SUCH_METHOD_ALIAS, sb.toString());
}
}
routineDesignator.setAliasDescriptor(proc);
dependencyProvider = proc;
break;
case AGGREGATE_PRIVILEGES:
dependencyProvider = getDataDictionary().getAliasDescriptor(sd.getUUID().toString(), objectName.getTableName(), AliasInfo.ALIAS_NAME_SPACE_AGGREGATE_AS_CHAR);
if (dependencyProvider == null) {
throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, "DERBY AGGREGATE", objectName.getFullTableName());
}
break;
case SEQUENCE_PRIVILEGES:
dependencyProvider = getDataDictionary().getSequenceDescriptor(sd, objectName.getTableName());
if (dependencyProvider == null) {
throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, "SEQUENCE", objectName.getFullTableName());
}
break;
case UDT_PRIVILEGES:
dependencyProvider = getDataDictionary().getAliasDescriptor(sd.getUUID().toString(), objectName.getTableName(), AliasInfo.ALIAS_NAME_SPACE_UDT_AS_CHAR);
if (dependencyProvider == null) {
throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, "TYPE", objectName.getFullTableName());
}
break;
default:
throw unimplementedFeature();
}
if (dependencyProvider != null) {
if (dependencies.get(dependencyProvider) == null) {
getCompilerContext().createDependency(dependencyProvider);
dependencies.put(dependencyProvider, dependencyProvider);
}
}
return this;
}
use of org.apache.derby.iapi.sql.dictionary.AliasDescriptor in project derby by apache.
the class QueryTreeNode method resolveTableToSynonym.
/**
* Resolve table/view reference to a synonym. May have to follow a synonym chain.
*
* @param tabName to match for a synonym
*
* @return Synonym TableName if a match is found, NULL otherwise.
*
* @exception StandardException Thrown on error
*/
TableName resolveTableToSynonym(TableName tabName) throws StandardException {
DataDictionary dd = getDataDictionary();
String nextSynonymTable = tabName.getTableName();
String nextSynonymSchema = tabName.getSchemaName();
boolean found = false;
CompilerContext cc = getCompilerContext();
// the following loop shouldn't loop forever.
for (; ; ) {
SchemaDescriptor nextSD = getSchemaDescriptor(nextSynonymSchema, false);
if (nextSD == null || nextSD.getUUID() == null)
break;
AliasDescriptor nextAD = dd.getAliasDescriptor(nextSD.getUUID().toString(), nextSynonymTable, AliasInfo.ALIAS_NAME_SPACE_SYNONYM_AS_CHAR);
if (nextAD == null)
break;
/* Query is dependent on the AliasDescriptor */
cc.createDependency(nextAD);
found = true;
SynonymAliasInfo info = ((SynonymAliasInfo) nextAD.getAliasInfo());
nextSynonymTable = info.getSynonymTable();
nextSynonymSchema = info.getSynonymSchema();
}
if (!found)
return null;
TableName tableName = new TableName(nextSynonymSchema, nextSynonymTable, getContextManager());
return tableName;
}
use of org.apache.derby.iapi.sql.dictionary.AliasDescriptor 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.sql.dictionary.AliasDescriptor 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);
}
}
Aggregations