diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result index c84da0d74968d52d636f07a62656042e0bf6ceca..2555749fa8c1a251437517f9bfa9683bd98ef8cb 100644 --- a/mysql-test/r/ctype_recoding.result +++ b/mysql-test/r/ctype_recoding.result @@ -277,9 +277,40 @@ CREATE TABLE t1 ( a VARCHAR(1) ); INSERT INTO t1 VALUES ('m'),('n'); CREATE VIEW v1 AS SELECT 'w' ; SELECT * FROM t1 WHERE a < ALL ( SELECT * FROM v1 ); -ERROR HY000: Illegal mix of collations (utf8_general_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '<=' +a +m +n drop view v1; drop table t1; SET character_set_connection = default; SET optimizer_switch= default; #End of 5.3 tests +# +# Start of 5.5 tests +# +# +# MDEV-10181 Illegal mix of collation for a field and an ASCII string as a view field +# +SET NAMES utf8; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1); +INSERT INTO t1 VALUES ('A'),('a'),('B'),('b'); +CREATE VIEW v1 AS SELECT 'a'; +SELECT * FROM v1,t1 where t1.a=v1.a; +a a +a A +a a +DROP VIEW v1; +DROP TABLE t1; +SET NAMES utf8; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1); +INSERT INTO t1 VALUES ('a'),('b'),('c'); +CREATE VIEW v1 AS SELECT 'a' AS a UNION SELECT 'b'; +SELECT * FROM v1,t1 WHERE t1.a=v1.a; +a a +a a +b b +DROP VIEW v1; +DROP TABLE t1; +# +# End of 5.5 tests +# diff --git a/mysql-test/t/ctype_recoding.test b/mysql-test/t/ctype_recoding.test index ee07ef24deff77eb2091a028643f35cfce2060f1..81c04fc9c309af113db466553bc080bfb6f33e8d 100644 --- a/mysql-test/t/ctype_recoding.test +++ b/mysql-test/t/ctype_recoding.test @@ -220,7 +220,6 @@ SET character_set_connection = utf8; CREATE TABLE t1 ( a VARCHAR(1) ); INSERT INTO t1 VALUES ('m'),('n'); CREATE VIEW v1 AS SELECT 'w' ; ---error ER_CANT_AGGREGATE_2COLLATIONS SELECT * FROM t1 WHERE a < ALL ( SELECT * FROM v1 ); drop view v1; drop table t1; @@ -228,3 +227,30 @@ SET character_set_connection = default; SET optimizer_switch= default; --echo #End of 5.3 tests + +--echo # +--echo # Start of 5.5 tests +--echo # + +--echo # +--echo # MDEV-10181 Illegal mix of collation for a field and an ASCII string as a view field +--echo # +SET NAMES utf8; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1); +INSERT INTO t1 VALUES ('A'),('a'),('B'),('b'); +CREATE VIEW v1 AS SELECT 'a'; +SELECT * FROM v1,t1 where t1.a=v1.a; +DROP VIEW v1; +DROP TABLE t1; + +SET NAMES utf8; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1); +INSERT INTO t1 VALUES ('a'),('b'),('c'); +CREATE VIEW v1 AS SELECT 'a' AS a UNION SELECT 'b'; +SELECT * FROM v1,t1 WHERE t1.a=v1.a; +DROP VIEW v1; +DROP TABLE t1; + +--echo # +--echo # End of 5.5 tests +--echo # diff --git a/sql/field.cc b/sql/field.cc index ceea0893a3f7bfbe545da38c9164b8e4de045404..a0686fb2f1974c14c7e41f55864316079b0e5568 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1701,6 +1701,7 @@ Field_str::Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, if (charset_arg->state & MY_CS_BINSORT) flags|=BINARY_FLAG; field_derivation= DERIVATION_IMPLICIT; + field_repertoire= my_charset_repertoire(charset_arg); } diff --git a/sql/field.h b/sql/field.h index f761aa8d3ea303bf62ab60ec2f00cebc3619241b..fdf229edfbbe34fb770cd61312d65383dae4da69 100644 --- a/sql/field.h +++ b/sql/field.h @@ -580,11 +580,12 @@ class Field { return binary() ? &my_charset_bin : charset(); } virtual CHARSET_INFO *sort_charset(void) const { return charset(); } virtual bool has_charset(void) const { return FALSE; } - virtual void set_charset(CHARSET_INFO *charset_arg) { } virtual enum Derivation derivation(void) const { return DERIVATION_IMPLICIT; } virtual uint repertoire(void) const { return MY_REPERTOIRE_UNICODE30; } - virtual void set_derivation(enum Derivation derivation_arg) { } + virtual void set_derivation(enum Derivation derivation_arg, + uint repertoire_arg) + { } virtual int set_time() { return 1; } void set_warning(MYSQL_ERROR::enum_warning_level, unsigned int code, int cuted_increment); @@ -775,8 +776,10 @@ class Field_num :public Field { class Field_str :public Field { protected: + // TODO-10.2: Reuse DTCollation instead of these three members CHARSET_INFO *field_charset; enum Derivation field_derivation; + uint field_repertoire; public: Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, @@ -799,15 +802,15 @@ class Field_str :public Field { int store_decimal(const my_decimal *); int store(const char *to,uint length,CHARSET_INFO *cs)=0; uint size_of() const { return sizeof(*this); } - uint repertoire(void) const - { - return my_charset_repertoire(field_charset); - } + uint repertoire(void) const { return field_repertoire; } CHARSET_INFO *charset(void) const { return field_charset; } - void set_charset(CHARSET_INFO *charset_arg) { field_charset= charset_arg; } enum Derivation derivation(void) const { return field_derivation; } - virtual void set_derivation(enum Derivation derivation_arg) - { field_derivation= derivation_arg; } + void set_derivation(enum Derivation derivation_arg, + uint repertoire_arg) + { + field_derivation= derivation_arg; + field_repertoire= repertoire_arg; + } bool binary() const { return field_charset == &my_charset_bin; } uint32 max_display_length() { return field_length; } friend class Create_field; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 91aecadfd0a3c5accdffb730e4e5771477ac5497..613cbb2e08699386288666408b1b5fc632f0e81e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -14586,7 +14586,8 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, item->collation.collation); else new_field= item->make_string_field(table); - new_field->set_derivation(item->collation.derivation); + new_field->set_derivation(item->collation.derivation, + item->collation.repertoire); break; case DECIMAL_RESULT: new_field= Field_new_decimal::create_from_item(item); @@ -14825,7 +14826,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, modify_item, convert_blob_length); case Item::TYPE_HOLDER: result= ((Item_type_holder *)item)->make_field_by_type(table); - result->set_derivation(item->collation.derivation); + result->set_derivation(item->collation.derivation, + item->collation.repertoire); return result; default: // Dosen't have to be stored return 0;