mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Fix for bug #20695: Charset introducer overrides charset definition for column.
- if there are two character set definitions in the column declaration, we replace the first one with the second one as we store both in the LEX->charset slot. Add a separate slot to the LEX structure to store underscore charset. - convert default values to the column charset of STRING, VARSTRING fields if necessary as well. mysql-test/r/ctype_recoding.result: Fix for bug #20695: Charset introducer overrides charset definition for column. - test result. mysql-test/t/ctype_recoding.test: Fix for bug #20695: Charset introducer overrides charset definition for column. - test case. sql/sql_lex.cc: Fix for bug #20695: Charset introducer overrides charset definition for column. - LEX->underscore_charset introduced to store UNDERSCORE_CHARSET sql/sql_lex.h: Fix for bug #20695: Charset introducer overrides charset definition for column. - LEX->underscore_charset introduced to store UNDERSCORE_CHARSET sql/sql_table.cc: Fix for bug #20695: Charset introducer overrides charset definition for column. - convert default values to the column charset of VARSTRING, STRING, ENUM, SET fields if necessary. sql/sql_yacc.yy: Fix for bug #20695: Charset introducer overrides charset definition for column. - LEX->underscore_charset introduced to store UNDERSCORE_CHARSET
This commit is contained in:
@ -247,3 +247,14 @@ lpad(c1,3,'
|
|||||||
select rpad(c1,3,'<27>'), rpad('<27>',3,c1) from t1;
|
select rpad(c1,3,'<27>'), rpad('<27>',3,c1) from t1;
|
||||||
rpad(c1,3,'<27>') rpad('<27>',3,c1)
|
rpad(c1,3,'<27>') rpad('<27>',3,c1)
|
||||||
<EFBFBD><EFBFBD><EFBFBD> <09><><EFBFBD>
|
<EFBFBD><EFBFBD><EFBFBD> <09><><EFBFBD>
|
||||||
|
drop table t1;
|
||||||
|
set names koi8r;
|
||||||
|
create table t1(a char character set cp1251 default _koi8r 0xFF);
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`a` char(1) character set cp1251 default '<27>'
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
drop table t1;
|
||||||
|
create table t1(a char character set latin1 default _cp1251 0xFF);
|
||||||
|
ERROR 42000: Invalid default value for 'a'
|
||||||
|
@ -186,5 +186,17 @@ select rpad(c1,3,'
|
|||||||
# TODO
|
# TODO
|
||||||
#select case c1 when '<27>' then '<27>' when '<27>' then '<27>' else 'c' end from t1;
|
#select case c1 when '<27>' then '<27>' when '<27>' then '<27>' else 'c' end from t1;
|
||||||
#select export_set(5,c1,'<27>'), export_set(5,'<27>',c1) from t1;
|
#select export_set(5,c1,'<27>'), export_set(5,'<27>',c1) from t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug 20695: problem with field default value's character set
|
||||||
|
#
|
||||||
|
|
||||||
|
set names koi8r;
|
||||||
|
create table t1(a char character set cp1251 default _koi8r 0xFF);
|
||||||
|
show create table t1;
|
||||||
|
drop table t1;
|
||||||
|
--error 1067
|
||||||
|
create table t1(a char character set latin1 default _cp1251 0xFF);
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
@ -643,8 +643,9 @@ int yylex(void *arg, void *yythd)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if ((yylval->lex_str.str[0]=='_') &&
|
if ((yylval->lex_str.str[0]=='_') &&
|
||||||
(lex->charset=get_charset_by_csname(yylval->lex_str.str+1,
|
(lex->underscore_charset=
|
||||||
MY_CS_PRIMARY,MYF(0))))
|
get_charset_by_csname(yylval->lex_str.str + 1,
|
||||||
|
MY_CS_PRIMARY,MYF(0))))
|
||||||
return(UNDERSCORE_CHARSET);
|
return(UNDERSCORE_CHARSET);
|
||||||
return(result_state); // IDENT or IDENT_QUOTED
|
return(result_state); // IDENT or IDENT_QUOTED
|
||||||
|
|
||||||
|
@ -613,7 +613,7 @@ typedef struct st_lex
|
|||||||
LEX_USER *grant_user;
|
LEX_USER *grant_user;
|
||||||
gptr yacc_yyss,yacc_yyvs;
|
gptr yacc_yyss,yacc_yyvs;
|
||||||
THD *thd;
|
THD *thd;
|
||||||
CHARSET_INFO *charset;
|
CHARSET_INFO *charset, *underscore_charset;
|
||||||
|
|
||||||
List<key_part_spec> col_list;
|
List<key_part_spec> col_list;
|
||||||
List<key_part_spec> ref_list;
|
List<key_part_spec> ref_list;
|
||||||
|
@ -516,6 +516,40 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Convert the default value character
|
||||||
|
set into the column character set if necessary.
|
||||||
|
*/
|
||||||
|
if (sql_field->def &&
|
||||||
|
savecs != sql_field->def->collation.collation &&
|
||||||
|
(sql_field->sql_type == FIELD_TYPE_VAR_STRING ||
|
||||||
|
sql_field->sql_type == FIELD_TYPE_STRING ||
|
||||||
|
sql_field->sql_type == FIELD_TYPE_SET ||
|
||||||
|
sql_field->sql_type == FIELD_TYPE_ENUM))
|
||||||
|
{
|
||||||
|
Item_arena backup_arena;
|
||||||
|
bool need_to_change_arena=
|
||||||
|
!thd->current_arena->is_conventional_execution();
|
||||||
|
if (need_to_change_arena)
|
||||||
|
{
|
||||||
|
/* Assert that we don't do that at every PS execute */
|
||||||
|
DBUG_ASSERT(thd->current_arena->is_first_stmt_execute());
|
||||||
|
thd->set_n_backup_item_arena(thd->current_arena, &backup_arena);
|
||||||
|
}
|
||||||
|
|
||||||
|
sql_field->def= sql_field->def->safe_charset_converter(savecs);
|
||||||
|
|
||||||
|
if (need_to_change_arena)
|
||||||
|
thd->restore_backup_item_arena(thd->current_arena, &backup_arena);
|
||||||
|
|
||||||
|
if (sql_field->def == NULL)
|
||||||
|
{
|
||||||
|
/* Could not convert */
|
||||||
|
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (sql_field->sql_type == FIELD_TYPE_SET ||
|
if (sql_field->sql_type == FIELD_TYPE_SET ||
|
||||||
sql_field->sql_type == FIELD_TYPE_ENUM)
|
sql_field->sql_type == FIELD_TYPE_ENUM)
|
||||||
{
|
{
|
||||||
@ -580,35 +614,6 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
sql_field->interval_list.empty(); // Don't need interval_list anymore
|
sql_field->interval_list.empty(); // Don't need interval_list anymore
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Convert the default value from client character
|
|
||||||
set into the column character set if necessary.
|
|
||||||
*/
|
|
||||||
if (sql_field->def && cs != sql_field->def->collation.collation)
|
|
||||||
{
|
|
||||||
Item_arena backup_arena;
|
|
||||||
bool need_to_change_arena=
|
|
||||||
!thd->current_arena->is_conventional_execution();
|
|
||||||
if (need_to_change_arena)
|
|
||||||
{
|
|
||||||
/* Asser that we don't do that at every PS execute */
|
|
||||||
DBUG_ASSERT(thd->current_arena->is_first_stmt_execute());
|
|
||||||
thd->set_n_backup_item_arena(thd->current_arena, &backup_arena);
|
|
||||||
}
|
|
||||||
|
|
||||||
sql_field->def= sql_field->def->safe_charset_converter(cs);
|
|
||||||
|
|
||||||
if (need_to_change_arena)
|
|
||||||
thd->restore_backup_item_arena(thd->current_arena, &backup_arena);
|
|
||||||
|
|
||||||
if (sql_field->def == NULL)
|
|
||||||
{
|
|
||||||
/* Could not convert */
|
|
||||||
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
|
|
||||||
DBUG_RETURN(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sql_field->sql_type == FIELD_TYPE_SET)
|
if (sql_field->sql_type == FIELD_TYPE_SET)
|
||||||
{
|
{
|
||||||
if (sql_field->def != NULL)
|
if (sql_field->def != NULL)
|
||||||
|
@ -4896,7 +4896,7 @@ text_literal:
|
|||||||
| NCHAR_STRING
|
| NCHAR_STRING
|
||||||
{ $$= new Item_string($1.str,$1.length,national_charset_info); }
|
{ $$= new Item_string($1.str,$1.length,national_charset_info); }
|
||||||
| UNDERSCORE_CHARSET TEXT_STRING
|
| UNDERSCORE_CHARSET TEXT_STRING
|
||||||
{ $$ = new Item_string($2.str,$2.length,Lex->charset); }
|
{ $$ = new Item_string($2.str,$2.length,Lex->underscore_charset); }
|
||||||
| text_literal TEXT_STRING_literal
|
| text_literal TEXT_STRING_literal
|
||||||
{ ((Item_string*) $1)->append($2.str,$2.length); }
|
{ ((Item_string*) $1)->append($2.str,$2.length); }
|
||||||
;
|
;
|
||||||
@ -4963,7 +4963,7 @@ literal:
|
|||||||
(String*) 0;
|
(String*) 0;
|
||||||
$$= new Item_string(str ? str->ptr() : "",
|
$$= new Item_string(str ? str->ptr() : "",
|
||||||
str ? str->length() : 0,
|
str ? str->length() : 0,
|
||||||
Lex->charset);
|
Lex->underscore_charset);
|
||||||
}
|
}
|
||||||
| DATE_SYM text_literal { $$ = $2; }
|
| DATE_SYM text_literal { $$ = $2; }
|
||||||
| TIME_SYM text_literal { $$ = $2; }
|
| TIME_SYM text_literal { $$ = $2; }
|
||||||
|
Reference in New Issue
Block a user