*/
void genExistsBaseTables(JBitSet referencedTableMap, FromList outerFromList,
boolean isNotExists)
throws StandardException
{
JBitSet dependencyMap = (JBitSet) referencedTableMap.clone();
// We currently only flatten single table from lists
if (SanityManager.DEBUG)
{
if (size() != 1)
{
SanityManager.THROWASSERT(
"size() expected to be 1, not " + size());
}
}
/* Create the dependency map */
int size = size();
for (int index = 0; index < size; index++)
{
ResultSetNode ft = ((ProjectRestrictNode) elementAt(index)).getChildResult();
if (ft instanceof FromTable)
{
dependencyMap.clear(((FromTable) ft).getTableNumber());
}
}
/* Degenerate case - If flattening a non-correlated EXISTS subquery
* then we need to make the table that is getting flattened dependendent on
* all of the tables in the outer query block. Gross but true. Otherwise
* that table can get chosen as an outer table and introduce duplicates.
* The reason that duplicates can be introduced is that we do special processing
* in the join to make sure only one qualified row from the right side is
* returned. If the exists table is on the left, we can return all the
* qualified rows.
*/
if (dependencyMap.getFirstSetBit() == -1)
{
int outerSize = outerFromList.size();
for (int outer = 0; outer < outerSize; outer++)
dependencyMap.or(((FromTable) outerFromList.elementAt(outer)).getReferencedTableMap());
}
/* Do the marking */
for (int index = 0; index < size; index++)
{
FromTable fromTable = (FromTable) elementAt(index);
if (fromTable instanceof ProjectRestrictNode)
{
ProjectRestrictNode prn = (ProjectRestrictNode) fromTable;
if (prn.getChildResult() instanceof FromBaseTable)
{
FromBaseTable fbt = (FromBaseTable) prn.getChildResult();
fbt.setExistsBaseTable(true, (JBitSet) dependencyMap.clone(), isNotExists);
}
}
}
}