use of org.apache.derby.iapi.services.io.FormatableArrayHolder in project derby by apache.
the class HashJoinStrategy method getScanArgs.
/**
* @see JoinStrategy#getScanArgs
*
* @exception StandardException Thrown on error
*/
public int getScanArgs(TransactionController tc, MethodBuilder mb, Optimizable innerTable, OptimizablePredicateList storeRestrictionList, OptimizablePredicateList nonStoreRestrictionList, ExpressionClassBuilderInterface acbi, int bulkFetch, int resultRowTemplate, int colRefItem, int indexColItem, int lockMode, boolean tableLocked, int isolationLevel, int maxMemoryPerTable, boolean genInListVals) throws StandardException {
/* We do not currently support IN-list "multi-probing" for hash scans
* (though we could do so in the future). So if we're doing a hash
* join then we shouldn't have any IN-list probe predicates in the
* store restriction list at this point. The reason is that, in the
* absence of proper multi-probing logic, such predicates would act
* as restrictions on the rows read from disk. That would be wrong
* because a probe predicate is of the form "col = <val>" where <val>
* is the first value in the IN-list. Enforcement of that restriction
* would lead to incorrect results--we need to return all rows having
* any value that appears in the IN-list, not just those rows matching
* the first value. Checks elsewhere in the code should ensure that
* no probe predicates have made it this far, but if we're running in
* SANE mode it doesn't hurt to verify.
*/
if (SanityManager.DEBUG) {
for (int i = storeRestrictionList.size() - 1; i >= 0; i--) {
Predicate pred = (Predicate) storeRestrictionList.getOptPredicate(i);
if (pred.isInListProbePredicate()) {
SanityManager.THROWASSERT("Found IN-list probing " + "(" + pred.binaryRelOpColRefsToString() + ") while generating HASH join, which should " + "not happen.");
}
}
}
ExpressionClassBuilder acb = (ExpressionClassBuilder) acbi;
fillInScanArgs1(tc, mb, innerTable, storeRestrictionList, acb, resultRowTemplate);
nonStoreRestrictionList.generateQualifiers(acb, mb, innerTable, true);
mb.push(innerTable.initialCapacity());
mb.push(innerTable.loadFactor());
mb.push(innerTable.maxCapacity((JoinStrategy) this, maxMemoryPerTable));
/* Get the hash key columns and wrap them in a formattable */
int[] hashKeyColumns = innerTable.hashKeyColumns();
FormatableIntHolder[] fihArray = FormatableIntHolder.getFormatableIntHolders(hashKeyColumns);
FormatableArrayHolder hashKeyHolder = new FormatableArrayHolder(fihArray);
int hashKeyItem = acb.addItem(hashKeyHolder);
mb.push(hashKeyItem);
fillInScanArgs2(mb, innerTable, bulkFetch, colRefItem, indexColItem, lockMode, tableLocked, isolationLevel);
return 28;
}
use of org.apache.derby.iapi.services.io.FormatableArrayHolder in project derby by apache.
the class HashTableNode method generateMinion.
/**
* Logic shared by generate() and generateResultSet().
*
* @param acb The ExpressionClassBuilder for the class being built
* @param mb the method the expression will go into
*
* @exception StandardException Thrown on error
*/
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());
/* 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
ResultColumnList.ColumnMapping mappingArrays = getResultColumns().mapSourceColumns();
int[] mapArray = mappingArrays.mapArray;
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(getResultSetNumber());
if (SanityManager.DEBUG) {
SanityManager.ASSERT(pSubqueryList.size() == 0, "pSubqueryList.size() expected to be 0");
}
}
if (rSubqueryList != null && rSubqueryList.size() > 0) {
rSubqueryList.setPointOfAttachment(getResultSetNumber());
if (SanityManager.DEBUG) {
SanityManager.ASSERT(rSubqueryList.size() == 0, "rSubqueryList.size() expected to be 0");
}
}
// Get the final cost estimate based on child's cost.
setCostEstimate(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
// which is the static field that "points" to the userExprFun
// that evaluates the where clause.
acb.pushMethodReference(mb, userExprFun);
}
/* Generate the qualifiers for the look up into
* the hash table.
*/
joinPredicateList.generateQualifiers(acb, mb, (Optimizable) childResult, false);
/* Determine whether or not reflection is needed for the projection.
* Reflection is not needed if all of the columns map directly to source
* columns.
*/
if (reflectionNeededForProjection()) {
// for the resultColumns, we generate a userExprFun
// that creates a new row from expressions against
// the current row of the child's result.
// (Generate optimization: see if we can simply
// return the current row -- we could, but don't, optimize
// the function call out and have execution understand
// that a null function pointer means take the current row
// as-is, with the performance trade-off as discussed above.)
/* Generate the Row function for the projection */
getResultColumns().generateCore(acb, mb, false);
} else {
mb.pushNull(ClassName.GeneratedMethod);
}
mb.push(getResultSetNumber());
mb.push(mapArrayItem);
mb.push(getResultColumns().reusableResult());
mb.push(hashKeyItem);
mb.push(false);
mb.push(-1L);
mb.push(initialCapacity);
mb.push(loadFactor);
mb.push(getCostEstimate().singleScanRowCount());
mb.push(getCostEstimate().getEstimatedCost());
mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "getHashTableResultSet", ClassName.NoPutResultSet, 14);
}
use of org.apache.derby.iapi.services.io.FormatableArrayHolder in project derby by apache.
the class FromBaseTable method generateDistinctScan.
private void generateDistinctScan(ExpressionClassBuilder acb, MethodBuilder mb) throws StandardException {
ConglomerateDescriptor cd = getTrulyTheBestAccessPath().getConglomerateDescriptor();
CostEstimate costEst = getFinalCostEstimate();
int colRefItem = (referencedCols == null) ? -1 : acb.addItem(referencedCols);
boolean tableLockGranularity = tableDescriptor.getLockGranularity() == TableDescriptor.TABLE_LOCK_GRANULARITY;
/*
** getDistinctScanResultSet
** (
** activation,
** resultSetNumber,
** resultRowAllocator,
** conglomereNumber,
** tableName,
** optimizeroverride
** indexName,
** colRefItem,
** lockMode,
** tableLocked,
** isolationLevel,
** optimizerEstimatedRowCount,
** optimizerEstimatedRowCost,
** closeCleanupMethod
** );
*/
/* Get the hash key columns and wrap them in a formattable */
int[] hashKeyCols;
hashKeyCols = new int[getResultColumns().size()];
if (referencedCols == null) {
for (int index = 0; index < hashKeyCols.length; index++) {
hashKeyCols[index] = index;
}
} else {
int index = 0;
for (int colNum = referencedCols.anySetBit(); colNum != -1; colNum = referencedCols.anySetBit(colNum)) {
hashKeyCols[index++] = colNum;
}
}
FormatableIntHolder[] fihArray = FormatableIntHolder.getFormatableIntHolders(hashKeyCols);
FormatableArrayHolder hashKeyHolder = new FormatableArrayHolder(fihArray);
int hashKeyItem = acb.addItem(hashKeyHolder);
long conglomNumber = cd.getConglomerateNumber();
StaticCompiledOpenConglomInfo scoci = getLanguageConnectionContext().getTransactionCompile().getStaticCompiledConglomInfo(conglomNumber);
acb.pushGetResultSetFactoryExpression(mb);
acb.pushThisAsActivation(mb);
mb.push(conglomNumber);
mb.push(acb.addItem(scoci));
mb.push(acb.addItem(getResultColumns().buildRowTemplate(referencedCols, false)));
mb.push(getResultSetNumber());
mb.push(hashKeyItem);
mb.push(tableDescriptor.getName());
// run time statistics.
if (tableProperties != null)
mb.push(org.apache.derby.iapi.util.PropertyUtil.sortProperties(tableProperties));
else
mb.pushNull("java.lang.String");
pushIndexName(cd, mb);
mb.push(cd.isConstraint());
mb.push(colRefItem);
mb.push(getTrulyTheBestAccessPath().getLockMode());
mb.push(tableLockGranularity);
mb.push(getCompilerContext().getScanIsolationLevel());
mb.push(costEst.singleScanRowCount());
mb.push(costEst.getEstimatedCost());
mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "getDistinctScanResultSet", ClassName.NoPutResultSet, 16);
}
use of org.apache.derby.iapi.services.io.FormatableArrayHolder in project derby by apache.
the class GroupByNode method generate.
/**
* generate the sort result set operating over the source
* result set. Adds distinct aggregates to the sort if
* necessary.
*
* @exception StandardException Thrown on error
*/
@Override
void generate(ActivationClassBuilder acb, MethodBuilder mb) throws StandardException {
FormatableArrayHolder orderingHolder;
/* Get the next ResultSet#, so we can number this ResultSetNode, its
* ResultColumnList and ResultSet.
*/
assignResultSetNumber();
// Get the final cost estimate from the child.
setCostEstimate(childResult.getFinalCostEstimate());
/*
** Get the column ordering for the sort. Note that
** for a scalar aggegate we may not have any ordering
** columns (if there are no distinct aggregates).
** WARNING: if a distinct aggregate is passed to
** SortResultSet it assumes that the last column
** is the distinct one. If this assumption changes
** then SortResultSet will have to change.
*/
orderingHolder = acb.getColumnOrdering(groupingList);
if (addDistinctAggregate) {
orderingHolder = acb.addColumnToOrdering(orderingHolder, addDistinctAggregateColumnNum);
}
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON("AggregateTrace")) {
StringBuilder s = new StringBuilder();
s.append("Group by column ordering is (");
ColumnOrdering[] ordering = orderingHolder.getArray(ColumnOrdering[].class);
for (int i = 0; i < ordering.length; i++) {
s.append(ordering[i].getColumnId());
s.append(" ");
}
s.append(")");
SanityManager.DEBUG("AggregateTrace", s.toString());
}
}
int orderingItem = acb.addItem(orderingHolder);
/*
** We have aggregates, so save the aggInfo
** struct in the activation and store the number
*/
if (SanityManager.DEBUG) {
SanityManager.ASSERT(aggInfo != null, "aggInfo not set up as expected");
}
int aggInfoItem = acb.addItem(aggInfo);
acb.pushGetResultSetFactoryExpression(mb);
// Generate the child ResultSet
childResult.generate(acb, mb);
mb.push(isInSortedOrder);
mb.push(aggInfoItem);
mb.push(orderingItem);
mb.push(acb.addItem(getResultColumns().buildRowTemplate()));
mb.push(getResultColumns().getTotalColumnSize());
mb.push(getResultSetNumber());
/* Generate a (Distinct)ScalarAggregateResultSet if scalar aggregates */
if ((groupingList == null) || (groupingList.size() == 0)) {
genScalarAggregateResultSet(acb, mb);
} else /* Generate a (Distinct)GroupedAggregateResultSet if grouped aggregates */
{
genGroupedAggregateResultSet(acb, mb);
}
}
use of org.apache.derby.iapi.services.io.FormatableArrayHolder in project derby by apache.
the class ColumnInfo method writeExternal.
/**
* Write this object to a stream of stored objects.
*
* @param out write bytes here.
*
* @exception IOException thrown on error
*/
public void writeExternal(ObjectOutput out) throws IOException {
FormatableHashtable fh = new FormatableHashtable();
fh.put("name", name);
fh.put("dataType", dataType);
fh.put("defaultValue", defaultValue);
fh.put("defaultInfo", defaultInfo);
fh.put("newDefaultUUID", newDefaultUUID);
fh.put("oldDefaultUUID", oldDefaultUUID);
fh.putInt("action", action);
if (autoincInc != 0) {
// only write out autoinc values if its an autoinc column.
fh.putLong("autoincStart", autoincStart);
fh.putLong("autoincInc", autoincInc);
}
if (providers != null) {
FormatableArrayHolder fah = new FormatableArrayHolder(providers);
fh.put("providers", fah);
}
out.writeObject(fh);
}
Aggregations