Search in sources :

Example 1 with RoutineAliasInfo

use of org.apache.derby.catalog.types.RoutineAliasInfo in project derby by apache.

the class DataDictionaryImpl method getRoutineList.

/**
 *		Get the list of routines matching the schema and routine name.
 *		While we only support a single alias for a given name,namespace just
 *		return a list of zero or one item.
 *		If the schema is SYSFUN then do not use the system catalogs,
 *        but instead look up the routines from the in-memory table driven
 *		by the contents of SYSFUN_FUNCTIONS.
 */
public java.util.List<AliasDescriptor> getRoutineList(String schemaID, String routineName, char nameSpace) throws StandardException {
    // We expect to find just a single function, since we currently
    // don't support multiple routines with the same name, but use a
    // list to support future extension.
    List<AliasDescriptor> list = new ArrayList<AliasDescriptor>(1);
    // Special in-memory table lookup for SYSFUN
    if (schemaID.equals(SchemaDescriptor.SYSFUN_SCHEMA_UUID) && nameSpace == AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR) {
        for (int f = 0; f < DataDictionaryImpl.SYSFUN_FUNCTIONS.length; f++) {
            String[] details = DataDictionaryImpl.SYSFUN_FUNCTIONS[f];
            String name = details[0];
            if (!name.equals(routineName))
                continue;
            AliasDescriptor ad = sysfunDescriptors[f];
            if (ad == null) {
                // details[1] Return type
                TypeDescriptor rt = DataTypeDescriptor.getBuiltInDataTypeDescriptor(details[1]).getCatalogType();
                boolean isDeterministic = Boolean.valueOf(details[SYSFUN_DETERMINISTIC_INDEX]).booleanValue();
                boolean hasVarargs = Boolean.valueOf(details[SYSFUN_VARARGS_INDEX]).booleanValue();
                // Determine the number of arguments (could be zero).
                int paramCount = details.length - SYSFUN_FIRST_PARAMETER_INDEX;
                TypeDescriptor[] pt = new TypeDescriptor[paramCount];
                String[] paramNames = new String[paramCount];
                int[] paramModes = new int[paramCount];
                for (int i = 0; i < paramCount; i++) {
                    pt[i] = DataTypeDescriptor.getBuiltInDataTypeDescriptor(details[SYSFUN_FIRST_PARAMETER_INDEX + i]).getCatalogType();
                    // Dummy names
                    paramNames[i] = "P" + (i + 1);
                    // All parameters must be IN.
                    paramModes[i] = (ParameterMetaData.parameterModeIn);
                }
                // details[3] = java method
                RoutineAliasInfo ai = new RoutineAliasInfo(details[3], paramCount, paramNames, pt, paramModes, 0, RoutineAliasInfo.PS_JAVA, RoutineAliasInfo.NO_SQL, isDeterministic, hasVarargs, false, /* hasDefinersRights */
                false, rt);
                // details[2] = class name
                ad = new AliasDescriptor(this, uuidFactory.createUUID(), name, uuidFactory.recreateUUID(schemaID), details[2], AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR, AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR, true, ai, null);
                sysfunDescriptors[f] = ad;
            }
            list.add(ad);
        }
        return list;
    }
    AliasDescriptor ad = getAliasDescriptor(schemaID, routineName, nameSpace);
    if (ad != null) {
        list.add(ad);
    }
    return list;
}
Also used : TypeDescriptor(org.apache.derby.catalog.TypeDescriptor) DataTypeDescriptor(org.apache.derby.iapi.types.DataTypeDescriptor) RoutineAliasInfo(org.apache.derby.catalog.types.RoutineAliasInfo) AliasDescriptor(org.apache.derby.iapi.sql.dictionary.AliasDescriptor) ArrayList(java.util.ArrayList) SQLLongint(org.apache.derby.iapi.types.SQLLongint)

Example 2 with RoutineAliasInfo

use of org.apache.derby.catalog.types.RoutineAliasInfo in project derby by apache.

the class DataDictionaryImpl method createSystemProcedureOrFunction.

