ConglomerateDescriptor[] cds;
LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
DataDictionary dd = lcc.getDataDictionary();
DependencyManager dm = dd.getDependencyManager();
TransactionController tc = lcc.getTransactionExecute();
if ((sd != null) && sd.getSchemaName().equals(SchemaDescriptor.STD_DECLARED_GLOBAL_TEMPORARY_TABLES_SCHEMA_NAME)) {
td = lcc.getTableDescriptorForDeclaredGlobalTempTable(tableName); //check if this is a temp table before checking data dictionary
if (td == null) //td null here means it is not a temporary table. Look for table in physical SESSION schema
td = dd.getTableDescriptor(tableName, sd);
if (td == null) //td null means tableName is not a temp table and it is not a physical table in SESSION schema
{
throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, fullTableName);
}
if (td.getTableType() == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE) {
dm.invalidateFor(td, DependencyManager.DROP_TABLE, lcc);
tc.dropConglomerate(td.getHeapConglomerateId());
lcc.dropDeclaredGlobalTempTable(tableName);
return;
}
}
/* Lock the table before we access the data dictionary
* to prevent deadlocks.
*
* Note that for DROP TABLE replayed at Targets during REFRESH,
* the conglomerateNumber will be 0. That's ok. During REFRESH,
* we don't need to lock the conglomerate.
*/
if ( conglomerateNumber != 0 ) { lockTableForDDL(tc, conglomerateNumber, true); }
/*
** 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 table descriptor. */
td = dd.getTableDescriptor(tableId);
if (td == null)
{
throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, fullTableName);
}
/* Get an exclusive table lock on the table. */
long heapId = td.getHeapConglomerateId();
lockTableForDDL(tc, heapId, true);
/* Drop the triggers */
GenericDescriptorList tdl = dd.getTriggerDescriptors(td);
Enumeration descs = tdl.elements();
while (descs.hasMoreElements())
{
TriggerDescriptor trd = (TriggerDescriptor) descs.nextElement();
trd.drop(lcc);
}
/* Drop all defaults */
ColumnDescriptorList cdl = td.getColumnDescriptorList();
int cdlSize = cdl.size();
for (int index = 0; index < cdlSize; index++)
{
ColumnDescriptor cd = (ColumnDescriptor) cdl.elementAt(index);
// If column has a default we drop the default and
// any dependencies
if (cd.getDefaultInfo() != null)
{
DefaultDescriptor defaultDesc = cd.getDefaultDescriptor(dd);
dm.clearDependencies(lcc, defaultDesc);
}
}
/* Drop the columns */
dd.dropAllColumnDescriptors(tableId, tc);
/* Drop all table and column permission descriptors */
dd.dropAllTableAndColPermDescriptors(tableId, tc);
/* Drop the constraints */
dropAllConstraintDescriptors(td, activation);
/*
** Drop all the conglomerates. Drop the heap last, because the
** store needs it for locking the indexes when they are dropped.
*/
cds = td.getConglomerateDescriptors();
long[] dropped = new long[cds.length - 1];
int numDropped = 0;
for (int index = 0; index < cds.length; index++)
{
ConglomerateDescriptor cd = cds[index];
/* if it's for an index, since similar indexes share one
* conglomerate, we only drop the conglomerate once
*/
if (cd.getConglomerateNumber() != heapId)
{
long thisConglom = cd.getConglomerateNumber();
int i;
for (i = 0; i < numDropped; i++)
{
if (dropped[i] == thisConglom)
break;
}
if (i == numDropped) // not dropped
{
dropped[numDropped++] = thisConglom;
tc.dropConglomerate(thisConglom);
dd.dropStatisticsDescriptors(td.getUUID(), cd.getUUID(), tc);
}
}
}
/* Prepare all dependents to invalidate. (This is there chance
* to say that they can't be invalidated. For example, an open
* cursor referencing a table/view that the user is attempting to
* drop.) If no one objects, then invalidate any dependent objects.
* We check for invalidation before we drop the table descriptor
* since the table descriptor may be looked up as part of
* decoding tuples in SYSDEPENDS.
*/
dm.invalidateFor(td, DependencyManager.DROP_TABLE, lcc);
/* Drop the table */
dd.dropTableDescriptor(td, sd, tc);
/* Drop the conglomerate descriptors */
dd.dropAllConglomerateDescriptors(td, tc);
/* Drop the store element at last, to prevent dangling reference
* for open cursor, beetle 4393.
*/
tc.dropConglomerate(heapId);
}