use of org.apache.derby.catalog.types.SynonymAliasInfo 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.catalog.types.SynonymAliasInfo 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.SynonymAliasInfo in project derby by apache.
the class CreateAliasConstantAction method executeConstantAction.
// INTERFACE METHODS
/**
* This is the guts of the Execution-time logic for
* CREATE FUNCTION, PROCEDURE, SYNONYM, and TYPE.
* <P>
* A function, procedure, or udt is represented as:
* <UL>
* <LI> AliasDescriptor
* </UL>
* Routine dependencies are created as:
* <UL>
* <LI> None
* </UL>
*
* <P>
* A synonym is represented as:
* <UL>
* <LI> AliasDescriptor
* <LI> TableDescriptor
* </UL>
* Synonym dependencies are created as:
* <UL>
* <LI> None
* </UL>
*
* In both cases a SchemaDescriptor will be created if
* needed. No dependency is created on the SchemaDescriptor.
*
* @see ConstantAction#executeConstantAction
* @see AliasDescriptor
* @see TableDescriptor
* @see SchemaDescriptor
*
* @exception StandardException Thrown on failure
*/
public void executeConstantAction(Activation activation) throws StandardException {
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
TransactionController tc = lcc.getTransactionExecute();
// For routines no validity checking is made
// on the Java method, that is checked when the
// routine is executed.
/*
** Inform the data dictionary that we are about to write to it.
** There are several calls to data dictionary "get" methods here
** that might be done in "read" mode in the data dictionary, but
** it seemed safer to do this whole operation in "write" mode.
**
** We tell the data dictionary we're done writing at the end of
** the transaction.
*/
dd.startWriting(lcc);
SchemaDescriptor sd = DDLConstantAction.getSchemaDescriptorForCreate(dd, activation, schemaName);
//
// Create a new alias descriptor with aliasID filled in.
//
UUID aliasID = dd.getUUIDFactory().createUUID();
AliasDescriptor ads = new AliasDescriptor(dd, aliasID, aliasName, sd.getUUID(), javaClassName, aliasType, nameSpace, false, aliasInfo, null);
// perform duplicate rule checking
switch(aliasType) {
case AliasInfo.ALIAS_TYPE_AGGREGATE_AS_CHAR:
AliasDescriptor duplicateAlias = dd.getAliasDescriptor(sd.getUUID().toString(), aliasName, nameSpace);
if (duplicateAlias != null) {
throw StandardException.newException(SQLState.LANG_OBJECT_ALREADY_EXISTS, ads.getDescriptorType(), aliasName);
}
// also don't want to collide with 1-arg functions by the same name
List<AliasDescriptor> funcList = dd.getRoutineList(sd.getUUID().toString(), aliasName, AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR);
for (int i = 0; i < funcList.size(); i++) {
AliasDescriptor func = funcList.get(i);
RoutineAliasInfo funcInfo = (RoutineAliasInfo) func.getAliasInfo();
if (funcInfo.getParameterCount() == 1) {
throw StandardException.newException(SQLState.LANG_BAD_UDA_OR_FUNCTION_NAME, schemaName, aliasName);
}
}
break;
case AliasInfo.ALIAS_TYPE_UDT_AS_CHAR:
AliasDescriptor duplicateUDT = dd.getAliasDescriptor(sd.getUUID().toString(), aliasName, nameSpace);
if (duplicateUDT != null) {
throw StandardException.newException(SQLState.LANG_OBJECT_ALREADY_EXISTS, ads.getDescriptorType(), aliasName);
}
break;
case AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR:
vetRoutine(dd, sd, ads);
break;
case AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR:
vetRoutine(dd, sd, ads);
// if this is a 1-arg function, make sure there isn't an aggregate
// by the same qualified name
int paramCount = ((RoutineAliasInfo) aliasInfo).getParameterCount();
if (paramCount == 1) {
AliasDescriptor aliasCollision = dd.getAliasDescriptor(sd.getUUID().toString(), aliasName, AliasInfo.ALIAS_NAME_SPACE_AGGREGATE_AS_CHAR);
if (aliasCollision != null) {
throw StandardException.newException(SQLState.LANG_BAD_UDA_OR_FUNCTION_NAME, schemaName, aliasName);
}
}
break;
case AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR:
// If target table/view exists already, error.
TableDescriptor targetTD = dd.getTableDescriptor(aliasName, sd, tc);
if (targetTD != null) {
throw StandardException.newException(SQLState.LANG_OBJECT_ALREADY_EXISTS, targetTD.getDescriptorType(), targetTD.getDescriptorName());
}
// Detect synonym cycles, if present.
String nextSynTable = ((SynonymAliasInfo) aliasInfo).getSynonymTable();
String nextSynSchema = ((SynonymAliasInfo) aliasInfo).getSynonymSchema();
SchemaDescriptor nextSD;
for (; ; ) {
nextSD = dd.getSchemaDescriptor(nextSynSchema, tc, false);
if (nextSD == null)
break;
AliasDescriptor nextAD = dd.getAliasDescriptor(nextSD.getUUID().toString(), nextSynTable, nameSpace);
if (nextAD == null)
break;
SynonymAliasInfo info = (SynonymAliasInfo) nextAD.getAliasInfo();
nextSynTable = info.getSynonymTable();
nextSynSchema = info.getSynonymSchema();
if (aliasName.equals(nextSynTable) && schemaName.equals(nextSynSchema))
throw StandardException.newException(SQLState.LANG_SYNONYM_CIRCULAR, aliasName, ((SynonymAliasInfo) aliasInfo).getSynonymTable());
}
// If synonym final target is not present, raise a warning
if (nextSD != null)
targetTD = dd.getTableDescriptor(nextSynTable, nextSD, tc);
if (nextSD == null || targetTD == null)
activation.addWarning(StandardException.newWarning(SQLState.LANG_SYNONYM_UNDEFINED, aliasName, nextSynSchema + "." + nextSynTable));
// To prevent any possible deadlocks with SYSTABLES, we insert a row into
// SYSTABLES also for synonyms. This also ensures tables/views/synonyms share
// same namespace
TableDescriptor td;
DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
td = ddg.newTableDescriptor(aliasName, sd, TableDescriptor.SYNONYM_TYPE, TableDescriptor.DEFAULT_LOCK_GRANULARITY);
dd.addDescriptor(td, sd, DataDictionary.SYSTABLES_CATALOG_NUM, false, tc);
break;
default:
break;
}
dd.addDescriptor(ads, null, DataDictionary.SYSALIASES_CATALOG_NUM, false, tc);
adjustUDTDependencies(lcc, dd, ads, true);
}
Aggregations