/**
 * Generic create procedure routine.
 * <p>
 * Takes the input procedure and inserts it into the appropriate
 * catalog.
 *
 * Assumes all arguments are "IN" type.
 *
 * @param routine_name  name of the routine in java and the SQL
 *                      procedure name.
 *
 * @param arg_names     String array of procedure argument names in order.
 *
 * @param arg_types     Internal SQL types of the arguments
 *
 * @param routine_sql_control
 *                      One of the RoutineAliasInfo constants:
 *                          MODIFIES_SQL_DATA
 *                          READS_SQL_DATA
 *                          CONTAINS_SQL
 *                          NO_SQL
 *
 * @param isDeterministic True if the procedure/function is DETERMINISTIC
 *
 * @param return_type   null for procedure.  For functions the return type
 *                      of the function.
 *
 * @param newlyCreatedRoutines evolving set of routines, some of which may need permissions later on
 * @param tc            an instance of the TransactionController
 *
 * @param procClass     the fully qualified name of the class that contains
 *                      java definitions for the stored procedures
 *
 * @return UUID 		UUID of system routine that got created.
 *
 * @exception  StandardException  Standard exception policy.
 */
private final UUID createSystemProcedureOrFunction(String routine_name, UUID schema_uuid, String[] arg_names, TypeDescriptor[] arg_types, int num_out_param, int num_result_sets, short routine_sql_control, boolean isDeterministic, boolean hasVarargs, TypeDescriptor return_type, HashSet<String> newlyCreatedRoutines, TransactionController tc, String procClass) throws StandardException {
    int num_args = 0;
    if (arg_names != null)
        num_args = arg_names.length;
    if (SanityManager.DEBUG) {
        if (num_args != 0) {
            SanityManager.ASSERT(arg_names != null);
            SanityManager.ASSERT(arg_types != null);
            SanityManager.ASSERT(arg_names.length == arg_types.length);
        }
    }
    // all args are only "in" arguments
    int[] arg_modes = null;
    if (num_args != 0) {
        arg_modes = new int[num_args];
        int num_in_param = num_args - num_out_param;
        for (int i = 0; i < num_in_param; i++) arg_modes[i] = (ParameterMetaData.parameterModeIn);
        for (int i = 0; i < num_out_param; i++) arg_modes[num_in_param + i] = (ParameterMetaData.parameterModeOut);
    }
    RoutineAliasInfo routine_alias_info = new RoutineAliasInfo(// name of routine
    routine_name, // number of params
    num_args, // names of params
    arg_names, // types of params
    arg_types, // all "IN" params
    arg_modes, // number of result sets
    num_result_sets, // link to java routine
    RoutineAliasInfo.PS_JAVA, // one of:
    routine_sql_control, // whether the procedure/function is DETERMINISTIC
    isDeterministic, // whether the procedure/function has VARARGS
    hasVarargs, // not definer's rights
    false, // true - calledOnNullInput
    true, return_type);
    UUID routine_uuid = getUUIDFactory().createUUID();
    AliasDescriptor ads = new AliasDescriptor(this, routine_uuid, routine_name, schema_uuid, procClass, (return_type == null) ? AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR : AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR, (return_type == null) ? AliasInfo.ALIAS_NAME_SPACE_PROCEDURE_AS_CHAR : AliasInfo.ALIAS_NAME_SPACE_FUNCTION_AS_CHAR, false, routine_alias_info, null);
    addDescriptor(ads, null, DataDictionary.SYSALIASES_CATALOG_NUM, false, tc);
    newlyCreatedRoutines.add(routine_name);
    return routine_uuid;
}
Also used : RoutineAliasInfo(org.apache.derby.catalog.types.RoutineAliasInfo) AliasDescriptor(org.apache.derby.iapi.sql.dictionary.AliasDescriptor) UUID(org.apache.derby.catalog.UUID) SQLLongint(org.apache.derby.iapi.types.SQLLongint)

Example 3 with RoutineAliasInfo

use of org.apache.derby.catalog.types.RoutineAliasInfo 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 4 with RoutineAliasInfo

use of org.apache.derby.catalog.types.RoutineAliasInfo in project derby by apache.

the class CreateAliasNode method bindStatement.

// We inherit the generate() method from DDLStatementNode.
/**
 * Bind this CreateAliasNode.  This means doing any static error
 * checking that can be done before actually creating the table.
 * For example, verifying that the column name list does not
 * contain any duplicate column names.
 *
 * @exception StandardException		Thrown on error
 */
