if (numAttr > 1) {
List<Long> perAttrDVs = Lists.newArrayList();
for (int idx = 0; idx < numAttr; idx++) {
for (Integer i : joinKeys.keySet()) {
String col = joinKeys.get(i).get(idx);
ColStatistics cs = joinedColStats.get(col);
if (cs != null) {
perAttrDVs.add(cs.getCountDistint());
}
}
distinctVals.add(getDenominator(perAttrDVs));
perAttrDVs.clear();
}
if (numAttr > numParent) {
// To avoid denominator getting larger and aggressively reducing
// number of rows, we will ease out denominator.
denom = getEasedOutDenominator(distinctVals);
} else {
for (Long l : distinctVals) {
denom = StatsUtils.safeMult(denom, l);
}
}
} else {
for (List<String> jkeys : joinKeys.values()) {
for (String jk : jkeys) {
ColStatistics cs = joinedColStats.get(jk);
if (cs != null) {
distinctVals.add(cs.getCountDistint());
}
}
}
denom = getDenominator(distinctVals);
}
// Update NDV of joined columns to be min(V(R,y), V(S,y))
updateJoinColumnsNDV(joinKeys, joinedColStats, numAttr);
// column statistics from different sources are put together and rename
// fully qualified column names based on output schema of join operator
Map<String, ExprNodeDesc> colExprMap = jop.getColumnExprMap();
RowSchema rs = jop.getSchema();
List<ColStatistics> outColStats = Lists.newArrayList();
Map<String, String> outInTabAlias = new HashMap<String, String>();
for (ColumnInfo ci : rs.getSignature()) {
String key = ci.getInternalName();
ExprNodeDesc end = colExprMap.get(key);
if (end instanceof ExprNodeColumnDesc) {
String colName = ((ExprNodeColumnDesc) end).getColumn();
String tabAlias = ((ExprNodeColumnDesc) end).getTabAlias();
String fqColName = StatsUtils.getFullyQualifiedColumnName(tabAlias, colName);
ColStatistics cs = joinedColStats.get(fqColName);
String outColName = key;
String outTabAlias = ci.getTabAlias();
outInTabAlias.put(outTabAlias, tabAlias);
if (cs != null) {
cs.setColumnName(outColName);
cs.setTableAlias(outTabAlias);
}
outColStats.add(cs);
}
}