Search in sources :

Example 6 with AliasDescriptor

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;
}
Also used : ClassFactory(org.apache.derby.iapi.services.loader.ClassFactory) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) CompilerContext(org.apache.derby.iapi.sql.compile.CompilerContext) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary) AliasDescriptor(org.apache.derby.iapi.sql.dictionary.AliasDescriptor)

Example 7 with AliasDescriptor

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;
}
Also used : SchemaDescriptor(org.apache.derby.iapi.sql.dictionary.SchemaDescriptor) RoutineAliasInfo(org.apache.derby.catalog.types.RoutineAliasInfo) TypeDescriptor(org.apache.derby.catalog.TypeDescriptor) AliasDescriptor(org.apache.derby.iapi.sql.dictionary.AliasDescriptor) TableDescriptor(org.apache.derby.iapi.sql.dictionary.TableDescriptor)

Example 8 with AliasDescriptor

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;
}
Also used : SchemaDescriptor(org.apache.derby.iapi.sql.dictionary.SchemaDescriptor) CompilerContext(org.apache.derby.iapi.sql.compile.CompilerContext) AliasDescriptor(org.apache.derby.iapi.sql.dictionary.AliasDescriptor) SynonymAliasInfo(org.apache.derby.catalog.types.SynonymAliasInfo) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary)

Example 9 with AliasDescriptor

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;
}
Also used : SchemaDescriptor(org.apache.derby.iapi.sql.dictionary.SchemaDescriptor) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) UserDefinedTypeIdImpl(org.apache.derby.catalog.types.UserDefinedTypeIdImpl) AliasDescriptor(org.apache.derby.iapi.sql.dictionary.AliasDescriptor) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary)

Example 10 with AliasDescriptor

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);
    }
}
Also used : DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) AliasDescriptor(org.apache.derby.iapi.sql.dictionary.AliasDescriptor)

Aggregations

AliasDescriptor (org.apache.derby.iapi.sql.dictionary.AliasDescriptor)31 SchemaDescriptor (org.apache.derby.iapi.sql.dictionary.SchemaDescriptor)11 RoutineAliasInfo (org.apache.derby.catalog.types.RoutineAliasInfo)9 DataDictionary (org.apache.derby.iapi.sql.dictionary.DataDictionary)9 DataTypeDescriptor (org.apache.derby.iapi.types.DataTypeDescriptor)7 UUID (org.apache.derby.catalog.UUID)6 TableDescriptor (org.apache.derby.iapi.sql.dictionary.TableDescriptor)6 TypeDescriptor (org.apache.derby.catalog.TypeDescriptor)5 TransactionController (org.apache.derby.iapi.store.access.TransactionController)5 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)4 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)4 SQLVarchar (org.apache.derby.iapi.types.SQLVarchar)4 AliasInfo (org.apache.derby.catalog.AliasInfo)3 AggregateAliasInfo (org.apache.derby.catalog.types.AggregateAliasInfo)3 TupleDescriptor (org.apache.derby.iapi.sql.dictionary.TupleDescriptor)3 SQLChar (org.apache.derby.iapi.types.SQLChar)3 SQLLongint (org.apache.derby.iapi.types.SQLLongint)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 SynonymAliasInfo (org.apache.derby.catalog.types.SynonymAliasInfo)2