diff --git ql/src/java/org/apache/hadoop/hive/ql/exec/UnionOperator.java ql/src/java/org/apache/hadoop/hive/ql/exec/UnionOperator.java index 59c07c352e1bf2bbc275ea8638f2334d120fe90c..0f761e8340dbfe539c6e3ecd15d246fcb04a8f3e 100644 --- ql/src/java/org/apache/hadoop/hive/ql/exec/UnionOperator.java +++ ql/src/java/org/apache/hadoop/hive/ql/exec/UnionOperator.java @@ -80,7 +80,7 @@ protected void initializeOp(Configuration hconf) throws HiveException { for (int p = 0; p < parents; p++) { assert (parentFields[p].size() == columns); for (int c = 0; c < columns; c++) { - if (!columnTypeResolvers[c].update(parentFields[p].get(c) + if (!columnTypeResolvers[c].updateForUnionAll(parentFields[p].get(c) .getFieldObjectInspector())) { // checked in SemanticAnalyzer. Should not happen throw new HiveException("Incompatible types for union operator"); diff --git ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFUtils.java ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFUtils.java index 1f70c552f35aaf52da22d90f6d0d2843983fbed5..833452d1454749c0d4aa3af07fadf12ba46a8d53 100644 --- ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFUtils.java +++ ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFUtils.java @@ -100,6 +100,26 @@ public ReturnObjectInspectorResolver(boolean allowTypeConversion) { * @return false if there is a type mismatch */ public boolean update(ObjectInspector oi) throws UDFArgumentTypeException { + return update(oi, false); + } + + /** + * Update returnObjectInspector and valueInspectorsAreTheSame based on the + * ObjectInspector seen for UnionAll. + * + * @return false if there is a type mismatch + */ + public boolean updateForUnionAll(ObjectInspector oi) throws UDFArgumentTypeException { + return update(oi, true); + } + + /** + * Update returnObjectInspector and valueInspectorsAreTheSame based on the + * ObjectInspector seen. + * + * @return false if there is a type mismatch + */ + private boolean update(ObjectInspector oi, boolean isUnionAll) throws UDFArgumentTypeException { if (oi instanceof VoidObjectInspector) { return true; } @@ -137,8 +157,14 @@ public boolean update(ObjectInspector oi) throws UDFArgumentTypeException { // Types are different, we need to check whether we can convert them to // a common base class or not. - TypeInfo commonTypeInfo = FunctionRegistry.getCommonClass(oiTypeInfo, + TypeInfo commonTypeInfo = null; + if (isUnionAll) { + commonTypeInfo = FunctionRegistry.getCommonClassForUnionAll(oiTypeInfo, + rTypeInfo); + } else { + commonTypeInfo = FunctionRegistry.getCommonClass(oiTypeInfo, rTypeInfo); + } if (commonTypeInfo == null) { return false; } diff --git ql/src/test/queries/clientpositive/union_date_trim.q ql/src/test/queries/clientpositive/union_date_trim.q new file mode 100644 index 0000000000000000000000000000000000000000..6842e564419a9d461a4ba6421083a6ebbf7f6342 --- /dev/null +++ ql/src/test/queries/clientpositive/union_date_trim.q @@ -0,0 +1,7 @@ +drop table if exists testDate; +create table testDate(id int, dt date); +insert into table testDate select 1, '2014-04-07' from src where key=100 limit 1; +insert into table testDate select 2, '2014-04-08' from src where key=100 limit 1; +insert into table testDate select 3, '2014-04-09' from src where key=100 limit 1; +--- without the fix following query will throw HiveException: Incompatible types for union operator +insert into table testDate select id, tm from (select id, dt as tm from testDate where id = 1 union all select id, dt as tm from testDate where id = 2 union all select id, trim(Cast (dt as string)) as tm from testDate where id = 3 ) a; diff --git ql/src/test/results/clientpositive/union_date_trim.q.out ql/src/test/results/clientpositive/union_date_trim.q.out new file mode 100644 index 0000000000000000000000000000000000000000..e0682e64ee2cdb1043574a27dc633eb84676c3d6 --- /dev/null +++ ql/src/test/results/clientpositive/union_date_trim.q.out @@ -0,0 +1,54 @@ +PREHOOK: query: drop table if exists testDate +PREHOOK: type: DROPTABLE +POSTHOOK: query: drop table if exists testDate +POSTHOOK: type: DROPTABLE +PREHOOK: query: create table testDate(id int, dt date) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@testDate +POSTHOOK: query: create table testDate(id int, dt date) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@testDate +PREHOOK: query: insert into table testDate select 1, '2014-04-07' from src where key=100 limit 1 +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Output: default@testdate +POSTHOOK: query: insert into table testDate select 1, '2014-04-07' from src where key=100 limit 1 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Output: default@testdate +POSTHOOK: Lineage: testdate.dt EXPRESSION [] +POSTHOOK: Lineage: testdate.id SIMPLE [] +PREHOOK: query: insert into table testDate select 2, '2014-04-08' from src where key=100 limit 1 +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Output: default@testdate +POSTHOOK: query: insert into table testDate select 2, '2014-04-08' from src where key=100 limit 1 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Output: default@testdate +POSTHOOK: Lineage: testdate.dt EXPRESSION [] +POSTHOOK: Lineage: testdate.id SIMPLE [] +PREHOOK: query: insert into table testDate select 3, '2014-04-09' from src where key=100 limit 1 +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Output: default@testdate +POSTHOOK: query: insert into table testDate select 3, '2014-04-09' from src where key=100 limit 1 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Output: default@testdate +POSTHOOK: Lineage: testdate.dt EXPRESSION [] +POSTHOOK: Lineage: testdate.id SIMPLE [] +PREHOOK: query: --- without the fix following query will throw HiveException: Incompatible types for union operator +insert into table testDate select id, tm from (select id, dt as tm from testDate where id = 1 union all select id, dt as tm from testDate where id = 2 union all select id, trim(Cast (dt as string)) as tm from testDate where id = 3 ) a +PREHOOK: type: QUERY +PREHOOK: Input: default@testdate +PREHOOK: Output: default@testdate +POSTHOOK: query: --- without the fix following query will throw HiveException: Incompatible types for union operator +insert into table testDate select id, tm from (select id, dt as tm from testDate where id = 1 union all select id, dt as tm from testDate where id = 2 union all select id, trim(Cast (dt as string)) as tm from testDate where id = 3 ) a +POSTHOOK: type: QUERY +POSTHOOK: Input: default@testdate +POSTHOOK: Output: default@testdate +POSTHOOK: Lineage: testdate.dt EXPRESSION [] +POSTHOOK: Lineage: testdate.id EXPRESSION [(testdate)testdate.FieldSchema(name:id, type:int, comment:null), (testdate)testdate.FieldSchema(name:id, type:int, comment:null), (testdate)testdate.FieldSchema(name:id, type:int, comment:null), ]