summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2016-06-10 15:50:19 +0400
committerAlexander Barkov <bar@mariadb.org>2016-06-10 15:50:19 +0400
commitdf1448801ceba4d8d8a02db83ba022fea9e6755d (patch)
treeae0b4ef49adccf5bae7c16168dd9db61364bfc29
parent7adf04e237c41d323b5181c108e7babed3c015fa (diff)
downloadmariadb-git-df1448801ceba4d8d8a02db83ba022fea9e6755d.tar.gz
MDEV-10181 Illegal mix of collation for a field and an ASCII string as a view field
-rw-r--r--mysql-test/r/ctype_recoding.result33
-rw-r--r--mysql-test/t/ctype_recoding.test28
-rw-r--r--sql/field.cc1
-rw-r--r--sql/field.h21
-rw-r--r--sql/sql_select.cc6
5 files changed, 76 insertions, 13 deletions
diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result
index c84da0d7496..2555749fa8c 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 ee07ef24def..81c04fc9c30 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 ceea0893a3f..a0686fb2f19 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 f761aa8d3ea..fdf229edfbb 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -580,11 +580,12 @@ public:
{ 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 @@ public:
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 @@ public:
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 91aecadfd0a..613cbb2e086 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;