private Plan makeIndexJoinPlan(Plan trunk, Schema trunkSch) {
		int matchedCount = 0;
		IndexInfo bestIndex = null;
		Map<String, String> bestJoinPairs = null; // <Outer Field -> Self Field>
		
		// Find the indexes that have fields joined with the target table
		Set<IndexInfo> candidates = new HashSet<IndexInfo>();
		for (String fieldName : sch.fields()) {
			Set<String> outerFlds = pred.joinFields(fieldName);
			if (outerFlds == null)
				continue;
			
			for (String outerFld : outerFlds)
				if (trunkSch.hasField(outerFld)) {
					List<IndexInfo> iis = VanillaDb.catalogMgr().getIndexInfo(tblName, fieldName, tx);
					candidates.addAll(iis);
					break;
				}
		}
		
		// Find the indexes with the most joined fields
		for (IndexInfo ii : candidates) {
			if (ii.fieldNames().size() < matchedCount)
				continue;
			
			Map<String, String> joinPairs = new HashMap<String, String>();
			for (String fieldName : ii.fieldNames()) {
				Set<String> outerFlds = pred.joinFields(fieldName);
				for (String outerFld : outerFlds)
					if (trunkSch.hasField(outerFld)) {
						joinPairs.put(outerFld, fieldName);
						break;
					}
			}
			
			if (joinPairs.size() > matchedCount) {
				matchedCount = joinPairs.size();
				bestIndex = ii;
				bestJoinPairs = joinPairs;
			}
		}
		
		if (bestIndex != null) {
			Plan p = new IndexJoinPlan(trunk, tp, bestIndex, bestJoinPairs, tx);
			/*
			 * Ideally, a select plan for this table should be
			 * created before applying the join. However, since
			 * indexjoin require the rhs plan to be a TablePlan,
			 * select predicate can only be added after the join, .
			 * which makes indexselect for this table infeasible.
			 */
			p = addSelectPredicate(p);
			return addJoinPredicate(p, trunkSch);
		}
		
		return null;
	}
private Plan makeIndexJoinPlan ( Plan trunk , Schema trunkSch ) { int matchedCount = 0 ; IndexInfo bestIndex = null ; Map < String , String > bestJoinPairs = null ; Set < IndexInfo > candidates = new HashSet < IndexInfo > ( ) ; for ( String fieldName : sch . fields ( ) ) { Set < String > outerFlds = pred . joinFields ( fieldName ) ; if ( outerFlds == null ) continue ; for ( String outerFld : outerFlds ) if ( trunkSch . hasField ( outerFld ) ) { List < IndexInfo > iis = VanillaDb . catalogMgr ( ) . getIndexInfo ( tblName , fieldName , tx ) ; candidates . addAll ( iis ) ; break ; } } for ( IndexInfo ii : candidates ) { if ( ii . fieldNames ( ) . size ( ) < matchedCount ) continue ; Map < String , String > joinPairs = new HashMap < String , String > ( ) ; for ( String fieldName : ii . fieldNames ( ) ) { Set < String > outerFlds = pred . joinFields ( fieldName ) ; for ( String outerFld : outerFlds ) if ( trunkSch . hasField ( outerFld ) ) { joinPairs . put ( outerFld , fieldName ) ; break ; } } if ( joinPairs . size ( ) > matchedCount ) { matchedCount = joinPairs . size ( ) ; bestIndex = ii ; bestJoinPairs = joinPairs ; } } if ( bestIndex != null ) { Plan p = new IndexJoinPlan ( trunk , tp , bestIndex , bestJoinPairs , tx ) ; p = addSelectPredicate ( p ) ; return addJoinPredicate ( p , trunkSch ) ; } return null ; }
Identify and construct an index join plan based on the predicate and
indexes by examining the fields opposite to an indexed field in all terms
of a predicate. Currently, fields and constants in a term cannot be moved
across the term operator. Therefore this method may not identify all
possible index joins. It is users' responsibility to issue queries that
help the identification: e.g., "F1 = F2", not "F1 - F2 = 0".