📄 hashjoinstrategy.java
字号:
/* 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; } /** * @see JoinStrategy#divideUpPredicateLists * * @exception StandardException Thrown on error */ public void divideUpPredicateLists( Optimizable innerTable, OptimizablePredicateList originalRestrictionList, OptimizablePredicateList storeRestrictionList, OptimizablePredicateList nonStoreRestrictionList, OptimizablePredicateList requalificationRestrictionList, DataDictionary dd ) throws StandardException { /* ** If we are walking a non-covering index, then all predicates that ** get evaluated in the HashScanResultSet, whether during the building ** or probing of the hash table, need to be evaluated at both the ** IndexRowToBaseRowResultSet and the HashScanResultSet to ensure ** that the rows materialized into the hash table still qualify when ** we go to read the row from the heap. This also includes predicates ** that are not qualifier/start/stop keys (hence not in store/non-store ** 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 { /* ** If the conglomerate is a heap, the column numbers of the hash ** key are the column numbers returned by findHashKeyColumns(). ** ** NOTE: Must switch from zero-based to one-based */ for (int index = 0; index < hashKeyColumns.length; index++) { conglomColumn[index] = hashKeyColumns[index] + 1; } } /* Put the equality predicates on the key columns for the hash first. * (Column # is columns[colCtr] from above.) */ for (int index = hashKeyColumns.length - 1; index >= 0; index--) { nonStoreRestrictionList.putOptimizableEqualityPredicateFirst( innerTable, conglomColumn[index]); } } /** * @see JoinStrategy#isHashJoin */ public boolean isHashJoin() { return true; } /** * @see JoinStrategy#doesMaterialization */ public boolean doesMaterialization() { return true; } /** * Find the hash key columns, if any, to use with this join. * * @param innerTable The inner table of the join * @param cd The conglomerate descriptor to use on inner table * @param predList The predicate list to look for the equijoin in * * @return the numbers of the hash key columns, or null if no hash key column * * @exception StandardException Thrown on error */ private int[] findHashKeyColumns(Optimizable innerTable, ConglomerateDescriptor cd, OptimizablePredicateList predList) throws StandardException { if (predList == null) return (int[]) null; /* Find the column to use as the hash key. * (There must be an equijoin condition on this column.) * If cd is null, then Optimizable is not a scan. * For indexes, we start at the first column in the key * and walk the key columns until we find the first one with * an equijoin condition on it. We do essentially the same * for heaps. (From column 1 through column n.) */ int[] columns = null; if (cd == null) { columns = new int[innerTable.getNumColumnsReturned()]; for (int j = 0; j < columns.length; j++) { columns[j] = j + 1; } } else if (cd.isIndex()) { columns = cd.getIndexDescriptor().baseColumnPositions(); } else { columns = new int[innerTable.getTableDescriptor().getNumberOfColumns()]; for (int j = 0; j < columns.length; j++) { columns[j] = j + 1; } } // Build a Vector of all the hash key columns int colCtr; Vector hashKeyVector = new Vector(); for (colCtr = 0; colCtr < columns.length; colCtr++) { // Is there an equijoin condition on this column? if (predList.hasOptimizableEquijoin(innerTable, columns[colCtr])) { hashKeyVector.addElement(new Integer(colCtr)); } } // Convert the Vector into an int[], if there are hash key columns if (hashKeyVector.size() > 0) { int[] keyCols = new int[hashKeyVector.size()]; for (int index = 0; index < keyCols.length; index++) { keyCols[index] = ((Integer) hashKeyVector.elementAt(index)).intValue(); } return keyCols; } else return (int[]) null; } public String toString() { return getName(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -