Index: common/src/java/org/apache/hadoop/hive/conf/HiveConf.java =================================================================== --- common/src/java/org/apache/hadoop/hive/conf/HiveConf.java (revision 1417820) +++ common/src/java/org/apache/hadoop/hive/conf/HiveConf.java (working copy) @@ -631,7 +631,7 @@ HIVE_CONCATENATE_CHECK_INDEX ("hive.exec.concatenate.check.index", true), HIVE_IO_EXCEPTION_HANDLERS("hive.io.exception.handlers", ""), - //prefix used to auto generated column aliases + // prefix used to auto generated column aliases (this should be started with '_') HIVE_AUTOGEN_COLUMNALIAS_PREFIX_LABEL("hive.autogen.columnalias.prefix.label", "_c"), HIVE_AUTOGEN_COLUMNALIAS_PREFIX_INCLUDEFUNCNAME( "hive.autogen.columnalias.prefix.includefuncname", false), Index: ql/src/test/results/clientpositive/alias_casted_column.q.out =================================================================== --- ql/src/test/results/clientpositive/alias_casted_column.q.out (revision 0) +++ ql/src/test/results/clientpositive/alias_casted_column.q.out (working copy) @@ -0,0 +1,84 @@ +PREHOOK: query: -- HIVE-2477 Use name of original expression for name of CAST output +explain select key from (select cast(key as int) from src )t +PREHOOK: type: QUERY +POSTHOOK: query: -- HIVE-2477 Use name of original expression for name of CAST output +explain select key from (select cast(key as int) from src )t +POSTHOOK: type: QUERY +ABSTRACT SYNTAX TREE: + (TOK_QUERY (TOK_FROM (TOK_SUBQUERY (TOK_QUERY (TOK_FROM (TOK_TABREF (TOK_TABNAME src))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR (TOK_FUNCTION TOK_INT (TOK_TABLE_OR_COL key)))))) t)) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR (TOK_TABLE_OR_COL key))))) + +STAGE DEPENDENCIES: + Stage-1 is a root stage + Stage-0 is a root stage + +STAGE PLANS: + Stage: Stage-1 + Map Reduce + Alias -> Map Operator Tree: + t:src + TableScan + alias: src + Select Operator + expressions: + expr: UDFToInteger(key) + type: int + outputColumnNames: _col0 + Select Operator + expressions: + expr: _col0 + type: int + outputColumnNames: _col0 + File Output Operator + compressed: false + GlobalTableId: 0 + table: + input format: org.apache.hadoop.mapred.TextInputFormat + output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat + + Stage: Stage-0 + Fetch Operator + limit: -1 + + +PREHOOK: query: --backward +explain select key2 from (select cast(key as int) key2 from src )t +PREHOOK: type: QUERY +POSTHOOK: query: --backward +explain select key2 from (select cast(key as int) key2 from src )t +POSTHOOK: type: QUERY +ABSTRACT SYNTAX TREE: + (TOK_QUERY (TOK_FROM (TOK_SUBQUERY (TOK_QUERY (TOK_FROM (TOK_TABREF (TOK_TABNAME src))) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR (TOK_FUNCTION TOK_INT (TOK_TABLE_OR_COL key)) key2)))) t)) (TOK_INSERT (TOK_DESTINATION (TOK_DIR TOK_TMP_FILE)) (TOK_SELECT (TOK_SELEXPR (TOK_TABLE_OR_COL key2))))) + +STAGE DEPENDENCIES: + Stage-1 is a root stage + Stage-0 is a root stage + +STAGE PLANS: + Stage: Stage-1 + Map Reduce + Alias -> Map Operator Tree: + t:src + TableScan + alias: src + Select Operator + expressions: + expr: UDFToInteger(key) + type: int + outputColumnNames: _col0 + Select Operator + expressions: + expr: _col0 + type: int + outputColumnNames: _col0 + File Output Operator + compressed: false + GlobalTableId: 0 + table: + input format: org.apache.hadoop.mapred.TextInputFormat + output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat + + Stage: Stage-0 + Fetch Operator + limit: -1 + + Index: ql/src/test/results/compiler/plan/input_testxpath2.q.xml =================================================================== --- ql/src/test/results/compiler/plan/input_testxpath2.q.xml (revision 1417820) +++ ql/src/test/results/compiler/plan/input_testxpath2.q.xml (working copy) @@ -532,7 +532,7 @@ - _c0 + lint _col0 @@ -545,7 +545,7 @@ - _c1 + lintstring _col1 @@ -558,7 +558,7 @@ - _c2 + mstringstring _col2 Index: ql/src/test/queries/clientpositive/alias_casted_column.q =================================================================== --- ql/src/test/queries/clientpositive/alias_casted_column.q (revision 0) +++ ql/src/test/queries/clientpositive/alias_casted_column.q (working copy) @@ -0,0 +1,5 @@ +-- HIVE-2477 Use name of original expression for name of CAST output +explain select key from (select cast(key as int) from src )t; + +--backward +explain select key2 from (select cast(key as int) key2 from src )t; Index: ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java (revision 1417820) +++ ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java (working copy) @@ -1180,6 +1180,34 @@ } /** + * Returns whether the exprNodeDesc is node of "cast". + */ + private static boolean isOpCast(ExprNodeDesc desc) { + if (!(desc instanceof ExprNodeGenericFuncDesc)) { + return false; + } + GenericUDF genericUDF = ((ExprNodeGenericFuncDesc)desc).getGenericUDF(); + Class udfClass; + if (genericUDF instanceof GenericUDFBridge) { + udfClass = ((GenericUDFBridge)genericUDF).getUdfClass(); + } else { + udfClass = genericUDF.getClass(); + } + return udfClass == UDFToBoolean.class || udfClass == UDFToByte.class || + udfClass == UDFToDouble.class || udfClass == UDFToFloat.class || + udfClass == UDFToInteger.class || udfClass == UDFToLong.class || + udfClass == UDFToShort.class || udfClass == UDFToString.class || + udfClass == GenericUDFTimestamp.class || udfClass == GenericUDFToBinary.class; + } + + /** + * Returns whether the exprNodeDesc can recommend name for the expression + */ + public static boolean isOpPreserveInputName(ExprNodeDesc desc) { + return isOpCast(desc); + } + + /** * Registers the appropriate kind of temporary function based on a class's * type. * Index: ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeDescUtils.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeDescUtils.java (revision 1417820) +++ ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeDescUtils.java (working copy) @@ -98,4 +98,19 @@ return new ExprNodeGenericFuncDesc(TypeInfoFactory.booleanTypeInfo, FunctionRegistry.getGenericUDFForAnd(), children); } + + /** + * Recommend name for the expression + */ + public static String recommendInputName(ExprNodeDesc desc) { + if (desc instanceof ExprNodeColumnDesc) { + return ((ExprNodeColumnDesc)desc).getColumn(); + } + List children = desc.getChildren(); + if (FunctionRegistry.isOpPreserveInputName(desc) && !children.isEmpty() && + children.get(0) instanceof ExprNodeColumnDesc) { + return ((ExprNodeColumnDesc)children.get(0)).getColumn(); + } + return null; + } } Index: ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java (revision 1417820) +++ ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java (working copy) @@ -126,6 +126,7 @@ import org.apache.hadoop.hive.ql.plan.ExprNodeColumnDesc; import org.apache.hadoop.hive.ql.plan.ExprNodeConstantDesc; import org.apache.hadoop.hive.ql.plan.ExprNodeDesc; +import org.apache.hadoop.hive.ql.plan.ExprNodeDescUtils; import org.apache.hadoop.hive.ql.plan.ExprNodeGenericFuncDesc; import org.apache.hadoop.hive.ql.plan.ExprNodeNullDesc; import org.apache.hadoop.hive.ql.plan.ExtractDesc; @@ -2413,6 +2414,10 @@ // We allow stateful functions in the SELECT list (but nowhere else) tcCtx.setAllowStatefulFunctions(true); 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); if (subQuery) { out_rwsch.checkColumn(tabAlias, colAlias); @@ -2461,6 +2466,17 @@ return output; } + private String recommendName(ExprNodeDesc exp, String colAlias) { + if (!colAlias.startsWith(autogenColAliasPrfxLbl)) { + return null; + } + String column = ExprNodeDescUtils.recommendInputName(exp); + if (column != null && !column.startsWith(autogenColAliasPrfxLbl)) { + return column; + } + return null; + } + /** * Class to store GenericUDAF related information. */