MDEV-6688 Illegal mix of collation with bit string B'01100001'
This commit is contained in:
parent
36f50be970
commit
e42f4e3199
@ -5996,5 +5996,17 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
DEALLOCATE PREPARE stmt;
|
DEALLOCATE PREPARE stmt;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-6688 Illegal mix of collation with bit string B'01100001'
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1, b INT);
|
||||||
|
INSERT INTO t1 VALUES ('a',1);
|
||||||
|
SELECT CONCAT(a, IF(b>10, _utf8 X'61', _utf8 X'61')) FROM t1;
|
||||||
|
CONCAT(a, IF(b>10, _utf8 X'61', _utf8 X'61'))
|
||||||
|
aa
|
||||||
|
SELECT CONCAT(a, IF(b>10, _utf8 X'61', _utf8 B'01100001')) FROM t1;
|
||||||
|
CONCAT(a, IF(b>10, _utf8 X'61', _utf8 B'01100001'))
|
||||||
|
aa
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# End of 10.0 tests
|
# End of 10.0 tests
|
||||||
#
|
#
|
||||||
|
@ -1710,6 +1710,16 @@ EXECUTE stmt USING @arg;
|
|||||||
DEALLOCATE PREPARE stmt;
|
DEALLOCATE PREPARE stmt;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-6688 Illegal mix of collation with bit string B'01100001'
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1, b INT);
|
||||||
|
INSERT INTO t1 VALUES ('a',1);
|
||||||
|
SELECT CONCAT(a, IF(b>10, _utf8 X'61', _utf8 X'61')) FROM t1;
|
||||||
|
SELECT CONCAT(a, IF(b>10, _utf8 X'61', _utf8 B'01100001')) FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.0 tests
|
--echo # End of 10.0 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
52
sql/item.h
52
sql/item.h
@ -2711,6 +2711,23 @@ public:
|
|||||||
|
|
||||||
class Item_string :public Item_basic_constant
|
class Item_string :public Item_basic_constant
|
||||||
{
|
{
|
||||||
|
bool m_cs_specified;
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
Set the value of m_cs_specified attribute.
|
||||||
|
|
||||||
|
m_cs_specified attribute shows whether character-set-introducer was
|
||||||
|
explicitly specified in the original query for this text literal or
|
||||||
|
not. The attribute makes sense (is used) only for views.
|
||||||
|
|
||||||
|
This operation is to be called from the parser during parsing an input
|
||||||
|
query.
|
||||||
|
*/
|
||||||
|
inline void set_cs_specified(bool cs_specified)
|
||||||
|
{
|
||||||
|
m_cs_specified= cs_specified;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Item_string(const char *str,uint length,
|
Item_string(const char *str,uint length,
|
||||||
CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE,
|
CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE,
|
||||||
@ -2860,21 +2877,6 @@ public:
|
|||||||
return m_cs_specified;
|
return m_cs_specified;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Set the value of m_cs_specified attribute.
|
|
||||||
|
|
||||||
m_cs_specified attribute shows whether character-set-introducer was
|
|
||||||
explicitly specified in the original query for this text literal or
|
|
||||||
not. The attribute makes sense (is used) only for views.
|
|
||||||
|
|
||||||
This operation is to be called from the parser during parsing an input
|
|
||||||
query.
|
|
||||||
*/
|
|
||||||
inline void set_cs_specified(bool cs_specified)
|
|
||||||
{
|
|
||||||
m_cs_specified= cs_specified;
|
|
||||||
}
|
|
||||||
|
|
||||||
String *check_well_formed_result(bool send_error)
|
String *check_well_formed_result(bool send_error)
|
||||||
{ return Item::check_well_formed_result(&str_value, send_error); }
|
{ return Item::check_well_formed_result(&str_value, send_error); }
|
||||||
|
|
||||||
@ -2906,8 +2908,24 @@ public:
|
|||||||
}
|
}
|
||||||
return MYSQL_TYPE_STRING; // Not a temporal literal
|
return MYSQL_TYPE_STRING; // Not a temporal literal
|
||||||
}
|
}
|
||||||
private:
|
};
|
||||||
bool m_cs_specified;
|
|
||||||
|
|
||||||
|
class Item_string_with_introducer :public Item_string
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Item_string_with_introducer(const char *str, uint length, CHARSET_INFO *cs)
|
||||||
|
:Item_string(str, length, cs)
|
||||||
|
{
|
||||||
|
set_repertoire_from_value();
|
||||||
|
set_cs_specified(true);
|
||||||
|
}
|
||||||
|
Item_string_with_introducer(const String *str, CHARSET_INFO *tocs)
|
||||||
|
:Item_string(str->ptr(), str->length(), tocs)
|
||||||
|
{
|
||||||
|
set_repertoire_from_value();
|
||||||
|
set_cs_specified(true);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1648,7 +1648,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
|
|
||||||
%type <lex_str>
|
%type <lex_str>
|
||||||
IDENT IDENT_QUOTED TEXT_STRING DECIMAL_NUM FLOAT_NUM NUM LONG_NUM
|
IDENT IDENT_QUOTED TEXT_STRING DECIMAL_NUM FLOAT_NUM NUM LONG_NUM
|
||||||
HEX_NUM HEX_STRING hex_num_or_string
|
HEX_NUM HEX_STRING
|
||||||
LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text
|
LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text
|
||||||
IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
|
IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
|
||||||
NCHAR_STRING opt_component key_cache_name
|
NCHAR_STRING opt_component key_cache_name
|
||||||
@ -1666,7 +1666,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|||||||
remember_name remember_end opt_db text_or_password
|
remember_name remember_end opt_db text_or_password
|
||||||
|
|
||||||
%type <string>
|
%type <string>
|
||||||
text_string opt_gconcat_separator
|
text_string hex_or_bin_String opt_gconcat_separator
|
||||||
|
|
||||||
%type <num>
|
%type <num>
|
||||||
type type_with_opt_collate int_type real_type order_dir lock_option
|
type type_with_opt_collate int_type real_type order_dir lock_option
|
||||||
@ -6517,11 +6517,6 @@ now_or_signed_literal:
|
|||||||
{ $$=$1; }
|
{ $$=$1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
hex_num_or_string:
|
|
||||||
HEX_NUM {}
|
|
||||||
| HEX_STRING {}
|
|
||||||
;
|
|
||||||
|
|
||||||
charset:
|
charset:
|
||||||
CHAR_SYM SET {}
|
CHAR_SYM SET {}
|
||||||
| CHARSET {}
|
| CHARSET {}
|
||||||
@ -13253,14 +13248,10 @@ text_literal:
|
|||||||
}
|
}
|
||||||
| UNDERSCORE_CHARSET TEXT_STRING
|
| UNDERSCORE_CHARSET TEXT_STRING
|
||||||
{
|
{
|
||||||
Item_string *str= new (thd->mem_root) Item_string($2.str,
|
$$= new (thd->mem_root) Item_string_with_introducer($2.str,
|
||||||
$2.length, $1);
|
$2.length, $1);
|
||||||
if (str == NULL)
|
if ($$ == NULL)
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
str->set_repertoire_from_value();
|
|
||||||
str->set_cs_specified(TRUE);
|
|
||||||
|
|
||||||
$$= str;
|
|
||||||
}
|
}
|
||||||
| text_literal TEXT_STRING_literal
|
| text_literal TEXT_STRING_literal
|
||||||
{
|
{
|
||||||
@ -13289,7 +13280,12 @@ text_string:
|
|||||||
if ($$ == NULL)
|
if ($$ == NULL)
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| HEX_NUM
|
| hex_or_bin_String { $$= $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
hex_or_bin_String:
|
||||||
|
HEX_NUM
|
||||||
{
|
{
|
||||||
Item *tmp= new (thd->mem_root) Item_hex_hybrid($1.str, $1.length);
|
Item *tmp= new (thd->mem_root) Item_hex_hybrid($1.str, $1.length);
|
||||||
if (tmp == NULL)
|
if (tmp == NULL)
|
||||||
@ -13394,60 +13390,12 @@ literal:
|
|||||||
if ($$ == NULL)
|
if ($$ == NULL)
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| UNDERSCORE_CHARSET hex_num_or_string
|
| UNDERSCORE_CHARSET hex_or_bin_String
|
||||||
{
|
{
|
||||||
Item *tmp= new (thd->mem_root) Item_hex_string($2.str, $2.length);
|
Item_string_with_introducer *item_str;
|
||||||
if (tmp == NULL)
|
item_str= new (thd->mem_root) Item_string_with_introducer($2, $1);
|
||||||
|
if (!item_str || !item_str->check_well_formed_result(true))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
/*
|
|
||||||
it is OK only emulate fix_fieds, because we need only
|
|
||||||
value of constant
|
|
||||||
*/
|
|
||||||
tmp->quick_fix_field();
|
|
||||||
String *str= tmp->val_str((String*) 0);
|
|
||||||
|
|
||||||
Item_string *item_str;
|
|
||||||
item_str= new (thd->mem_root)
|
|
||||||
Item_string(NULL, /* name will be set in select_item */
|
|
||||||
str ? str->ptr() : "",
|
|
||||||
str ? str->length() : 0,
|
|
||||||
$1);
|
|
||||||
if (!item_str ||
|
|
||||||
!item_str->check_well_formed_result(true))
|
|
||||||
{
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
item_str->set_repertoire_from_value();
|
|
||||||
item_str->set_cs_specified(TRUE);
|
|
||||||
|
|
||||||
$$= item_str;
|
|
||||||
}
|
|
||||||
| UNDERSCORE_CHARSET BIN_NUM
|
|
||||||
{
|
|
||||||
Item *tmp= new (thd->mem_root) Item_bin_string($2.str, $2.length);
|
|
||||||
if (tmp == NULL)
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
/*
|
|
||||||
it is OK only emulate fix_fieds, because we need only
|
|
||||||
value of constant
|
|
||||||
*/
|
|
||||||
tmp->quick_fix_field();
|
|
||||||
String *str= tmp->val_str((String*) 0);
|
|
||||||
|
|
||||||
Item_string *item_str;
|
|
||||||
item_str= new (thd->mem_root)
|
|
||||||
Item_string(NULL, /* name will be set in select_item */
|
|
||||||
str ? str->ptr() : "",
|
|
||||||
str ? str->length() : 0,
|
|
||||||
$1);
|
|
||||||
if (!item_str ||
|
|
||||||
!item_str->check_well_formed_result(true))
|
|
||||||
{
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
item_str->set_cs_specified(TRUE);
|
|
||||||
|
|
||||||
$$= item_str;
|
$$= item_str;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user