@Override
public void bindStatement() throws StandardException {
    // Are we dealing with user defined function or procedure?
    if (aliasType == AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR || aliasType == AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR) {
        RoutineAliasInfo rai = (RoutineAliasInfo) aliasInfo;
        // Set the collation for all string types in parameters
        // and return types including row multi-sets to be that of
        // the schema the routine is being defined in.
        rai.setCollationTypeForAllStringTypes(getSchemaDescriptor().getCollationType());
        bindParameterTypes((RoutineAliasInfo) aliasInfo);
        if (rai.hasVarargs()) {
            switch(rai.getParameterStyle()) {
                case RoutineAliasInfo.PS_DERBY_JDBC_RESULT_SET:
                case RoutineAliasInfo.PS_DERBY:
                    break;
                default:
                    throw StandardException.newException(SQLState.LANG_VARARGS_PARAMETER_STYLE);
            }
            if (rai.getMaxDynamicResultSets() > 0) {
                throw StandardException.newException(SQLState.LANG_VARARGS_RETURN_RESULT_SETS);
            }
        }
        if ((rai.getParameterStyle() == RoutineAliasInfo.PS_DERBY) && !rai.hasVarargs()) {
            throw StandardException.newException(SQLState.LANG_DERBY_PARAMETER_STYLE);
        }
    }
    // validity checking for UDTs
    if (aliasType == AliasInfo.ALIAS_TYPE_UDT_AS_CHAR) {
        // 
        // Make sure that the java class name is not the name of a builtin
        // type. This skirts problems caused by logic across the system
        // which assumes a tight association between the builtin SQL types
        // and the Java classes which implement them.
        // 
        // For security reasons we do not allow the user to bind a UDT
        // to a Derby class.
        // 
        TypeId[] allSystemTypeIds = TypeId.getAllBuiltinTypeIds();
        int systemTypeCount = allSystemTypeIds.length;
        boolean foundConflict = javaClassName.startsWith("org.apache.derby.");
        if (!foundConflict) {
            for (int i = 0; i < systemTypeCount; i++) {
                TypeId systemType = allSystemTypeIds[i];
                String systemTypeName = systemType.getCorrespondingJavaTypeName();
                if (systemTypeName.equals(javaClassName)) {
                    foundConflict = true;
                    break;
                }
            }
        }
        if (foundConflict) {
            throw StandardException.newException(SQLState.LANG_UDT_BUILTIN_CONFLICT, javaClassName);
        }
        return;
    }
    // validity checking for aggregates
    if (aliasType == AliasInfo.ALIAS_TYPE_AGGREGATE_AS_CHAR) {
        bindAggregate();
    }
    // runtime execution. Synonyms do need some validity checks.
    if (aliasType != AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR)
        return;
    // a temporary table is created later with same name.
    if (isSessionSchema(getSchemaDescriptor().getSchemaName()))
        throw StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES);
    String targetSchema = ((SynonymAliasInfo) aliasInfo).getSynonymSchema();
    String targetTable = ((SynonymAliasInfo) aliasInfo).getSynonymTable();
    if (this.getObjectName().equals(targetSchema, targetTable))
        throw StandardException.newException(SQLState.LANG_SYNONYM_CIRCULAR, this.getFullName(), targetSchema + "." + targetTable);
    SchemaDescriptor targetSD = getSchemaDescriptor(targetSchema, false);
    if ((targetSD != null) && isSessionSchema(targetSD))
        throw StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES);
}
Also used : TypeId(org.apache.derby.iapi.types.TypeId) SchemaDescriptor(org.apache.derby.iapi.sql.dictionary.SchemaDescriptor) RoutineAliasInfo(org.apache.derby.catalog.types.RoutineAliasInfo) SynonymAliasInfo(org.apache.derby.catalog.types.SynonymAliasInfo)

Example 5 with RoutineAliasInfo

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

Aggregations

RoutineAliasInfo (org.apache.derby.catalog.types.RoutineAliasInfo)14 AliasDescriptor (org.apache.derby.iapi.sql.dictionary.AliasDescriptor)9 TypeDescriptor (org.apache.derby.catalog.TypeDescriptor)6 SchemaDescriptor (org.apache.derby.iapi.sql.dictionary.SchemaDescriptor)4 DataTypeDescriptor (org.apache.derby.iapi.types.DataTypeDescriptor)4 ResultSet (java.sql.ResultSet)3 UUID (org.apache.derby.catalog.UUID)3 TableDescriptor (org.apache.derby.iapi.sql.dictionary.TableDescriptor)3 PreparedStatement (java.sql.PreparedStatement)2 ArrayList (java.util.ArrayList)2 AggregateAliasInfo (org.apache.derby.catalog.types.AggregateAliasInfo)2 SynonymAliasInfo (org.apache.derby.catalog.types.SynonymAliasInfo)2 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)2 TransactionController (org.apache.derby.iapi.store.access.TransactionController)2 SQLLongint (org.apache.derby.iapi.types.SQLLongint)2 TypeId (org.apache.derby.iapi.types.TypeId)2 Method (java.lang.reflect.Method)1 Connection (java.sql.Connection)1 ResultSetMetaData (java.sql.ResultSetMetaData)1 SQLException (java.sql.SQLException)1