// Check to see if the child nodes reference any base tables; if either
// child does not reference at least one base table, then we don't try
// to push the predicate.
boolean canPush = false;
JBitSet tableNums = new JBitSet(getReferencedTableMap().size());
BaseTableNumbersVisitor btnVis =
new BaseTableNumbersVisitor(tableNums);
// Check the left child.
leftResultSet.accept(btnVis);
canPush = (tableNums.getFirstSetBit() != -1);
/* If we can't push it to _both_ children, then we don't push at all.
* RESOLVE: We can add the ability to push a predicate to one side
* only by putting a ProjectRestrictNode between the union node and
* the child as a place to park the predicate. To make things simple,
* we might want to always put ProjectRestrictNodes under both sides
* of the union during preprocessing (i.e. after binding but before
* optimization). In some cases the extra nodes won't be needed, but
* PRNs (and the corresponding ProjectRestrictResultSets) are cheap.
* Also, we could eliminate unnecessary ProjectRestrictNodes at the
* end of optimization (possibly in modifyAccessPaths()). Until all
* of that is implemented, though, we only push if we can push to
* both sides...
*/
if (!canPush)
return false;
// Check the right child.
tableNums.clearAll();
rightResultSet.accept(btnVis);
canPush = (tableNums.getFirstSetBit() != -1);
if (!canPush)
return false;
// Get a list of all of the underlying base tables that this node
// references. We pass this down when scoping so that we can tell
// if the operands are actually supposed to be scoped to _this_
// node's children. Note that in order for the predicate to
// have been pushed this far, at least one of its operands must
// apply to this node--we don't know which one it is, though,
// so we use this tableNums info to figure that out.
tableNums.clearAll();
this.accept(btnVis);
/* What we want to do here is push the predicate to the left/right
* child. That means that we need to find the equivalent column(s)
* in each child.