diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java index ba64f97105..c7a679b1b4 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/CalcitePlanner.java @@ -3903,102 +3903,92 @@ private void setQueryHints(QB qb) throws SemanticException { } } - Map subQueryToRelNode = new HashMap<>(); - boolean isSubQuery = genSubQueryRelNode(qb, expr, srcRel, false, - subQueryToRelNode); - if(isSubQuery) { - ExprNodeDesc subQueryExpr = genExprNodeDesc(expr, relToHiveRR.get(srcRel), - outerRR, subQueryToRelNode, true); - col_list.add(subQueryExpr); + Map subQueryToRelNode = new HashMap<>(); + boolean isSubQuery = genSubQueryRelNode(qb, expr, srcRel, false, + subQueryToRelNode); + if(isSubQuery) { + ExprNodeDesc subQueryExpr = genExprNodeDesc(expr, relToHiveRR.get(srcRel), + outerRR, subQueryToRelNode, true); + col_list.add(subQueryExpr); + + ColumnInfo colInfo = new ColumnInfo(SemanticAnalyzer.getColumnInternalName(pos), + subQueryExpr.getWritableObjectInspector(), tabAlias, false); + if (!out_rwsch.putWithCheck(tabAlias, colAlias, null, colInfo)) { + throw new CalciteSemanticException("Cannot add column to RR: " + tabAlias + "." + + colAlias + " => " + colInfo + " due to duplication, see previous warnings", + UnsupportedFeature.Duplicates_in_RR); + } + pos = Integer.valueOf(pos.intValue() + 1); + } else { + + // 6.4 Build ExprNode corresponding to colums + if (expr.getType() == HiveParser.TOK_ALLCOLREF) { + pos = genColListRegex(".*", expr.getChildCount() == 0 ? null : SemanticAnalyzer + .getUnescapedName((ASTNode) expr.getChild(0)).toLowerCase(), expr, col_list, + excludedColumns, inputRR, starRR, pos, out_rwsch, qb.getAliases(), true); + selectStar = true; + } else if (expr.getType() == HiveParser.TOK_TABLE_OR_COL + && !hasAsClause + && !inputRR.getIsExprResolver() + && SemanticAnalyzer.isRegex( + SemanticAnalyzer.unescapeIdentifier(expr.getChild(0).getText()), conf)) { + // In case the expression is a regex COL. + // This can only happen without AS clause + // We don't allow this for ExprResolver - the Group By case + pos = genColListRegex(SemanticAnalyzer.unescapeIdentifier(expr.getChild(0).getText()), + null, expr, col_list, excludedColumns, inputRR, starRR, pos, out_rwsch, + qb.getAliases(), true); + } else if (expr.getType() == HiveParser.DOT + && expr.getChild(0).getType() == HiveParser.TOK_TABLE_OR_COL + && inputRR.hasTableAlias(SemanticAnalyzer.unescapeIdentifier(expr.getChild(0) + .getChild(0).getText().toLowerCase())) + && !hasAsClause + && !inputRR.getIsExprResolver() + && SemanticAnalyzer.isRegex( + SemanticAnalyzer.unescapeIdentifier(expr.getChild(1).getText()), conf)) { + // In case the expression is TABLE.COL (col can be regex). + // This can only happen without AS clause + // We don't allow this for ExprResolver - the Group By case + pos = genColListRegex( + SemanticAnalyzer.unescapeIdentifier(expr.getChild(1).getText()), + SemanticAnalyzer.unescapeIdentifier(expr.getChild(0).getChild(0).getText() + .toLowerCase()), expr, col_list, excludedColumns, inputRR, starRR, pos, + out_rwsch, qb.getAliases(), true); + } else if (ParseUtils.containsTokenOfType(expr, HiveParser.TOK_FUNCTIONDI) + && !(srcRel instanceof HiveAggregate)) { + // Likely a malformed query eg, select hash(distinct c1) from t1; + throw new CalciteSemanticException("Distinct without an aggregation.", + UnsupportedFeature.Distinct_without_an_aggreggation); + } else { + // Case when this is an expression + TypeCheckCtx tcCtx = new TypeCheckCtx(inputRR); + // We allow stateful functions in the SELECT list (but nowhere else) + tcCtx.setAllowStatefulFunctions(true); + if (!qbp.getDestToGroupBy().isEmpty()) { + // Special handling of grouping function + expr = rewriteGroupingFunctionAST(getGroupByForClause(qbp, selClauseName), expr, + !cubeRollupGrpSetPresent); + } + ExprNodeDesc exp = genExprNodeDesc(expr, inputRR, tcCtx); + String recommended = recommendName(exp, colAlias); + if (recommended != null && out_rwsch.get(null, recommended) == null) { + colAlias = recommended; + } + col_list.add(exp); ColumnInfo colInfo = new ColumnInfo(SemanticAnalyzer.getColumnInternalName(pos), - subQueryExpr.getWritableObjectInspector(), tabAlias, false); + exp.getWritableObjectInspector(), tabAlias, false); + colInfo.setSkewedCol((exp instanceof ExprNodeColumnDesc) ? ((ExprNodeColumnDesc) exp) + .isSkewedCol() : false); if (!out_rwsch.putWithCheck(tabAlias, colAlias, null, colInfo)) { throw new CalciteSemanticException("Cannot add column to RR: " + tabAlias + "." + colAlias + " => " + colInfo + " due to duplication, see previous warnings", UnsupportedFeature.Duplicates_in_RR); } - pos = Integer.valueOf(pos.intValue() + 1); - } else { - // 6.4 Build ExprNode corresponding to colums - if (expr.getType() == HiveParser.TOK_ALLCOLREF) { - pos = genColListRegex(".*", expr.getChildCount() == 0 ? null : SemanticAnalyzer - .getUnescapedName((ASTNode) expr.getChild(0)).toLowerCase(), expr, col_list, - excludedColumns, inputRR, starRR, pos, out_rwsch, qb.getAliases(), true); - selectStar = true; - } else if (expr.getType() == HiveParser.TOK_TABLE_OR_COL - && !hasAsClause - && !inputRR.getIsExprResolver() - && SemanticAnalyzer.isRegex( - SemanticAnalyzer.unescapeIdentifier(expr.getChild(0).getText()), conf)) { - // In case the expression is a regex COL. - // This can only happen without AS clause - // We don't allow this for ExprResolver - the Group By case - pos = genColListRegex(SemanticAnalyzer.unescapeIdentifier(expr.getChild(0).getText()), - null, expr, col_list, excludedColumns, inputRR, starRR, pos, out_rwsch, - qb.getAliases(), true); - } else if (expr.getType() == HiveParser.DOT - && expr.getChild(0).getType() == HiveParser.TOK_TABLE_OR_COL - && inputRR.hasTableAlias(SemanticAnalyzer.unescapeIdentifier(expr.getChild(0) - .getChild(0).getText().toLowerCase())) - && !hasAsClause - && !inputRR.getIsExprResolver() - && SemanticAnalyzer.isRegex( - SemanticAnalyzer.unescapeIdentifier(expr.getChild(1).getText()), conf)) { - // In case the expression is TABLE.COL (col can be regex). - // This can only happen without AS clause - // We don't allow this for ExprResolver - the Group By case - pos = genColListRegex( - SemanticAnalyzer.unescapeIdentifier(expr.getChild(1).getText()), - SemanticAnalyzer.unescapeIdentifier(expr.getChild(0).getChild(0).getText() - .toLowerCase()), expr, col_list, excludedColumns, inputRR, starRR, pos, - out_rwsch, qb.getAliases(), true); - } else if (ParseUtils.containsTokenOfType(expr, HiveParser.TOK_FUNCTIONDI) - && !(srcRel instanceof HiveAggregate)) { - // Likely a malformed query eg, select hash(distinct c1) from t1; - throw new CalciteSemanticException("Distinct without an aggregation.", - UnsupportedFeature.Distinct_without_an_aggreggation); - } - else { - // Case when this is an expression - TypeCheckCtx tcCtx = new TypeCheckCtx(inputRR); - // We allow stateful functions in the SELECT list (but nowhere else) - tcCtx.setAllowStatefulFunctions(true); - if (!qbp.getDestToGroupBy().isEmpty()) { - // Special handling of grouping function - expr = rewriteGroupingFunctionAST(getGroupByForClause(qbp, selClauseName), expr, - !cubeRollupGrpSetPresent); - } - ExprNodeDesc exp = genExprNodeDesc(expr, inputRR, tcCtx); - String recommended = recommendName(exp, colAlias); - if (recommended != null && out_rwsch.get(null, recommended) == null) { - colAlias = recommended; - } - col_list.add(exp); - - ColumnInfo colInfo = new ColumnInfo(SemanticAnalyzer.getColumnInternalName(pos), - exp.getWritableObjectInspector(), tabAlias, false); - colInfo.setSkewedCol((exp instanceof ExprNodeColumnDesc) ? ((ExprNodeColumnDesc) exp) - .isSkewedCol() : false); - if (!out_rwsch.putWithCheck(tabAlias, colAlias, null, colInfo)) { - throw new CalciteSemanticException("Cannot add column to RR: " + tabAlias + "." - + colAlias + " => " + colInfo + " due to duplication, see previous warnings", - UnsupportedFeature.Duplicates_in_RR); - } - - if (exp instanceof ExprNodeColumnDesc) { - ExprNodeColumnDesc colExp = (ExprNodeColumnDesc) exp; - String[] altMapping = inputRR.getAlternateMappings(colExp.getColumn()); - if (altMapping != null) { - // TODO: this can overwrite the mapping. Should this be allowed? - out_rwsch.put(altMapping[0], altMapping[1], colInfo); - } - } - - pos = Integer.valueOf(pos.intValue() + 1); - } + pos = Integer.valueOf(pos.intValue() + 1); } + } } selectStar = selectStar && exprList.getChildCount() == posn + 1; diff --git a/ql/src/test/queries/clientpositive/groupby_multialias.q b/ql/src/test/queries/clientpositive/groupby_multialias.q new file mode 100644 index 0000000000..b0a01715d2 --- /dev/null +++ b/ql/src/test/queries/clientpositive/groupby_multialias.q @@ -0,0 +1,7 @@ +create table t1 (a int); + +explain +select t1.a as a1, min(t1.a) as a +from t1 +group by t1.a; + diff --git a/ql/src/test/results/clientpositive/groupby_multialias.q.out b/ql/src/test/results/clientpositive/groupby_multialias.q.out new file mode 100644 index 0000000000..cee790a3c6 --- /dev/null +++ b/ql/src/test/results/clientpositive/groupby_multialias.q.out @@ -0,0 +1,66 @@ +PREHOOK: query: create table t1 (a int) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@t1 +POSTHOOK: query: create table t1 (a int) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@t1 +PREHOOK: query: explain +select t1.a as a1, min(t1.a) as a +from t1 +group by t1.a +PREHOOK: type: QUERY +POSTHOOK: query: explain +select t1.a as a1, min(t1.a) as a +from t1 +group by t1.a +POSTHOOK: type: QUERY +STAGE DEPENDENCIES: + Stage-1 is a root stage + Stage-0 depends on stages: Stage-1 + +STAGE PLANS: + Stage: Stage-1 + Map Reduce + Map Operator Tree: + TableScan + alias: t1 + Statistics: Num rows: 1 Data size: 0 Basic stats: PARTIAL Column stats: NONE + Select Operator + expressions: a (type: int) + outputColumnNames: a + Statistics: Num rows: 1 Data size: 0 Basic stats: PARTIAL Column stats: NONE + Group By Operator + aggregations: min(a) + keys: a (type: int) + mode: hash + outputColumnNames: _col0, _col1 + Statistics: Num rows: 1 Data size: 0 Basic stats: PARTIAL Column stats: NONE + Reduce Output Operator + key expressions: _col0 (type: int) + sort order: + + Map-reduce partition columns: _col0 (type: int) + Statistics: Num rows: 1 Data size: 0 Basic stats: PARTIAL Column stats: NONE + value expressions: _col1 (type: int) + Reduce Operator Tree: + Group By Operator + aggregations: min(VALUE._col0) + keys: KEY._col0 (type: int) + mode: mergepartial + outputColumnNames: _col0, _col1 + Statistics: Num rows: 1 Data size: 0 Basic stats: PARTIAL Column stats: NONE + File Output Operator + compressed: false + Statistics: Num rows: 1 Data size: 0 Basic stats: PARTIAL Column stats: NONE + table: + input format: org.apache.hadoop.mapred.SequenceFileInputFormat + output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat + serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe + + Stage: Stage-0 + Fetch Operator + limit: -1 + Processor Tree: + ListSink +