private void generateMinion(ExpressionClassBuilder acb,
MethodBuilder mb, boolean genChildResultSet)
throws StandardException
{
MethodBuilder userExprFun;
ValueNode searchClause = null;
ValueNode equijoinClause = null;
/* The tableProperties, if non-null, must be correct to get this far.
* We simply call verifyProperties to set initialCapacity and
* loadFactor.
*/
verifyProperties(getDataDictionary());
// build up the tree.
/* Put the predicates back into the tree */
if (searchPredicateList != null)
{
// Remove any redundant predicates before restoring
searchPredicateList.removeRedundantPredicates();
searchClause = searchPredicateList.restorePredicates();
/* Allow the searchPredicateList to get garbage collected now
* that we're done with it.
*/
searchPredicateList = null;
}
// for the single table predicates, we generate an exprFun
// that evaluates the expression of the clause
// against the current row of the child's result.
// if the restriction is empty, simply pass null
// to optimize for run time performance.
// generate the function and initializer:
// Note: Boolean lets us return nulls (boolean would not)
// private Boolean exprN()
// {
// return <<searchClause.generate(ps)>>;
// }
// static Method exprN = method pointer to exprN;
// Map the result columns to the source columns
int[] mapArray = resultColumns.mapSourceColumns();
int mapArrayItem = acb.addItem(new ReferencedColumnsDescriptorImpl(mapArray));
// Save the hash key columns
FormatableIntHolder[] fihArray =
FormatableIntHolder.getFormatableIntHolders(hashKeyColumns());
FormatableArrayHolder hashKeyHolder = new FormatableArrayHolder(fihArray);
int hashKeyItem = acb.addItem(hashKeyHolder);
/* Generate the HashTableResultSet:
* arg1: childExpress - Expression for childResultSet
* arg2: searchExpress - Expression for single table predicates
* arg3 : equijoinExpress - Qualifier[] for hash table look up
* arg4: projectExpress - Expression for projection, if any
* arg5: resultSetNumber
* arg6: mapArrayItem - item # for mapping of source columns
* arg7: reuseResult - whether or not the result row can be reused
* (ie, will it always be the same)
* arg8: hashKeyItem - item # for int[] of hash column #s
* arg9: removeDuplicates - don't remove duplicates in hash table (for now)
* arg10: maxInMemoryRowCount - max row size for in-memory hash table
* arg11: initialCapacity - initialCapacity for java.util.Hashtable
* arg12 : loadFactor - loadFactor for java.util.Hashtable
* arg13: estimated row count
* arg14: estimated cost
* arg15: close method
*/
acb.pushGetResultSetFactoryExpression(mb);
if (genChildResultSet)
childResult.generateResultSet(acb, mb);
else
childResult.generate((ActivationClassBuilder) acb, mb);
/* Get the next ResultSet #, so that we can number this ResultSetNode, its
* ResultColumnList and ResultSet.
*/
assignResultSetNumber();
/* Set the point of attachment in all subqueries attached
* to this node.
*/
if (pSubqueryList != null && pSubqueryList.size() > 0)
{
pSubqueryList.setPointOfAttachment(resultSetNumber);
if (SanityManager.DEBUG)
{
SanityManager.ASSERT(pSubqueryList.size() == 0,
"pSubqueryList.size() expected to be 0");
}
}
if (rSubqueryList != null && rSubqueryList.size() > 0)
{
rSubqueryList.setPointOfAttachment(resultSetNumber);
if (SanityManager.DEBUG)
{
SanityManager.ASSERT(rSubqueryList.size() == 0,
"rSubqueryList.size() expected to be 0");
}
}
// Get the final cost estimate based on child's cost.
costEstimate = childResult.getFinalCostEstimate();
// if there is no searchClause, we just want to pass null.
if (searchClause == null)
{
mb.pushNull(ClassName.GeneratedMethod);
}
else
{
// this sets up the method and the static field.
// generates:
// DataValueDescriptor userExprFun { }
userExprFun = acb.newUserExprFun();
// searchClause knows it is returning its value;
/* generates:
* return <searchClause.generate(acb)>;
* and adds it to userExprFun
* NOTE: The explicit cast to DataValueDescriptor is required
* since the searchClause may simply be a boolean column or subquery
* which returns a boolean. For example:
* where booleanColumn
*/
searchClause.generateExpression(acb, userExprFun);
userExprFun.methodReturn();
/* PUSHCOMPILER
userSB.newReturnStatement(searchClause.generateExpression(acb, userSB));
*/
// we are done modifying userExprFun, complete it.
userExprFun.complete();
// searchClause is used in the final result set as an access of the new static
// field holding a reference to this new method.
// generates:
// ActivationClass.userExprFun