diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 2f42bedf67a..fbd4f8e11dc 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -996,3 +996,40 @@ PARTITIONED_B WHERE PARTITIONED_B.ID=PARTITIONED.ID1) UNION PARTITIONED_B WHERE PARTITIONED_B.ID=PARTITIONED.ID1); ID1 ID2 DATA1 DATA2 DATA3 ID DATA1 drop table t1,t2; +create table t1 (a ENUM('Yes', 'No') NOT NULL); +create table t2 (a ENUM('aaa', 'bbb') NOT NULL); +insert into t1 values ('No'); +insert into t2 values ('bbb'); +create table t3 (a SET('Yes', 'No') NOT NULL); +create table t4 (a SET('aaa', 'bbb') NOT NULL); +insert into t3 values (1); +insert into t4 values (3); +select "1" as a union select a from t1; +a +1 +No +select a as a from t1 union select "1"; +a +No +1 +select a as a from t2 union select a from t1; +a +bbb +No +select "1" as a union select a from t3; +a +1 +Yes +select a as a from t3 union select "1"; +a +Yes +1 +select a as a from t4 union select a from t3; +a +aaa,bbb +Yes +select a as a from t1 union select a from t4; +a +No +aaa,bbb +drop table t1,t2,t3,t4; diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 263f631a65f..c5e72e85835 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -575,3 +575,23 @@ PARTITIONED_B WHERE PARTITIONED_B.ID=PARTITIONED.ID1) UNION (SELECT * FROM t1 AS PARTITIONED, t2 AS PARTITIONED_B WHERE PARTITIONED_B.ID=PARTITIONED.ID1); drop table t1,t2; + +# +# merging ENUM and SET fields in one UNION +# +create table t1 (a ENUM('Yes', 'No') NOT NULL); +create table t2 (a ENUM('aaa', 'bbb') NOT NULL); +insert into t1 values ('No'); +insert into t2 values ('bbb'); +create table t3 (a SET('Yes', 'No') NOT NULL); +create table t4 (a SET('aaa', 'bbb') NOT NULL); +insert into t3 values (1); +insert into t4 values (3); +select "1" as a union select a from t1; +select a as a from t1 union select "1"; +select a as a from t2 union select a from t1; +select "1" as a union select a from t3; +select a as a from t3 union select "1"; +select a as a from t4 union select a from t3; +select a as a from t1 union select a from t4; +drop table t1,t2,t3,t4; diff --git a/sql/item.cc b/sql/item.cc index 8233d050783..2ae0fb598ec 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2509,27 +2509,41 @@ bool Item_type_holder::join_types(THD *thd, Item *item) bool change_field= 0, skip_store_field= 0; Item_result new_type= type_convertor[item_type][item->result_type()]; - // we have both fields + /* + we have both fields and field is not enum or set(different enums(sets) + can't be joinned in one enum(set) field) + */ if (field_example && item->type() == Item::FIELD_ITEM) { Field *field= ((Item_field *)item)->field; - if (field_example->field_cast_type() != field->field_cast_type()) + Field::field_cast_enum field_type= field->field_cast_type(); + + if (field_type != Field::FIELD_CAST_ENUM && + field_type != Field::FIELD_CAST_SET) { - if (!(change_field= - field_example->field_cast_compatible(field->field_cast_type()))) + if (field_example->field_cast_type() != field_type) { - /* - if old field can't store value of 'worse' new field we will make - decision about result field type based only on Item result type - */ - if (!field->field_cast_compatible(field_example->field_cast_type())) - skip_store_field= 1; + if (!(change_field= + field_example->field_cast_compatible(field->field_cast_type()))) + { + /* + if old field can't store value of 'worse' new field we will make + decision about result field type based only on Item result type + */ + if (!field->field_cast_compatible(field_example->field_cast_type())) + skip_store_field= 1; + } } } + else + skip_store_field= 1; } + else if (field_example || item->type() == Item::FIELD_ITEM) + skip_store_field= 1; // size/type should be changed if (change_field || + skip_store_field || (new_type != item_type) || (max_length < new_length) || ((new_type == INT_RESULT) &&