use of org.apache.derby.iapi.sql.dictionary.AliasDescriptor in project derby by apache.
the class DDLConstantAction method adjustUDTDependencies.
/**
* Adjust dependencies of a table on ANSI UDTs. We only add one dependency
* between a table and a UDT. If the table already depends on the UDT, we don't add
* a redundant dependency.
*/
protected void adjustUDTDependencies(LanguageConnectionContext lcc, DataDictionary dd, TableDescriptor td, ColumnInfo[] columnInfos, boolean dropWholeTable) throws StandardException {
if ((!dropWholeTable) && (columnInfos == null)) {
return;
}
TransactionController tc = lcc.getTransactionExecute();
int changedColumnCount = columnInfos == null ? 0 : columnInfos.length;
HashMap<String, AliasDescriptor> addUdtMap = new HashMap<String, AliasDescriptor>();
HashMap<String, AliasDescriptor> dropUdtMap = new HashMap<String, AliasDescriptor>();
HashSet<String> addColumnNames = new HashSet<String>();
HashSet<String> dropColumnNames = new HashSet<String>();
// and the old ones which are candidates for removal
for (int i = 0; i < changedColumnCount; i++) {
ColumnInfo ci = columnInfos[i];
// skip this column if it is not a UDT
AliasDescriptor ad = dd.getAliasDescriptorForUDT(tc, columnInfos[i].dataType);
if (ad == null) {
continue;
}
String key = ad.getObjectID().toString();
if (ci.action == ColumnInfo.CREATE) {
addColumnNames.add(ci.name);
// no need to add the descriptor if it is already on the list
if (addUdtMap.get(key) != null) {
continue;
}
addUdtMap.put(key, ad);
} else if (ci.action == ColumnInfo.DROP) {
dropColumnNames.add(ci.name);
dropUdtMap.put(key, ad);
}
}
// and this is not a DROP TABLE command
if (!dropWholeTable && addUdtMap.isEmpty() && dropUdtMap.isEmpty()) {
return;
}
//
// Now prune from the add list all udt descriptors for which we already have dependencies.
// These are the udts for old columns. This supports the ALTER TABLE ADD COLUMN
// case.
//
// Also prune from the drop list add udt descriptors which will still be
// referenced by the remaining columns.
//
ColumnDescriptorList cdl = td.getColumnDescriptorList();
int totalColumnCount = cdl.size();
for (int i = 0; i < totalColumnCount; i++) {
ColumnDescriptor cd = cdl.elementAt(i);
// skip columns that are being added and dropped. we only want the untouched columns
if (addColumnNames.contains(cd.getColumnName()) || dropColumnNames.contains(cd.getColumnName())) {
continue;
}
// nothing to do if the old column isn't a UDT
AliasDescriptor ad = dd.getAliasDescriptorForUDT(tc, cd.getType());
if (ad == null) {
continue;
}
String key = ad.getObjectID().toString();
// ha, it is a UDT.
if (dropWholeTable) {
dropUdtMap.put(key, ad);
} else {
if (addUdtMap.get(key) != null) {
addUdtMap.remove(key);
}
if (dropUdtMap.get(key) != null) {
dropUdtMap.remove(key);
}
}
}
adjustUDTDependencies(lcc, dd, td, addUdtMap, dropUdtMap);
}
use of org.apache.derby.iapi.sql.dictionary.AliasDescriptor in project derby by apache.
the class CreateAliasConstantAction method vetRoutine.
/**
* Common checks to be performed for functions and procedures
*/
private void vetRoutine(DataDictionary dd, SchemaDescriptor sd, AliasDescriptor ads) throws StandardException {
List<AliasDescriptor> list = dd.getRoutineList(sd.getUUID().toString(), aliasName, aliasType);
for (int i = list.size() - 1; i >= 0; i--) {
AliasDescriptor proc = list.get(i);
RoutineAliasInfo procedureInfo = (RoutineAliasInfo) proc.getAliasInfo();
int parameterCount = procedureInfo.getParameterCount();
if (parameterCount != ((RoutineAliasInfo) aliasInfo).getParameterCount()) {
continue;
}
// one procedure with a given number of parameters.
throw StandardException.newException(SQLState.LANG_OBJECT_ALREADY_EXISTS, ads.getDescriptorType(), aliasName);
}
}
use of org.apache.derby.iapi.sql.dictionary.AliasDescriptor 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);
}
use of org.apache.derby.iapi.sql.dictionary.AliasDescriptor in project derby by apache.
the class DropAliasConstantAction method executeConstantAction.
// INTERFACE METHODS
/**
* This is the guts of the Execution-time logic for DROP ALIAS.
*
* @see ConstantAction#executeConstantAction
*
* @exception StandardException Thrown on failure
*/
public void executeConstantAction(Activation activation) throws StandardException {
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
/*
** 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);
/* Get the alias descriptor. We're responsible for raising
* the error if it isn't found
*/
AliasDescriptor ad = dd.getAliasDescriptor(sd.getUUID().toString(), aliasName, nameSpace);
// RESOLVE - fix error message
if (ad == null) {
throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, AliasDescriptor.getAliasType(nameSpace), aliasName);
}
adjustUDTDependencies(lcc, dd, ad, false);
ad.drop(lcc);
}
use of org.apache.derby.iapi.sql.dictionary.AliasDescriptor in project derby by apache.
the class QueryTreeNode method getUDTDesc.
/**
* Get the AliasDescriptor of a UDT
*/
public AliasDescriptor getUDTDesc(DataTypeDescriptor dtd) throws StandardException {
UserDefinedTypeIdImpl userTypeID = (UserDefinedTypeIdImpl) dtd.getTypeId().getBaseTypeId();
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);
return ad;
}
Aggregations