Commit 7614eb0d authored by unknown's avatar unknown
Browse files

Bug#21505 Create view - illegal mix of collation for operation 'UNION'

  
  The problem was that any VIEW columns had always implicit derivation.
  Fix: derivation is now copied from the original expression
  given in VIEW definition.
  For example:
  - a VIEW column which comes from a string constant
    in CREATE VIEW definition have now coercible derivation.
  - a VIEW column having COLLATE clause
    in CREATE VIEW definition have now explicit derivation.


mysql-test/r/ctype_utf8.result:
  Adding test case
mysql-test/t/ctype_utf8.test:
  Adding test case
sql/field.cc:
  Copying derivation from item to field.
sql/field.h:
  Adding derivation and methods to get/set it into Field.
sql/item.cc:
  Copying derivation from field to item.
sql/item.h:
  Moving "enum Derivation" declaration from item.h to mysql_priv.h
sql/mysql_priv.h:
  Moving "enum Derivation" declaration from item.h to mysql_priv.h
sql/sql_select.cc:
  Copying derivation from item to field in
  create_tmp_field_from_item() and create_tmp_field().
parent a39b8a06
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -1536,6 +1536,32 @@ set @a:=null;
execute my_stmt using @a;
a	b
drop table if exists t1;
drop table if exists t1;
drop view if exists v1, v2;
set names utf8;
create table t1(col1 varchar(12) character set utf8 collate utf8_unicode_ci);
insert into t1 values('t1_val');
create view v1 as select 'v1_val' as col1;
select coercibility(col1), collation(col1) from v1;
coercibility(col1)	collation(col1)
4	utf8_general_ci
create view v2 as select col1 from v1 union select col1 from t1;
select coercibility(col1), collation(col1)from v2;
coercibility(col1)	collation(col1)
2	utf8_unicode_ci
2	utf8_unicode_ci
drop view v1, v2;
create view v1 as select 'v1_val' collate utf8_swedish_ci as col1;
select coercibility(col1), collation(col1) from v1;
coercibility(col1)	collation(col1)
0	utf8_swedish_ci
create view v2 as select col1 from v1 union select col1 from t1;
select coercibility(col1), collation(col1) from v2;
coercibility(col1)	collation(col1)
0	utf8_swedish_ci
0	utf8_swedish_ci
drop view v1, v2;
drop table t1;
CREATE TABLE t1 (
colA int(11) NOT NULL,
colB varchar(255) character set utf8 NOT NULL,
+24 −0
Original line number Diff line number Diff line
@@ -1228,6 +1228,30 @@ set @a:=null;
execute my_stmt using @a;
drop table if exists t1;


#
# Bug#21505 Create view - illegal mix of collation for operation 'UNION'
#
--disable_warnings
drop table if exists t1;
drop view if exists v1, v2;
--enable_warnings
set names utf8;
create table t1(col1 varchar(12) character set utf8 collate utf8_unicode_ci);
insert into t1 values('t1_val');
create view v1 as select 'v1_val' as col1;
select coercibility(col1), collation(col1) from v1;
create view v2 as select col1 from v1 union select col1 from t1;
select coercibility(col1), collation(col1)from v2;
drop view v1, v2;
create view v1 as select 'v1_val' collate utf8_swedish_ci as col1;
select coercibility(col1), collation(col1) from v1;
create view v2 as select col1 from v1 union select col1 from t1;
select coercibility(col1), collation(col1) from v2;
drop view v1, v2;
drop table t1;


#
# Bug#19960: Inconsistent results when joining
# InnoDB tables using partial UTF8 indexes
+1 −0
Original line number Diff line number Diff line
@@ -1399,6 +1399,7 @@ Field_str::Field_str(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
  field_charset=charset;
  if (charset->state & MY_CS_BINSORT)
    flags|=BINARY_FLAG;
  field_derivation= DERIVATION_IMPLICIT;
}


+7 −0
Original line number Diff line number Diff line
@@ -302,6 +302,9 @@ class Field
  virtual CHARSET_INFO *sort_charset(void) const { return charset(); }
  virtual bool has_charset(void) const { return FALSE; }
  virtual void set_charset(CHARSET_INFO *charset) { }
  virtual enum Derivation derivation(void) const
  { return DERIVATION_IMPLICIT; }
  virtual void set_derivation(enum Derivation derivation) { }
  bool set_warning(MYSQL_ERROR::enum_warning_level, unsigned int code,
                   int cuted_increment);
  bool check_int(const char *str, int length, const char *int_end,
@@ -373,6 +376,7 @@ class Field_num :public Field {
class Field_str :public Field {
protected:
  CHARSET_INFO *field_charset;
  enum Derivation field_derivation;
public:
  Field_str(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
	    uchar null_bit_arg, utype unireg_check_arg,
@@ -387,6 +391,9 @@ class Field_str :public Field {
  uint size_of() const { return sizeof(*this); }
  CHARSET_INFO *charset(void) const { return field_charset; }
  void set_charset(CHARSET_INFO *charset) { field_charset=charset; }
  enum Derivation derivation(void) const { return field_derivation; }
  virtual void set_derivation(enum Derivation derivation_arg)
  { field_derivation= derivation_arg; }
  bool binary() const { return field_charset == &my_charset_bin; }
  uint32 max_length() { return field_length; }
  friend class create_field;
+1 −1
Original line number Diff line number Diff line
@@ -1622,7 +1622,7 @@ void Item_field::set_field(Field *field_par)
  db_name= field_par->table->s->db;
  alias_name_used= field_par->table->alias_name_used;
  unsigned_flag=test(field_par->flags & UNSIGNED_FLAG);
  collation.set(field_par->charset(), DERIVATION_IMPLICIT);
  collation.set(field_par->charset(), field_par->derivation());
  fixed= 1;
}

Loading