** list).
*/
originalRestrictionList.copyPredicatesToOtherList(
requalificationRestrictionList);
ConglomerateDescriptor cd =
innerTable.getTrulyTheBestAccessPath().getConglomerateDescriptor();
/* For the inner table of a hash join, then divide up the predicates:
*
* o restrictionList - predicates that get applied when creating
* the hash table (single table clauses)
*
* o nonBaseTableRestrictionList
* - those that get applied when probing into the
* hash table (equijoin clauses on key columns,
* ordered by key column position first, followed
* by any other join predicates. (All predicates
* in this list are qualifiers which can be
* evaluated in the store).
*
* o baseTableRL - Only applicable if this is not a covering
* index. In that case, we will need to
* requalify the data page. Thus, this list
* will include all predicates.
*/
// Build the list to be applied when creating the hash table
originalRestrictionList.transferPredicates(
storeRestrictionList,
innerTable.getReferencedTableMap(),
innerTable);
/*
* Eliminate any non-qualifiers that may have been pushed, but
* are redundant and not useful for hash join.
*
* For instance "in" (or other non-qualifier) was pushed down for
* start/stop key, * but for hash join, it may no longer be because
* previous key column may have been disqualified (eg., correlation).
* We simply remove
* such non-qualifier ("in") because we left it as residual predicate
* anyway. It's easier/safer to filter it out here than detect it
* ealier (and not push it down). Beetle 4316.
*
* Can't filter out OR list, as it is not a residual predicate,
*/
for (int i = storeRestrictionList.size() - 1; i >= 0; i--)
{
Predicate p1 = (Predicate) storeRestrictionList.getOptPredicate(i);
if (!p1.isStoreQualifier() && !p1.isStartKey() && !p1.isStopKey())
{
storeRestrictionList.removeOptPredicate(i);
}
}
for (int i = originalRestrictionList.size() - 1; i >= 0; i--)
{
Predicate p1 =
(Predicate) originalRestrictionList.getOptPredicate(i);
if (!p1.isStoreQualifier())
originalRestrictionList.removeOptPredicate(i);
}
/* Copy the rest of the predicates to the non-store list */
originalRestrictionList.copyPredicatesToOtherList(
nonStoreRestrictionList);
/* If innerTable is ProjectRestrictNode, we need to use its child
* to find hash key columns, this is because ProjectRestrictNode may
* not have underlying node's every result column as result column,
* and the predicate's column reference was bound to the underlying
* node's column position. Also we have to pass in the
* ProjectRestrictNode rather than the underlying node to this method
* because a predicate's referencedTableMap references the table number
* of the ProjectRestrictiveNode. And we need this info to see if
* a predicate is in storeRestrictionList that can be pushed down.
* Beetle 3458.
*/
Optimizable hashTableFor = innerTable;
if (innerTable instanceof ProjectRestrictNode)
{
ProjectRestrictNode prn = (ProjectRestrictNode) innerTable;
if (prn.getChildResult() instanceof Optimizable)
hashTableFor = (Optimizable) (prn.getChildResult());
}
int[] hashKeyColumns = findHashKeyColumns(hashTableFor,
cd,
nonStoreRestrictionList);
if (hashKeyColumns != null)
{
innerTable.setHashKeyColumns(hashKeyColumns);
}
else
{
String name;
if (cd != null && cd.isIndex())
{
name = cd.getConglomerateName();
}
else
{
name = innerTable.getBaseTableName();
}
throw StandardException.newException(SQLState.LANG_HASH_NO_EQUIJOIN_FOUND,
name,
innerTable.getBaseTableName());
}
// Mark all of the predicates in the probe list as qualifiers
nonStoreRestrictionList.markAllPredicatesQualifiers();
int[] conglomColumn = new int[hashKeyColumns.length];
if (cd != null && cd.isIndex())
{
/*
** If the conglomerate is an index, get the column numbers of the
** hash keys in the base heap.
*/
for (int index = 0; index < hashKeyColumns.length; index++)
{
conglomColumn[index] =
cd.getIndexDescriptor().baseColumnPositions()[hashKeyColumns[index]];
}
}
else
{
/*