if (!noCheckOuterJoin) {
checkMapJoin(mapJoinPos, condns);
}
RowResolver oldOutputRS = opParseCtxMap.get(op).getRowResolver();
RowResolver outputRS = new RowResolver();
ArrayList<String> outputColumnNames = new ArrayList<String>();
Map<Byte, List<ExprNodeDesc>> keyExprMap = new HashMap<Byte, List<ExprNodeDesc>>();
Map<Byte, List<ExprNodeDesc>> valueExprMap = new HashMap<Byte, List<ExprNodeDesc>>();
// Walk over all the sources (which are guaranteed to be reduce sink
// operators).
// The join outputs a concatenation of all the inputs.
QBJoinTree leftSrc = joinTree.getJoinSrc();
List<Operator<? extends Serializable>> parentOps = op.getParentOperators();
List<Operator<? extends Serializable>> newParentOps = new ArrayList<Operator<? extends Serializable>>();
List<Operator<? extends Serializable>> oldReduceSinkParentOps = new ArrayList<Operator<? extends Serializable>>();
Map<String, ExprNodeDesc> colExprMap = new HashMap<String, ExprNodeDesc>();
HashMap<Byte, HashMap<String, ExprNodeDesc>> columnTransfer = new HashMap<Byte, HashMap<String, ExprNodeDesc>>();
// found a source which is not to be stored in memory
if (leftSrc != null) {
// assert mapJoinPos == 0;
Operator<? extends Serializable> parentOp = parentOps.get(0);
assert parentOp.getParentOperators().size() == 1;
Operator<? extends Serializable> grandParentOp = parentOp.getParentOperators().get(0);
oldReduceSinkParentOps.add(parentOp);
grandParentOp.removeChild(parentOp);
newParentOps.add(grandParentOp);
}
int pos = 0;
// Remove parent reduce-sink operators
for (String src : joinTree.getBaseSrc()) {
if (src != null) {
Operator<? extends Serializable> parentOp = parentOps.get(pos);
assert parentOp.getParentOperators().size() == 1;
Operator<? extends Serializable> grandParentOp = parentOp.getParentOperators().get(0);
grandParentOp.removeChild(parentOp);
oldReduceSinkParentOps.add(parentOp);
newParentOps.add(grandParentOp);
}
pos++;
}
// get the join keys from old parent ReduceSink operators
for (pos = 0; pos < newParentOps.size(); pos++) {
ReduceSinkOperator oldPar = (ReduceSinkOperator) oldReduceSinkParentOps.get(pos);
ReduceSinkDesc rsconf = oldPar.getConf();
Byte tag = (byte) rsconf.getTag();
List<ExprNodeDesc> keys = rsconf.getKeyCols();
keyExprMap.put(tag, keys);
// set column transfer
HashMap<String, ExprNodeDesc> map = (HashMap<String, ExprNodeDesc>) oldPar.getColumnExprMap();
columnTransfer.put(tag, map);
}
// create the map-join operator
for (pos = 0; pos < newParentOps.size(); pos++) {
RowResolver inputRS = opParseCtxMap.get(newParentOps.get(pos)).getRowResolver();
List<ExprNodeDesc> values = new ArrayList<ExprNodeDesc>();
Iterator<String> keysIter = inputRS.getTableNames().iterator();
while (keysIter.hasNext()) {
String key = keysIter.next();
HashMap<String, ColumnInfo> rrMap = inputRS.getFieldMap(key);
Iterator<String> fNamesIter = rrMap.keySet().iterator();
while (fNamesIter.hasNext()) {
String field = fNamesIter.next();
ColumnInfo valueInfo = inputRS.get(key, field);
ColumnInfo oldValueInfo = oldOutputRS.get(key, field);
if (oldValueInfo == null) {
continue;
}
String outputCol = oldValueInfo.getInternalName();