From 4b5a76741eced5b3c39e8438f45d979136d58a33 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 1 Oct 2019 22:30:28 +0400 Subject: [PATCH] MDEV-20712 Wrong data type for CAST(@a AS BINARY) for a numeric variable --- mysql-test/main/ctype_latin1.result | 20 ++++++++++++++++++++ mysql-test/main/ctype_latin1.test | 18 ++++++++++++++++++ mysql-test/main/ctype_utf8.result | 20 ++++++++++++++++++++ mysql-test/main/ctype_utf8.test | 19 +++++++++++++++++++ mysql-test/main/user_var.result | 2 +- sql/item_func.cc | 24 ++++++++++++++++-------- 6 files changed, 94 insertions(+), 9 deletions(-) diff --git a/mysql-test/main/ctype_latin1.result b/mysql-test/main/ctype_latin1.result index a4925af69ae..4362ed44699 100644 --- a/mysql-test/main/ctype_latin1.result +++ b/mysql-test/main/ctype_latin1.result @@ -8889,3 +8889,23 @@ DROP TABLE t1; # # End of 10.2 tests # +# +# Start of 10.5 tests +# +# +# MDEV-20712 Wrong data type for CAST(@a AS BINARY) for a numeric variable +# +SET NAMES latin1; +SET @a=2; +CREATE OR REPLACE TABLE t1 AS SELECT CAST(1 AS BINARY), CAST(@a AS BINARY), CAST(@b:=3 AS BINARY); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `CAST(1 AS BINARY)` varbinary(1) DEFAULT NULL, + `CAST(@a AS BINARY)` varbinary(20) DEFAULT NULL, + `CAST(@b:=3 AS BINARY)` varbinary(1) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/ctype_latin1.test b/mysql-test/main/ctype_latin1.test index a556c86c016..97190caf890 100644 --- a/mysql-test/main/ctype_latin1.test +++ b/mysql-test/main/ctype_latin1.test @@ -441,3 +441,21 @@ SET NAMES latin1; --echo # --echo # End of 10.2 tests --echo # + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-20712 Wrong data type for CAST(@a AS BINARY) for a numeric variable +--echo # + +SET NAMES latin1; +SET @a=2; +CREATE OR REPLACE TABLE t1 AS SELECT CAST(1 AS BINARY), CAST(@a AS BINARY), CAST(@b:=3 AS BINARY); +SHOW CREATE TABLE t1; +DROP TABLE t1; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/mysql-test/main/ctype_utf8.result b/mysql-test/main/ctype_utf8.result index 9cb7fc0ad76..d044fe6e430 100644 --- a/mysql-test/main/ctype_utf8.result +++ b/mysql-test/main/ctype_utf8.result @@ -11323,3 +11323,23 @@ DROP TABLE t1; # # End of 10.3 tests # +# +# Start of 10.5 tests +# +# +# MDEV-20712 Wrong data type for CAST(@a AS BINARY) for a numeric variable +# +SET NAMES utf8; +SET @a=2; +CREATE OR REPLACE TABLE t1 AS SELECT CAST(1 AS BINARY), CAST(@a AS BINARY), CAST(@b:=3 AS BINARY); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `CAST(1 AS BINARY)` varbinary(1) DEFAULT NULL, + `CAST(@a AS BINARY)` varbinary(20) DEFAULT NULL, + `CAST(@b:=3 AS BINARY)` varbinary(1) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/ctype_utf8.test b/mysql-test/main/ctype_utf8.test index 26fc491c568..89243a1d23d 100644 --- a/mysql-test/main/ctype_utf8.test +++ b/mysql-test/main/ctype_utf8.test @@ -2260,3 +2260,22 @@ DROP TABLE t1; --echo # --echo # End of 10.3 tests --echo # + + +--echo # +--echo # Start of 10.5 tests +--echo # + +--echo # +--echo # MDEV-20712 Wrong data type for CAST(@a AS BINARY) for a numeric variable +--echo # + +SET NAMES utf8; +SET @a=2; +CREATE OR REPLACE TABLE t1 AS SELECT CAST(1 AS BINARY), CAST(@a AS BINARY), CAST(@b:=3 AS BINARY); +SHOW CREATE TABLE t1; +DROP TABLE t1; + +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/mysql-test/main/user_var.result b/mysql-test/main/user_var.result index b475a8ca60a..7b4c8e0b66e 100644 --- a/mysql-test/main/user_var.result +++ b/mysql-test/main/user_var.result @@ -188,7 +188,7 @@ NULL 2 set @v1=null, @v2=1, @v3=1.1, @v4=now(); select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4); coercibility(@v1) coercibility(@v2) coercibility(@v3) coercibility(@v4) -2 2 2 2 +2 5 5 2 set session @honk=99; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '@honk=99' at line 1 select @@local.max_allowed_packet; diff --git a/sql/item_func.cc b/sql/item_func.cc index b7b1dbb7432..2e4a813990f 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4490,8 +4490,10 @@ bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref) null_item= (args[0]->type() == NULL_ITEM); if (!m_var_entry->charset() || !null_item) m_var_entry->set_charset(args[0]->collation.derivation == DERIVATION_NUMERIC ? - default_charset() : args[0]->collation.collation); - collation.set(m_var_entry->charset(), DERIVATION_IMPLICIT); + &my_charset_numeric : args[0]->collation.collation); + collation.set(m_var_entry->charset(), + args[0]->collation.derivation == DERIVATION_NUMERIC ? + DERIVATION_NUMERIC : DERIVATION_IMPLICIT); switch (args[0]->result_type()) { case STRING_RESULT: case TIME_RESULT: @@ -4544,11 +4546,14 @@ Item_func_set_user_var::fix_length_and_dec() { maybe_null=args[0]->maybe_null; decimals=args[0]->decimals; - collation.set(DERIVATION_IMPLICIT); if (args[0]->collation.derivation == DERIVATION_NUMERIC) - fix_length_and_charset(args[0]->max_char_length(), default_charset()); + { + collation.set(DERIVATION_NUMERIC); + fix_length_and_charset(args[0]->max_char_length(), &my_charset_numeric); + } else { + collation.set(DERIVATION_IMPLICIT); fix_length_and_charset(args[0]->max_char_length(), args[0]->collation.collation); } @@ -4943,13 +4948,13 @@ Item_func_set_user_var::update() case REAL_RESULT: { res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal), - REAL_RESULT, default_charset(), 0); + REAL_RESULT, &my_charset_numeric, 0); break; } case INT_RESULT: { res= update_hash((void*) &save_result.vint, sizeof(save_result.vint), - INT_RESULT, default_charset(), unsigned_flag); + INT_RESULT, &my_charset_numeric, unsigned_flag); break; } case STRING_RESULT: @@ -4969,7 +4974,7 @@ Item_func_set_user_var::update() else res= update_hash((void*) save_result.vdec, sizeof(my_decimal), DECIMAL_RESULT, - default_charset(), 0); + &my_charset_numeric, 0); break; } case ROW_RESULT: @@ -5408,23 +5413,26 @@ bool Item_func_get_user_var::fix_length_and_dec() { unsigned_flag= m_var_entry->unsigned_flag; max_length= (uint32)m_var_entry->length; - collation.set(m_var_entry->charset(), DERIVATION_IMPLICIT); switch (m_var_entry->type) { case REAL_RESULT: + collation.set(&my_charset_numeric, DERIVATION_NUMERIC); fix_char_length(DBL_DIG + 8); set_handler(&type_handler_double); break; case INT_RESULT: + collation.set(&my_charset_numeric, DERIVATION_NUMERIC); fix_char_length(MAX_BIGINT_WIDTH); decimals=0; set_handler(unsigned_flag ? &type_handler_ulonglong : &type_handler_slonglong); break; case STRING_RESULT: + collation.set(m_var_entry->charset(), DERIVATION_IMPLICIT); max_length= MAX_BLOB_WIDTH - 1; set_handler(&type_handler_long_blob); break; case DECIMAL_RESULT: + collation.set(&my_charset_numeric, DERIVATION_NUMERIC); fix_char_length(DECIMAL_MAX_STR_LENGTH); decimals= DECIMAL_MAX_SCALE; set_handler(&type_handler_newdecimal);