ArrayList<ColumnInfo> colInfoList = inputRR.getColumnInfos();
RowResolver rsNewRR = new RowResolver();
int pos = 0;
for (ColumnInfo colInfo : colInfoList) {
ExprNodeDesc valueColExpr = new ExprNodeColumnDesc(colInfo.getType(), colInfo
.getInternalName(), colInfo.getTabAlias(), colInfo
.getIsVirtualCol());
valueCols.add(valueColExpr);
colExprMap.put(colInfo.getInternalName(), valueColExpr);
String outColName = SemanticAnalyzer.getColumnInternalName(pos++);
outputColumnNames.add(outColName);
String[] alias = inputRR.reverseLookup(colInfo.getInternalName());
ColumnInfo newColInfo = new ColumnInfo(
outColName, colInfo.getType(), alias[0],
colInfo.getIsVirtualCol(), colInfo.isHiddenVirtualCol());
rsNewRR.put(alias[0], alias[1], newColInfo);
}
input = putOpInsertMap(OperatorFactory.getAndMakeChild(PlanUtils
.getReduceSinkDesc(orderCols,
valueCols, outputColumnNames, false,
-1, partCols, orderString.toString(), -1),
new RowSchema(rsNewRR.getColumnInfos()), input), rsNewRR);
input.setColumnExprMap(colExprMap);
// Construct the RR for extract operator
RowResolver extractRR = new RowResolver();
LinkedHashMap<String[], ColumnInfo> colsAddedByHaving =
new LinkedHashMap<String[], ColumnInfo>();
pos = 0;
for (ColumnInfo colInfo : colInfoList) {
String[] alias = inputRR.reverseLookup(colInfo.getInternalName());
/*
* if we have already encountered this colInfo internalName.
* We encounter it again because it must be put for the Having clause.
* We will add these entries in the end; in a loop on colsAddedByHaving. See below.
*/
if ( colsAddedByHaving.containsKey(alias)) {
continue;
}
ASTNode astNode = PTFTranslator.getASTNode(colInfo, inputRR);
ColumnInfo eColInfo = new ColumnInfo(
SemanticAnalyzer.getColumnInternalName(pos++), colInfo.getType(), alias[0],
colInfo.getIsVirtualCol(), colInfo.isHiddenVirtualCol());
if ( astNode == null ) {
extractRR.put(alias[0], alias[1], eColInfo);
}
else {
/*
* in case having clause refers to this column may have been added twice;
* once with the ASTNode.toStringTree as the alias
* and then with the real alias.
*/
extractRR.putExpression(astNode, eColInfo);
if ( !astNode.toStringTree().toLowerCase().equals(alias[1]) ) {
colsAddedByHaving.put(alias, eColInfo);
}
}
}
for(Map.Entry<String[], ColumnInfo> columnAddedByHaving : colsAddedByHaving.entrySet() ) {
String[] alias = columnAddedByHaving.getKey();
ColumnInfo eColInfo = columnAddedByHaving.getValue();
extractRR.put(alias[0], alias[1], eColInfo);
}
/*
* b. Construct Extract Operator.
*/
input = putOpInsertMap(OperatorFactory.getAndMakeChild(
new ExtractDesc(
new ExprNodeColumnDesc(TypeInfoFactory.stringTypeInfo,
Utilities.ReduceField.VALUE
.toString(), "", false)),
new RowSchema(inputRR.getColumnInfos()),
input), extractRR);