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;
}
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;
}
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;
}
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);
}
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());
}
Aggregations