Skip to content

Commit df14488

Browse files
author
Alexander Barkov
committed
MDEV-10181 Illegal mix of collation for a field and an ASCII string as a view field
1 parent 7adf04e commit df14488

File tree

5 files changed

+76
-13
lines changed

5 files changed

+76
-13
lines changed

mysql-test/r/ctype_recoding.result

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,40 @@ CREATE TABLE t1 ( a VARCHAR(1) );
277277
INSERT INTO t1 VALUES ('m'),('n');
278278
CREATE VIEW v1 AS SELECT 'w' ;
279279
SELECT * FROM t1 WHERE a < ALL ( SELECT * FROM v1 );
280-
ERROR HY000: Illegal mix of collations (utf8_general_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '<='
280+
a
281+
m
282+
n
281283
drop view v1;
282284
drop table t1;
283285
SET character_set_connection = default;
284286
SET optimizer_switch= default;
285287
#End of 5.3 tests
288+
#
289+
# Start of 5.5 tests
290+
#
291+
#
292+
# MDEV-10181 Illegal mix of collation for a field and an ASCII string as a view field
293+
#
294+
SET NAMES utf8;
295+
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1);
296+
INSERT INTO t1 VALUES ('A'),('a'),('B'),('b');
297+
CREATE VIEW v1 AS SELECT 'a';
298+
SELECT * FROM v1,t1 where t1.a=v1.a;
299+
a a
300+
a A
301+
a a
302+
DROP VIEW v1;
303+
DROP TABLE t1;
304+
SET NAMES utf8;
305+
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1);
306+
INSERT INTO t1 VALUES ('a'),('b'),('c');
307+
CREATE VIEW v1 AS SELECT 'a' AS a UNION SELECT 'b';
308+
SELECT * FROM v1,t1 WHERE t1.a=v1.a;
309+
a a
310+
a a
311+
b b
312+
DROP VIEW v1;
313+
DROP TABLE t1;
314+
#
315+
# End of 5.5 tests
316+
#

mysql-test/t/ctype_recoding.test

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,11 +220,37 @@ SET character_set_connection = utf8;
220220
CREATE TABLE t1 ( a VARCHAR(1) );
221221
INSERT INTO t1 VALUES ('m'),('n');
222222
CREATE VIEW v1 AS SELECT 'w' ;
223-
--error ER_CANT_AGGREGATE_2COLLATIONS
224223
SELECT * FROM t1 WHERE a < ALL ( SELECT * FROM v1 );
225224
drop view v1;
226225
drop table t1;
227226
SET character_set_connection = default;
228227
SET optimizer_switch= default;
229228

230229
--echo #End of 5.3 tests
230+
231+
--echo #
232+
--echo # Start of 5.5 tests
233+
--echo #
234+
235+
--echo #
236+
--echo # MDEV-10181 Illegal mix of collation for a field and an ASCII string as a view field
237+
--echo #
238+
SET NAMES utf8;
239+
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1);
240+
INSERT INTO t1 VALUES ('A'),('a'),('B'),('b');
241+
CREATE VIEW v1 AS SELECT 'a';
242+
SELECT * FROM v1,t1 where t1.a=v1.a;
243+
DROP VIEW v1;
244+
DROP TABLE t1;
245+
246+
SET NAMES utf8;
247+
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1);
248+
INSERT INTO t1 VALUES ('a'),('b'),('c');
249+
CREATE VIEW v1 AS SELECT 'a' AS a UNION SELECT 'b';
250+
SELECT * FROM v1,t1 WHERE t1.a=v1.a;
251+
DROP VIEW v1;
252+
DROP TABLE t1;
253+
254+
--echo #
255+
--echo # End of 5.5 tests
256+
--echo #

sql/field.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,6 +1701,7 @@ Field_str::Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
17011701
if (charset_arg->state & MY_CS_BINSORT)
17021702
flags|=BINARY_FLAG;
17031703
field_derivation= DERIVATION_IMPLICIT;
1704+
field_repertoire= my_charset_repertoire(charset_arg);
17041705
}
17051706

17061707

sql/field.h

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -580,11 +580,12 @@ class Field
580580
{ return binary() ? &my_charset_bin : charset(); }
581581
virtual CHARSET_INFO *sort_charset(void) const { return charset(); }
582582
virtual bool has_charset(void) const { return FALSE; }
583-
virtual void set_charset(CHARSET_INFO *charset_arg) { }
584583
virtual enum Derivation derivation(void) const
585584
{ return DERIVATION_IMPLICIT; }
586585
virtual uint repertoire(void) const { return MY_REPERTOIRE_UNICODE30; }
587-
virtual void set_derivation(enum Derivation derivation_arg) { }
586+
virtual void set_derivation(enum Derivation derivation_arg,
587+
uint repertoire_arg)
588+
{ }
588589
virtual int set_time() { return 1; }
589590
void set_warning(MYSQL_ERROR::enum_warning_level, unsigned int code,
590591
int cuted_increment);
@@ -775,8 +776,10 @@ class Field_num :public Field {
775776

776777
class Field_str :public Field {
777778
protected:
779+
// TODO-10.2: Reuse DTCollation instead of these three members
778780
CHARSET_INFO *field_charset;
779781
enum Derivation field_derivation;
782+
uint field_repertoire;
780783
public:
781784
Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
782785
uchar null_bit_arg, utype unireg_check_arg,
@@ -799,15 +802,15 @@ class Field_str :public Field {
799802
int store_decimal(const my_decimal *);
800803
int store(const char *to,uint length,CHARSET_INFO *cs)=0;
801804
uint size_of() const { return sizeof(*this); }
802-
uint repertoire(void) const
803-
{
804-
return my_charset_repertoire(field_charset);
805-
}
805+
uint repertoire(void) const { return field_repertoire; }
806806
CHARSET_INFO *charset(void) const { return field_charset; }
807-
void set_charset(CHARSET_INFO *charset_arg) { field_charset= charset_arg; }
808807
enum Derivation derivation(void) const { return field_derivation; }
809-
virtual void set_derivation(enum Derivation derivation_arg)
810-
{ field_derivation= derivation_arg; }
808+
void set_derivation(enum Derivation derivation_arg,
809+
uint repertoire_arg)
810+
{
811+
field_derivation= derivation_arg;
812+
field_repertoire= repertoire_arg;
813+
}
811814
bool binary() const { return field_charset == &my_charset_bin; }
812815
uint32 max_display_length() { return field_length; }
813816
friend class Create_field;

sql/sql_select.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14586,7 +14586,8 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
1458614586
item->collation.collation);
1458714587
else
1458814588
new_field= item->make_string_field(table);
14589-
new_field->set_derivation(item->collation.derivation);
14589+
new_field->set_derivation(item->collation.derivation,
14590+
item->collation.repertoire);
1459014591
break;
1459114592
case DECIMAL_RESULT:
1459214593
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,
1482514826
modify_item, convert_blob_length);
1482614827
case Item::TYPE_HOLDER:
1482714828
result= ((Item_type_holder *)item)->make_field_by_type(table);
14828-
result->set_derivation(item->collation.derivation);
14829+
result->set_derivation(item->collation.derivation,
14830+
item->collation.repertoire);
1482914831
return result;
1483014832
default: // Dosen't have to be stored
1483114833
return 0;

0 commit comments

Comments
 (0)