Commit df144880 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-10181 Illegal mix of collation for a field and an ASCII string as a view field

parent 7adf04e2
...@@ -277,9 +277,40 @@ CREATE TABLE t1 ( a VARCHAR(1) ); ...@@ -277,9 +277,40 @@ CREATE TABLE t1 ( a VARCHAR(1) );
INSERT INTO t1 VALUES ('m'),('n'); INSERT INTO t1 VALUES ('m'),('n');
CREATE VIEW v1 AS SELECT 'w' ; CREATE VIEW v1 AS SELECT 'w' ;
SELECT * FROM t1 WHERE a < ALL ( SELECT * FROM v1 ); 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 view v1;
drop table t1; drop table t1;
SET character_set_connection = default; SET character_set_connection = default;
SET optimizer_switch= default; SET optimizer_switch= default;
#End of 5.3 tests #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
#
...@@ -220,7 +220,6 @@ SET character_set_connection = utf8; ...@@ -220,7 +220,6 @@ SET character_set_connection = utf8;
CREATE TABLE t1 ( a VARCHAR(1) ); CREATE TABLE t1 ( a VARCHAR(1) );
INSERT INTO t1 VALUES ('m'),('n'); INSERT INTO t1 VALUES ('m'),('n');
CREATE VIEW v1 AS SELECT 'w' ; CREATE VIEW v1 AS SELECT 'w' ;
--error ER_CANT_AGGREGATE_2COLLATIONS
SELECT * FROM t1 WHERE a < ALL ( SELECT * FROM v1 ); SELECT * FROM t1 WHERE a < ALL ( SELECT * FROM v1 );
drop view v1; drop view v1;
drop table t1; drop table t1;
...@@ -228,3 +227,30 @@ SET character_set_connection = default; ...@@ -228,3 +227,30 @@ SET character_set_connection = default;
SET optimizer_switch= default; SET optimizer_switch= default;
--echo #End of 5.3 tests --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 #
...@@ -1701,6 +1701,7 @@ Field_str::Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, ...@@ -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) if (charset_arg->state & MY_CS_BINSORT)
flags|=BINARY_FLAG; flags|=BINARY_FLAG;
field_derivation= DERIVATION_IMPLICIT; field_derivation= DERIVATION_IMPLICIT;
field_repertoire= my_charset_repertoire(charset_arg);
} }
......
...@@ -580,11 +580,12 @@ public: ...@@ -580,11 +580,12 @@ public:
{ return binary() ? &my_charset_bin : charset(); } { return binary() ? &my_charset_bin : charset(); }
virtual CHARSET_INFO *sort_charset(void) const { return charset(); } virtual CHARSET_INFO *sort_charset(void) const { return charset(); }
virtual bool has_charset(void) const { return FALSE; } virtual bool has_charset(void) const { return FALSE; }
virtual void set_charset(CHARSET_INFO *charset_arg) { }
virtual enum Derivation derivation(void) const virtual enum Derivation derivation(void) const
{ return DERIVATION_IMPLICIT; } { return DERIVATION_IMPLICIT; }
virtual uint repertoire(void) const { return MY_REPERTOIRE_UNICODE30; } 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; } virtual int set_time() { return 1; }
void set_warning(MYSQL_ERROR::enum_warning_level, unsigned int code, void set_warning(MYSQL_ERROR::enum_warning_level, unsigned int code,
int cuted_increment); int cuted_increment);
...@@ -775,8 +776,10 @@ public: ...@@ -775,8 +776,10 @@ public:
class Field_str :public Field { class Field_str :public Field {
protected: protected:
// TODO-10.2: Reuse DTCollation instead of these three members
CHARSET_INFO *field_charset; CHARSET_INFO *field_charset;
enum Derivation field_derivation; enum Derivation field_derivation;
uint field_repertoire;
public: public:
Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg, uchar null_bit_arg, utype unireg_check_arg,
...@@ -799,15 +802,15 @@ public: ...@@ -799,15 +802,15 @@ public:
int store_decimal(const my_decimal *); int store_decimal(const my_decimal *);
int store(const char *to,uint length,CHARSET_INFO *cs)=0; int store(const char *to,uint length,CHARSET_INFO *cs)=0;
uint size_of() const { return sizeof(*this); } uint size_of() const { return sizeof(*this); }
uint repertoire(void) const uint repertoire(void) const { return field_repertoire; }
{
return my_charset_repertoire(field_charset);
}
CHARSET_INFO *charset(void) const { return field_charset; } 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; } enum Derivation derivation(void) const { return field_derivation; }
virtual void set_derivation(enum Derivation derivation_arg) void set_derivation(enum Derivation derivation_arg,
{ field_derivation= derivation_arg; } uint repertoire_arg)
{
field_derivation= derivation_arg;
field_repertoire= repertoire_arg;
}
bool binary() const { return field_charset == &my_charset_bin; } bool binary() const { return field_charset == &my_charset_bin; }
uint32 max_display_length() { return field_length; } uint32 max_display_length() { return field_length; }
friend class Create_field; friend class Create_field;
......
...@@ -14586,7 +14586,8 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, ...@@ -14586,7 +14586,8 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
item->collation.collation); item->collation.collation);
else else
new_field= item->make_string_field(table); 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; break;
case DECIMAL_RESULT: case DECIMAL_RESULT:
new_field= Field_new_decimal::create_from_item(item); 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, ...@@ -14825,7 +14826,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
modify_item, convert_blob_length); modify_item, convert_blob_length);
case Item::TYPE_HOLDER: case Item::TYPE_HOLDER:
result= ((Item_type_holder *)item)->make_field_by_type(table); 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; return result;
default: // Dosen't have to be stored default: // Dosen't have to be stored
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment