summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libmysqld/lib_sql.cc2
-rw-r--r--mysql-test/r/query_cache.result2
-rw-r--r--mysql-test/r/variables.result20
-rw-r--r--mysql-test/t/variables.test12
-rw-r--r--sql/convert.cc3
-rw-r--r--sql/log.cc2
-rw-r--r--sql/log_event.cc4
-rw-r--r--sql/protocol.cc15
-rw-r--r--sql/protocol.h4
-rw-r--r--sql/set_var.cc74
-rw-r--r--sql/set_var.h18
-rw-r--r--sql/sql_cache.cc14
-rw-r--r--sql/sql_class.h27
-rw-r--r--sql/sql_db.cc1
-rw-r--r--sql/sql_lex.cc12
-rw-r--r--sql/sql_lex.h1
-rw-r--r--sql/sql_show.cc4
-rw-r--r--sql/sql_yacc.yy10
18 files changed, 68 insertions, 157 deletions
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 68a7b940220..12647a32713 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -504,6 +504,7 @@ bool Protocol::net_store_data(const char *from, uint length)
return false;
}
+#if 0
/* The same as Protocol::net_store_data but does the converstion
*/
bool Protocol::convert_str(const char *from, uint length)
@@ -519,3 +520,4 @@ bool Protocol::convert_str(const char *from, uint length)
return false;
}
+#endif
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
index 30a0cd01c51..00d79ec0b6e 100644
--- a/mysql-test/r/query_cache.result
+++ b/mysql-test/r/query_cache.result
@@ -377,7 +377,7 @@ a
set CHARACTER SET cp1251_koi8;
select * from t1;
a
+?
set CHARACTER SET DEFAULT;
show status like "Qcache_queries_in_cache";
Variable_name Value
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index b66d75e2b3a..822fab5ae47 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -156,17 +156,17 @@ show variables like 'net_buffer_length';
Variable_name Value
net_buffer_length 1048576
set GLOBAL character set cp1251_koi8;
-show global variables like "convert_character_set";
+show global variables like "client_collation";
Variable_name Value
-convert_character_set cp1251_koi8
+client_collation cp1251
set character set cp1251_koi8;
-show variables like "convert_character_set";
+show variables like "client_collation";
Variable_name Value
-convert_character_set cp1251_koi8
+client_collation cp1251
set global character set default, session character set default;
-show variables like "convert_character_set";
+show variables like "client_collation";
Variable_name Value
-convert_character_set cp1251_koi8
+client_collation latin1
select @@timestamp>0;
@@timestamp>0
1
@@ -193,12 +193,12 @@ set SESSION query_cache_size=10000;
Variable 'query_cache_size' is a GLOBAL variable and should be set with SET GLOBAL
set GLOBAL table_type=DEFAULT;
Variable 'table_type' doesn't have a default value
-set convert_character_set=UNKNOWN_CHARACTER_SET;
+set client_collation=UNKNOWN_CHARACTER_SET;
Unknown character set: 'UNKNOWN_CHARACTER_SET'
set character set unknown;
Unknown character set: 'unknown'
set character set 0;
-Wrong argument type to variable 'convert_character_set'
+Wrong argument type to variable 'client_collation'
set global autocommit=1;
Variable 'autocommit' is a LOCAL variable and can't be used with SET GLOBAL
select @@global.timestamp;
@@ -218,8 +218,8 @@ select @@autocommit, @@big_tables;
1 1
set global binlog_cache_size=100;
set bulk_insert_buffer_size=100;
-set convert_character_set=cp1251_koi8;
-set convert_character_set=default;
+set character set cp1251_koi8;
+set character set default;
set @@global.concurrent_insert=1;
set global connect_timeout=100;
select @@delay_key_write;
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index 39aa5a20a71..4bde54f868a 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -92,11 +92,11 @@ set net_buffer_length=2000000000;
show variables like 'net_buffer_length';
set GLOBAL character set cp1251_koi8;
-show global variables like "convert_character_set";
+show global variables like "client_collation";
set character set cp1251_koi8;
-show variables like "convert_character_set";
+show variables like "client_collation";
set global character set default, session character set default;
-show variables like "convert_character_set";
+show variables like "client_collation";
select @@timestamp>0;
set @@rand_seed1=10000000,@@rand_seed2=1000000;
@@ -123,7 +123,7 @@ set SESSION query_cache_size=10000;
--error 1230
set GLOBAL table_type=DEFAULT;
--error 1115
-set convert_character_set=UNKNOWN_CHARACTER_SET;
+set client_collation=UNKNOWN_CHARACTER_SET;
--error 1115
set character set unknown;
--error 1232
@@ -148,8 +148,8 @@ set big_tables=1;
select @@autocommit, @@big_tables;
set global binlog_cache_size=100;
set bulk_insert_buffer_size=100;
-set convert_character_set=cp1251_koi8;
-set convert_character_set=default;
+set character set cp1251_koi8;
+set character set default;
set @@global.concurrent_insert=1;
set global connect_timeout=100;
select @@delay_key_write;
diff --git a/sql/convert.cc b/sql/convert.cc
index 84003af3922..bfdf49bf42d 100644
--- a/sql/convert.cc
+++ b/sql/convert.cc
@@ -14,6 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+#if 0
/*
** Convert tables between different character sets
@@ -460,3 +461,5 @@ bool CONVERT::store(String *packet,const char *from,uint length)
packet->length((uint) (store_dest(to, from, length)-packet->ptr()));
return 0;
}
+
+#endif
diff --git a/sql/log.cc b/sql/log.cc
index 170e976e643..e70facd64df 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1194,6 +1194,7 @@ bool MYSQL_LOG::write(Log_event* event_info)
goto err;
}
}
+#if 0
if (thd->variables.convert_set)
{
char buf[256], *p;
@@ -1204,6 +1205,7 @@ bool MYSQL_LOG::write(Log_event* event_info)
if (e.write(file))
goto err;
}
+#endif
}
event_info->set_log_pos(this);
if (event_info->write(file) ||
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 3a1dbb6485e..378c0639d54 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -943,7 +943,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->db = thd->query = 0;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
- thd->variables.convert_set = 0;
+ //thd->variables.convert_set = 0;
close_thread_tables(thd);
free_root(&thd->mem_root,0);
return 1;
@@ -954,7 +954,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
thd->query= 0; // just to be sure
VOID(pthread_mutex_unlock(&LOCK_thread_count));
// assume no convert for next query unless set explictly
- thd->variables.convert_set = 0;
+ //thd->variables.convert_set = 0;
close_thread_tables(thd);
if (thd->query_error || thd->is_fatal_error)
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 9fb32daf57f..af8f966a4b6 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -43,11 +43,6 @@ bool Protocol::net_store_data(const char *from, uint length)
packet->length((uint) (to+length-packet->ptr()));
return 0;
}
-
-inline bool Protocol::convert_str(const char *from, uint length)
-{
- return convert->store(packet, from, length);
-}
#endif
@@ -472,7 +467,6 @@ char *net_store_data(char *to,longlong from)
void Protocol::init(THD *thd_arg)
{
thd=thd_arg;
- convert=thd->variables.convert_set;
packet= &thd->packet;
#ifndef DEBUG_OFF
field_types= 0;
@@ -487,15 +481,12 @@ void Protocol::init(THD *thd_arg)
send_fields()
THD Thread data object
list List of items to send to client
- convert object used to convertation to another character set
flag Bit mask with the following functions:
1 send number of rows
2 send default values
DESCRIPTION
Sum fields has table name empty and field_name.
- Uses send_fields_convert() and send_fields() depending on
- if we have an active character set convert or not.
RETURN VALUES
0 ok
@@ -712,8 +703,6 @@ bool Protocol_simple::store(const char *from, uint length, CHARSET_INFO *cs)
field_types[field_pos] <= MYSQL_TYPE_GEOMETRY));
field_pos++;
#endif
- if (convert)
- return convert_str(from, length);
if (cs != this->thd->charset())
{
String tmp;
@@ -813,8 +802,6 @@ bool Protocol_simple::store(Field *field)
char buff[MAX_FIELD_WIDTH];
String tmp1(buff,sizeof(buff), &my_charset_bin);
field->val_str(&tmp1,&tmp1);
- if (convert)
- return convert_str(tmp1.ptr(), tmp1.length());
if (field->charset() != this->thd->charset())
{
String tmp;
@@ -929,8 +916,6 @@ bool Protocol_prep::store(const char *from,uint length, CHARSET_INFO *cs)
field_types[field_pos] <= MYSQL_TYPE_GEOMETRY));
#endif
field_pos++;
- if (convert)
- return convert_str(from, length);
return net_store_data(from, length);
}
diff --git a/sql/protocol.h b/sql/protocol.h
index e9df013e81c..71ad5c1302b 100644
--- a/sql/protocol.h
+++ b/sql/protocol.h
@@ -20,7 +20,6 @@
#define PACKET_BUFFET_EXTRA_ALLOC 1024
-class CONVERT;
class i_string;
class THD;
#ifdef EMBEDDED_LIBRARY
@@ -37,15 +36,12 @@ protected:
#endif
uint field_count;
bool net_store_data(const char *from, uint length);
- bool convert_str(const char *from, uint length);
#ifdef EMBEDDED_LIBRARY
char **next_field;
MYSQL_FIELD *next_mysql_field;
MEM_ROOT *alloc;
#endif
public:
- CONVERT *convert;
-
Protocol() {}
Protocol(THD *thd) { init(thd); }
void init(THD* thd);
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 0b85f50e0ef..a51a2e7204a 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -105,7 +105,6 @@ sys_var_str sys_charset("character_set",
sys_update_charset,
sys_set_default_charset);
sys_var_client_collation sys_client_collation("client_collation");
-sys_var_thd_conv_charset sys_convert_charset("convert_character_set");
sys_var_bool_ptr sys_concurrent_insert("concurrent_insert",
&myisam_concurrent_insert);
sys_var_long_ptr sys_connect_timeout("connect_timeout",
@@ -337,7 +336,6 @@ sys_var *sys_variables[]=
&sys_client_collation,
&sys_concurrent_insert,
&sys_connect_timeout,
- &sys_convert_charset,
&sys_default_week_format,
&sys_delay_key_write,
&sys_delayed_insert_limit,
@@ -445,7 +443,6 @@ struct show_var_st init_vars[]= {
{sys_client_collation.name, (char*) &sys_client_collation, SHOW_SYS},
{sys_concurrent_insert.name,(char*) &sys_concurrent_insert, SHOW_SYS},
{sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS},
- {sys_convert_charset.name, (char*) &sys_convert_charset, SHOW_SYS},
{"datadir", mysql_real_data_home, SHOW_CHAR},
{"default_week_format", (char*) &sys_default_week_format, SHOW_SYS},
{sys_delay_key_write.name, (char*) &sys_delay_key_write, SHOW_SYS},
@@ -1131,56 +1128,38 @@ byte *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type)
}
-bool sys_var_thd_conv_charset::check(THD *thd, set_var *var)
-{
- CONVERT *tmp;
- char buff[80];
- String str(buff,sizeof(buff), system_charset_info), *res;
-
- if (!var->value) // Default value
- {
- var->save_result.convert= (var->type != OPT_GLOBAL ?
- global_system_variables.convert_set
- : (CONVERT*) 0);
- return 0;
- }
- if (!(res=var->value->val_str(&str)))
- res= &empty_string;
-
- if (!(tmp=get_convert_set(res->c_ptr())))
- {
- my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr());
- return 1;
- }
- var->save_result.convert=tmp; // Save for update
- return 0;
-}
+typedef struct old_names_map_st {
+ const char *old_name;
+ const char *new_name;
+} my_old_conv;
+static my_old_conv old_conv[]=
+{
+ { "cp1251_koi8" , "cp1251" },
+ { "cp1250_latin2" , "cp1250" },
+ { "kam_latin2" , "keybcs2" },
+ { "mac_latin2" , "MacRoman" },
+ { "macce_latin2" , "MacCE" },
+ { "pc2_latin2" , "pclatin2" },
+ { "vga_latin2" , "pclatin1" },
+ { "koi8_cp1251" , "koi8r" },
+ { "win1251ukr_koi8_ukr" , "win1251ukr" },
+ { "koi8_ukr_win1251ukr" , "koi8u" },
+ { NULL , NULL }
+};
-bool sys_var_thd_conv_charset::update(THD *thd, set_var *var)
+static CHARSET_INFO *get_old_charset_by_name(const char *name)
{
- if (var->type == OPT_GLOBAL)
- global_system_variables.convert_set= var->save_result.convert;
- else
+ my_old_conv *c;
+
+ for (c= old_conv; c->old_name; c++)
{
- thd->lex.convert_set= thd->variables.convert_set=
- var->save_result.convert;
- thd->protocol_simple.init(thd);
- thd->protocol_prep.init(thd);
+ if (!my_strcasecmp(&my_charset_latin1,name,c->old_name))
+ return get_charset_by_name(c->new_name,MYF(0));
}
- return 0;
+ return NULL;
}
-
-byte *sys_var_thd_conv_charset::value_ptr(THD *thd, enum_var_type type)
-{
- CONVERT *conv= ((type == OPT_GLOBAL) ?
- global_system_variables.convert_set :
- thd->variables.convert_set);
- return conv ? (byte*) conv->name : (byte*) "";
-}
-
-
bool sys_var_client_collation::check(THD *thd, set_var *var)
{
CHARSET_INFO *tmp;
@@ -1198,7 +1177,8 @@ bool sys_var_client_collation::check(THD *thd, set_var *var)
if (!(res=var->value->val_str(&str)))
res= &empty_string;
- if (!(tmp=get_charset_by_name(res->c_ptr(),MYF(0))))
+ if (!(tmp=get_charset_by_name(res->c_ptr(),MYF(0))) &&
+ !(tmp=get_old_charset_by_name(res->c_ptr())))
{
my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr());
return 1;
diff --git a/sql/set_var.h b/sql/set_var.h
index b84e0b888e2..d91b6796d20 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -406,23 +406,6 @@ public:
};
-class sys_var_thd_conv_charset :public sys_var_thd
-{
-public:
- sys_var_thd_conv_charset(const char *name_arg)
- :sys_var_thd(name_arg)
- {}
- bool check(THD *thd, set_var *var);
- bool update(THD *thd, set_var *var);
- SHOW_TYPE type() { return SHOW_CHAR; }
- byte *value_ptr(THD *thd, enum_var_type type);
- bool check_update_type(Item_result type)
- {
- return type != STRING_RESULT; /* Only accept strings */
- }
- bool check_default(enum_var_type type) { return 0; }
-};
-
class sys_var_client_collation :public sys_var_thd
{
public:
@@ -490,7 +473,6 @@ public:
union
{
CHARSET_INFO *charset;
- CONVERT *convert;
ulong ulong_value;
} save_result;
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 90fd61ebeb7..bd6d7f83c95 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -778,11 +778,8 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
most significant bit - CLIENT_LONG_FLAG,
other - charset number (0 no charset convertion)
*/
- if (thd->variables.convert_set != 0)
- {
- flags|= (byte) thd->variables.convert_set->number();
- DBUG_ASSERT(thd->variables.convert_set->number() < 128);
- }
+ flags|= (byte) thd->charset()->number;
+ DBUG_ASSERT(thd->charset()->number < 128);
tot_length=thd->query_length+thd->db_length+2;
thd->query[tot_length-1] = (char) flags;
@@ -935,11 +932,8 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
Other - charset number (0 no charset convertion)
*/
flags = (thd->client_capabilities & CLIENT_LONG_FLAG ? 0x80 : 0);
- if (thd->variables.convert_set != 0)
- {
- flags |= (byte) thd->variables.convert_set->number();
- DBUG_ASSERT(thd->variables.convert_set->number() < 128);
- }
+ flags |= (byte) thd->charset()->number;
+ DBUG_ASSERT(thd->charset()->number < 128);
sql[tot_length-1] = (char) flags;
query_block = (Query_cache_block *) hash_search(&queries, (byte*) sql,
tot_length);
diff --git a/sql/sql_class.h b/sql/sql_class.h
index dbf9f0d13d6..d2ceb2e6139 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -172,32 +172,6 @@ public:
/* character conversion tables */
-class CONVERT;
-CONVERT *get_convert_set(const char *name_ptr);
-
-class CONVERT
-{
- const uchar *from_map,*to_map;
- void convert_array(const uchar *mapping,uchar *buff,uint length);
-public:
- const char *name;
- uint numb;
- CONVERT(const char *name_par,uchar *from_par,uchar *to_par, uint number)
- :from_map(from_par),to_map(to_par),name(name_par),numb(number) {}
- friend CONVERT *get_convert_set(const char *name_ptr);
- inline void convert(char *a,uint length)
- {
- convert_array(from_map, (uchar*) a,length);
- }
- char *store_dest(char *to, const char *from, uint length)
- {
- for (const char *end=from+length ; from != end ; from++)
- *to++= to_map[(uchar) *from];
- return to;
- }
- bool store(String *, const char *,uint);
- inline uint number() { return numb; }
-};
typedef struct st_copy_info {
ha_rows records;
@@ -400,7 +374,6 @@ struct system_variables
my_bool log_warnings;
my_bool low_priority_updates;
- CONVERT *convert_set;
CHARSET_INFO *thd_charset;
};
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 03ccf88316c..ffa5416eaf5 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -615,7 +615,6 @@ int mysqld_show_create_db(THD *thd, char *dbname,
uint db_access;
bool found_libchar;
HA_CREATE_INFO create;
- CONVERT *convert=thd->variables.convert_set;
uint create_options = create_info ? create_info->options : 0;
Protocol *protocol=thd->protocol;
DBUG_ENTER("mysql_show_create_db");
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 378aa380a3c..da67f5646fc 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -107,6 +107,7 @@ void lex_free(void)
LEX *lex_start(THD *thd, uchar *buf,uint length)
{
LEX *lex= &thd->lex;
+ lex->thd= thd;
lex->next_state=MY_LEX_START;
lex->end_of_query=(lex->ptr=buf)+length;
lex->yylineno = 1;
@@ -117,7 +118,6 @@ LEX *lex_start(THD *thd, uchar *buf,uint length)
lex->select_lex.ftfunc_list_alloc.empty();
lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc;
lex->current_select= &lex->select_lex;
- lex->convert_set= (lex->thd= thd)->variables.convert_set;
lex->thd_charset= lex->thd->variables.thd_charset;
lex->yacc_yyss=lex->yacc_yyvs=0;
lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE);
@@ -520,8 +520,6 @@ int yylex(void *arg, void *yythd)
yySkip(); // next state does a unget
}
yylval->lex_str=get_token(lex,length);
- if (lex->convert_set)
- lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
/*
Note: "SELECT _bla AS 'alias'"
@@ -621,8 +619,6 @@ int yylex(void *arg, void *yythd)
case MY_LEX_FOUND_IDENT: // Complete ident
yylval->lex_str=get_token(lex,yyLength());
- if (lex->convert_set)
- lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
return(IDENT);
case MY_LEX_USER_VARIABLE_DELIMITER:
@@ -670,8 +666,6 @@ int yylex(void *arg, void *yythd)
else
yylval->lex_str=get_token(lex,yyLength());
}
- if (lex->convert_set)
- lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
if (c == delim)
yySkip(); // Skip end `
return(IDENT);
@@ -802,8 +796,6 @@ int yylex(void *arg, void *yythd)
break;
}
yylval->lex_str.length=lex->yytoklen;
- if (lex->convert_set)
- lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
return(TEXT_STRING);
case MY_LEX_COMMENT: // Comment
@@ -940,8 +932,6 @@ int yylex(void *arg, void *yythd)
return(tokval); // Was keyword
}
yylval->lex_str=get_token(lex,length);
- if (lex->convert_set)
- lex->convert_set->convert((char*) yylval->lex_str.str,lex->yytoklen);
return(IDENT);
}
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 7c45e9e5619..d8045dcc556 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -448,7 +448,6 @@ typedef struct st_lex
TYPELIB *interval;
create_field *last_field;
Item *default_value, *comment;
- CONVERT *convert_set;
CHARSET_INFO *thd_charset;
LEX_USER *grant_user;
gptr yacc_yyss,yacc_yyvs;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 00df2c44fd6..9f26c8a12ad 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -979,8 +979,8 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd)
if (store_create_info(thd, table, packet))
DBUG_RETURN(-1);
- if (protocol->convert)
- protocol->convert->convert((char*) packet->ptr(), packet->length());
+ //if (protocol->convert)
+ // protocol->convert->convert((char*) packet->ptr(), packet->length());
if (fd < 0)
{
if (protocol->write())
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 7749aea0040..d7971cb7c08 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -4306,9 +4306,15 @@ option_value:
}
| charset opt_equal set_expr_or_default
{
- LEX *lex=Lex;
+ THD *thd= YYTHD;
+ LEX *lex= &thd->lex;
+ if (!$3)
+ {
+ CHARSET_INFO *cl= thd->db_charset;
+ $3= new Item_string(cl->name, strlen(cl->name), &my_charset_latin1);
+ }
lex->var_list.push_back(new set_var(lex->option_type,
- find_sys_var("convert_character_set"),
+ find_sys_var("client_collation"),
$3));
}
| NAMES_SYM charset_name_or_default opt_collate