Commit e165845d authored by bar@bar.mysql.r18.ru's avatar bar@bar.mysql.r18.ru

sys_var_collation is now abstract class

Two separate classes sys_var_client_collation and sys_var_literal_collation have been added
for "literal_collation" and "client_collation" variables.
parent e0caf3f2
...@@ -4567,6 +4567,8 @@ static void set_options(void) ...@@ -4567,6 +4567,8 @@ static void set_options(void)
/* Set default values for some variables */ /* Set default values for some variables */
global_system_variables.convert_result_charset= TRUE; global_system_variables.convert_result_charset= TRUE;
global_system_variables.client_collation= default_charset_info;
global_system_variables.literal_collation= default_charset_info;
global_system_variables.table_type= DB_TYPE_MYISAM; global_system_variables.table_type= DB_TYPE_MYISAM;
global_system_variables.tx_isolation= ISO_REPEATABLE_READ; global_system_variables.tx_isolation= ISO_REPEATABLE_READ;
global_system_variables.select_limit= (ulonglong) HA_POS_ERROR; global_system_variables.select_limit= (ulonglong) HA_POS_ERROR;
......
...@@ -805,7 +805,7 @@ bool Protocol_simple::store(float from, uint32 decimals, String *buffer) ...@@ -805,7 +805,7 @@ bool Protocol_simple::store(float from, uint32 decimals, String *buffer)
field_types[field_pos] == MYSQL_TYPE_FLOAT); field_types[field_pos] == MYSQL_TYPE_FLOAT);
field_pos++; field_pos++;
#endif #endif
buffer->set((double) from, decimals, thd->variables.thd_charset); buffer->set((double) from, decimals, thd->charset());
return net_store_data((char*) buffer->ptr(), buffer->length()); return net_store_data((char*) buffer->ptr(), buffer->length());
} }
...@@ -817,7 +817,7 @@ bool Protocol_simple::store(double from, uint32 decimals, String *buffer) ...@@ -817,7 +817,7 @@ bool Protocol_simple::store(double from, uint32 decimals, String *buffer)
field_types[field_pos] == MYSQL_TYPE_DOUBLE); field_types[field_pos] == MYSQL_TYPE_DOUBLE);
field_pos++; field_pos++;
#endif #endif
buffer->set(from, decimals, thd->variables.thd_charset); buffer->set(from, decimals, thd->charset());
return net_store_data((char*) buffer->ptr(), buffer->length()); return net_store_data((char*) buffer->ptr(), buffer->length());
} }
......
...@@ -133,6 +133,7 @@ sys_var_thd_ulong sys_join_buffer_size("join_buffer_size", ...@@ -133,6 +133,7 @@ sys_var_thd_ulong sys_join_buffer_size("join_buffer_size",
sys_var_ulonglong_ptr sys_key_buffer_size("key_buffer_size", sys_var_ulonglong_ptr sys_key_buffer_size("key_buffer_size",
&keybuff_size, &keybuff_size,
fix_key_buffer_size); fix_key_buffer_size);
sys_var_literal_collation sys_literal_collation("literal_collation");
sys_var_bool_ptr sys_local_infile("local_infile", sys_var_bool_ptr sys_local_infile("local_infile",
&opt_local_infile); &opt_local_infile);
sys_var_thd_bool sys_log_warnings("log_warnings", &SV::log_warnings); sys_var_thd_bool sys_log_warnings("log_warnings", &SV::log_warnings);
...@@ -363,6 +364,7 @@ sys_var *sys_variables[]= ...@@ -363,6 +364,7 @@ sys_var *sys_variables[]=
&sys_interactive_timeout, &sys_interactive_timeout,
&sys_join_buffer_size, &sys_join_buffer_size,
&sys_key_buffer_size, &sys_key_buffer_size,
&sys_literal_collation,
&sys_last_insert_id, &sys_last_insert_id,
&sys_local_infile, &sys_local_infile,
&sys_log_binlog, &sys_log_binlog,
...@@ -507,6 +509,7 @@ struct show_var_st init_vars[]= { ...@@ -507,6 +509,7 @@ struct show_var_st init_vars[]= {
{sys_key_buffer_size.name, (char*) &sys_key_buffer_size, SHOW_SYS}, {sys_key_buffer_size.name, (char*) &sys_key_buffer_size, SHOW_SYS},
{"language", language, SHOW_CHAR}, {"language", language, SHOW_CHAR},
{"large_files_support", (char*) &opt_large_files, SHOW_BOOL}, {"large_files_support", (char*) &opt_large_files, SHOW_BOOL},
{sys_literal_collation.name,(char*) &sys_literal_collation, SHOW_SYS},
{sys_local_infile.name, (char*) &sys_local_infile, SHOW_SYS}, {sys_local_infile.name, (char*) &sys_local_infile, SHOW_SYS},
#ifdef HAVE_MLOCKALL #ifdef HAVE_MLOCKALL
{"locked_in_memory", (char*) &locked_in_memory, SHOW_BOOL}, {"locked_in_memory", (char*) &locked_in_memory, SHOW_BOOL},
...@@ -1155,7 +1158,8 @@ byte *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type) ...@@ -1155,7 +1158,8 @@ byte *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type)
} }
typedef struct old_names_map_st { typedef struct old_names_map_st
{
const char *old_name; const char *old_name;
const char *new_name; const char *new_name;
} my_old_conv; } my_old_conv;
...@@ -1187,20 +1191,12 @@ CHARSET_INFO *get_old_charset_by_name(const char *name) ...@@ -1187,20 +1191,12 @@ CHARSET_INFO *get_old_charset_by_name(const char *name)
return NULL; return NULL;
} }
bool sys_var_client_collation::check(THD *thd, set_var *var) bool sys_var_collation::check(THD *thd, set_var *var)
{ {
CHARSET_INFO *tmp; CHARSET_INFO *tmp;
char buff[80]; char buff[80];
String str(buff,sizeof(buff), system_charset_info), *res; String str(buff,sizeof(buff), system_charset_info), *res;
if (!var->value) // Default value
{
var->save_result.charset= (var->type != OPT_GLOBAL ?
global_system_variables.thd_charset
: thd->db_charset);
return 0;
}
if (!(res=var->value->val_str(&str))) if (!(res=var->value->val_str(&str)))
res= &empty_string; res= &empty_string;
...@@ -1217,27 +1213,90 @@ bool sys_var_client_collation::check(THD *thd, set_var *var) ...@@ -1217,27 +1213,90 @@ bool sys_var_client_collation::check(THD *thd, set_var *var)
bool sys_var_client_collation::update(THD *thd, set_var *var) bool sys_var_client_collation::update(THD *thd, set_var *var)
{ {
if (var->type == OPT_GLOBAL) if (var->type == OPT_GLOBAL)
global_system_variables.thd_charset= var->save_result.charset; global_system_variables.client_collation= var->save_result.charset;
else else
{ {
thd->variables.thd_charset= var->save_result.charset; thd->variables.client_collation= var->save_result.charset;
thd->protocol_simple.init(thd); thd->protocol_simple.init(thd);
thd->protocol_prep.init(thd); thd->protocol_prep.init(thd);
} }
return 0; return 0;
} }
byte *sys_var_client_collation::value_ptr(THD *thd, enum_var_type type) byte *sys_var_client_collation::value_ptr(THD *thd, enum_var_type type)
{ {
CHARSET_INFO *cs= ((type == OPT_GLOBAL) ? CHARSET_INFO *cs= ((type == OPT_GLOBAL) ?
global_system_variables.thd_charset : global_system_variables.client_collation :
thd->variables.thd_charset); thd->variables.client_collation);
return cs ? (byte*) cs->name : (byte*) ""; return cs ? (byte*) cs->name : (byte*) "";
} }
void sys_var_client_collation::set_default(THD *thd, enum_var_type type)
{
if (type == OPT_GLOBAL)
global_system_variables.client_collation= default_charset_info;
else
{
thd->variables.client_collation= thd->db_charset;
}
}
bool sys_var_literal_collation::update(THD *thd, set_var *var)
{
if (var->type == OPT_GLOBAL)
global_system_variables.literal_collation= var->save_result.charset;
else
thd->variables.literal_collation= var->save_result.charset;
return 0;
}
byte *sys_var_literal_collation::value_ptr(THD *thd, enum_var_type type)
{
CHARSET_INFO *cs= ((type == OPT_GLOBAL) ?
global_system_variables.literal_collation :
thd->variables.literal_collation);
return cs ? (byte*) cs->name : (byte*) "";
}
void sys_var_literal_collation::set_default(THD *thd, enum_var_type type)
{
if (type == OPT_GLOBAL)
global_system_variables.literal_collation= default_charset_info;
else
thd->variables.literal_collation= thd->db_charset;
}
/*****************************************************************************
Functions to handle SET NAMES and SET CHARACTER SET
*****************************************************************************/
int set_var_client_collation::check(THD *thd)
{
client_charset= client_charset ? client_charset : thd->db_charset;
client_collation= client_collation ? client_collation : client_charset;
if (!my_charset_same(client_charset, client_collation))
{
my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
client_collation->name, client_charset->csname);
return -1;
}
return 0;
}
int set_var_client_collation::update(THD *thd)
{
thd->variables.client_collation= client_collation;
thd->variables.literal_collation= client_collation;
thd->variables.convert_result_charset= convert_result_charset;
thd->protocol_simple.init(thd);
thd->protocol_prep.init(thd);
return 0;
}
/****************************************************************************/
bool sys_var_timestamp::update(THD *thd, set_var *var) bool sys_var_timestamp::update(THD *thd, set_var *var)
{ {
thd->set_time((time_t) var->value->val_int()); thd->set_time((time_t) var->value->val_int());
...@@ -1656,31 +1715,6 @@ int set_var_password::update(THD *thd) ...@@ -1656,31 +1715,6 @@ int set_var_password::update(THD *thd)
} }
/*****************************************************************************
Functions to handle SET NAMES and SET CHARACTER SET
*****************************************************************************/
int set_var_client_collation::check(THD *thd)
{
client_charset= client_charset ? client_charset : thd->db_charset;
client_collation= client_collation ? client_collation : client_charset;
if (!my_charset_same(client_charset, client_collation))
{
my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
client_collation->name, client_charset->csname);
return -1;
}
return 0;
}
int set_var_client_collation::update(THD *thd)
{
thd->variables.thd_charset= client_collation;
thd->variables.convert_result_charset= convert_result_charset;
thd->protocol_simple.init(thd);
thd->protocol_prep.init(thd);
return 0;
}
......
...@@ -406,20 +406,36 @@ public: ...@@ -406,20 +406,36 @@ public:
}; };
class sys_var_client_collation :public sys_var_thd class sys_var_collation :public sys_var_thd
{ {
public: public:
sys_var_client_collation(const char *name_arg) :sys_var_thd(name_arg) sys_var_collation(const char *name_arg) :sys_var_thd(name_arg) {}
{}
bool check(THD *thd, set_var *var); bool check(THD *thd, set_var *var);
bool update(THD *thd, set_var *var); SHOW_TYPE type() { return SHOW_CHAR; }
SHOW_TYPE type() { return SHOW_CHAR; }
byte *value_ptr(THD *thd, enum_var_type type);
bool check_update_type(Item_result type) bool check_update_type(Item_result type)
{ {
return type != STRING_RESULT; /* Only accept strings */ return type != STRING_RESULT; /* Only accept strings */
} }
bool check_default(enum_var_type type) { return 0; } bool check_default(enum_var_type type) { return 0; }
virtual void set_default(THD *thd, enum_var_type type)= 0;
};
class sys_var_client_collation :public sys_var_collation
{
public:
sys_var_client_collation(const char *name_arg) :sys_var_collation(name_arg) {}
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type);
};
class sys_var_literal_collation :public sys_var_collation
{
public:
sys_var_literal_collation(const char *name_arg) :sys_var_collation(name_arg) {}
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type);
}; };
......
...@@ -901,14 +901,14 @@ int collect_real(double *element, element_count count __attribute__((unused)), ...@@ -901,14 +901,14 @@ int collect_real(double *element, element_count count __attribute__((unused)),
TREE_INFO *info) TREE_INFO *info)
{ {
char buff[MAX_FIELD_WIDTH]; char buff[MAX_FIELD_WIDTH];
String s(buff, sizeof(buff),current_thd->variables.thd_charset); String s(buff, sizeof(buff),current_thd->charset());
if (info->found) if (info->found)
info->str->append(','); info->str->append(',');
else else
info->found = 1; info->found = 1;
info->str->append('\''); info->str->append('\'');
s.set(*element, info->item->decimals, current_thd->variables.thd_charset); s.set(*element, info->item->decimals, current_thd->charset());
info->str->append(s); info->str->append(s);
info->str->append('\''); info->str->append('\'');
return 0; return 0;
...@@ -927,7 +927,7 @@ int collect_longlong(longlong *element, ...@@ -927,7 +927,7 @@ int collect_longlong(longlong *element,
else else
info->found = 1; info->found = 1;
info->str->append('\''); info->str->append('\'');
s.set(*element, current_thd->variables.thd_charset); s.set(*element, current_thd->charset());
info->str->append(s); info->str->append(s);
info->str->append('\''); info->str->append('\'');
return 0; return 0;
...@@ -946,7 +946,7 @@ int collect_ulonglong(ulonglong *element, ...@@ -946,7 +946,7 @@ int collect_ulonglong(ulonglong *element,
else else
info->found = 1; info->found = 1;
info->str->append('\''); info->str->append('\'');
s.set(*element, current_thd->variables.thd_charset); s.set(*element, current_thd->charset());
info->str->append(s); info->str->append(s);
info->str->append('\''); info->str->append('\'');
return 0; return 0;
......
...@@ -207,7 +207,7 @@ void THD::init(void) ...@@ -207,7 +207,7 @@ void THD::init(void)
{ {
pthread_mutex_lock(&LOCK_global_system_variables); pthread_mutex_lock(&LOCK_global_system_variables);
variables= global_system_variables; variables= global_system_variables;
variables.thd_charset=default_charset_info; variables.client_collation= default_charset_info;
pthread_mutex_unlock(&LOCK_global_system_variables); pthread_mutex_unlock(&LOCK_global_system_variables);
server_status= SERVER_STATUS_AUTOCOMMIT; server_status= SERVER_STATUS_AUTOCOMMIT;
options= thd_startup_options; options= thd_startup_options;
......
...@@ -380,7 +380,8 @@ struct system_variables ...@@ -380,7 +380,8 @@ struct system_variables
my_bool new_mode; my_bool new_mode;
my_bool convert_result_charset; my_bool convert_result_charset;
CHARSET_INFO *thd_charset; CHARSET_INFO *client_collation;
CHARSET_INFO *literal_collation;
}; };
void free_tmp_table(THD *thd, TABLE *entry); void free_tmp_table(THD *thd, TABLE *entry);
...@@ -661,9 +662,9 @@ public: ...@@ -661,9 +662,9 @@ public:
net.report_error= 1; net.report_error= 1;
DBUG_PRINT("error",("Fatal error set")); DBUG_PRINT("error",("Fatal error set"));
} }
inline CHARSET_INFO *charset() { return variables.thd_charset; } inline CHARSET_INFO *charset() { return variables.client_collation; }
inline CHARSET_INFO *result_charset(CHARSET_INFO *cs) inline CHARSET_INFO *result_charset(CHARSET_INFO *cs)
{ return variables.convert_result_charset ? variables.thd_charset : cs; } { return variables.convert_result_charset ? charset() : cs; }
}; };
/* /*
......
...@@ -602,7 +602,7 @@ bool mysql_change_db(THD *thd, const char *name) ...@@ -602,7 +602,7 @@ bool mysql_change_db(THD *thd, const char *name)
strmov(path+unpack_dirname(path,path), MY_DB_OPT_FILE); strmov(path+unpack_dirname(path,path), MY_DB_OPT_FILE);
load_db_opt(path, &create); load_db_opt(path, &create);
thd->db_charset= create.table_charset ? create.table_charset : default_charset_info; thd->db_charset= create.table_charset ? create.table_charset : default_charset_info;
thd->variables.thd_charset=thd->db_charset ? thd->db_charset : default_charset_info; thd->variables.client_collation=thd->db_charset ? thd->db_charset : default_charset_info;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
...@@ -118,7 +118,6 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) ...@@ -118,7 +118,6 @@ LEX *lex_start(THD *thd, uchar *buf,uint length)
lex->select_lex.ftfunc_list_alloc.empty(); lex->select_lex.ftfunc_list_alloc.empty();
lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc; lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc;
lex->current_select= &lex->select_lex; lex->current_select= &lex->select_lex;
lex->thd_charset= lex->thd->variables.thd_charset;
lex->yacc_yyss=lex->yacc_yyvs=0; lex->yacc_yyss=lex->yacc_yyvs=0;
lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE); lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE);
lex->sql_command=SQLCOM_END; lex->sql_command=SQLCOM_END;
...@@ -209,7 +208,7 @@ static char *get_text(LEX *lex) ...@@ -209,7 +208,7 @@ static char *get_text(LEX *lex)
{ {
reg1 uchar c,sep; reg1 uchar c,sep;
uint found_escape=0; uint found_escape=0;
CHARSET_INFO *cs= lex->thd->variables.thd_charset; CHARSET_INFO *cs= lex->thd->charset();
sep= yyGetLast(); // String should end with this sep= yyGetLast(); // String should end with this
//lex->tok_start=lex->ptr-1; // Remember ' //lex->tok_start=lex->ptr-1; // Remember '
...@@ -422,7 +421,7 @@ int yylex(void *arg, void *yythd) ...@@ -422,7 +421,7 @@ int yylex(void *arg, void *yythd)
enum my_lex_states state,prev_state; enum my_lex_states state,prev_state;
LEX *lex= &(((THD *)yythd)->lex); LEX *lex= &(((THD *)yythd)->lex);
YYSTYPE *yylval=(YYSTYPE*) arg; YYSTYPE *yylval=(YYSTYPE*) arg;
CHARSET_INFO *cs= ((THD *) yythd)->variables.thd_charset; CHARSET_INFO *cs= ((THD *) yythd)->charset();
uchar *state_map= cs->state_map; uchar *state_map= cs->state_map;
uchar *ident_map= cs->ident_map; uchar *ident_map= cs->ident_map;
......
...@@ -448,7 +448,6 @@ typedef struct st_lex ...@@ -448,7 +448,6 @@ typedef struct st_lex
TYPELIB *interval; TYPELIB *interval;
create_field *last_field; create_field *last_field;
Item *default_value, *comment; Item *default_value, *comment;
CHARSET_INFO *thd_charset;
uint uint_geom_type; uint uint_geom_type;
LEX_USER *grant_user; LEX_USER *grant_user;
gptr yacc_yyss,yacc_yyvs; gptr yacc_yyss,yacc_yyvs;
......
...@@ -2167,7 +2167,7 @@ simple_expr: ...@@ -2167,7 +2167,7 @@ simple_expr:
| simple_expr COLLATE_SYM ident_or_text %prec NEG | simple_expr COLLATE_SYM ident_or_text %prec NEG
{ {
$$= new Item_func_set_collation($1,new Item_string($3.str,$3.length, $$= new Item_func_set_collation($1,new Item_string($3.str,$3.length,
YYTHD->variables.thd_charset)); YYTHD->charset()));
} }
| literal | literal
| param_marker | param_marker
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment