diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f68de23034a..4ad1335d080 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -528,6 +528,7 @@ int mysqld_show_variables(THD *thd,const char *wild); int mysqld_show(THD *thd, const char *wild, show_var_st *variables, enum enum_var_type value_type); int mysqld_show_charsets(THD *thd,const char *wild); +int mysqld_show_collations(THD *thd,const char *wild); int mysqld_show_table_types(THD *thd); int mysqld_show_privileges(THD *thd); int mysqld_show_column_types(THD *thd); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index d8045dcc556..0d284d5f619 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -52,7 +52,7 @@ enum enum_sql_command { SQLCOM_SHOW_INNODB_STATUS, SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT, SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS, - SQLCOM_SHOW_CREATE_DB, + SQLCOM_SHOW_COLLATIONS, SQLCOM_SHOW_CREATE_DB, SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES, SQLCOM_GRANT, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8ca5bf2f12d..d08e6b70634 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2566,6 +2566,9 @@ mysql_execute_command(THD *thd) case SQLCOM_SHOW_CHARSETS: res= mysqld_show_charsets(thd,(lex->wild ? lex->wild->ptr() : NullS)); break; + case SQLCOM_SHOW_COLLATIONS: + res= mysqld_show_collations(thd,(lex->wild ? lex->wild->ptr() : NullS)); + break; case SQLCOM_SHOW_FIELDS: #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 122a0171777..d2cc9045148 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1414,6 +1414,71 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) Status functions *****************************************************************************/ +static bool write_collation(Protocol *protocol, CHARSET_INFO *cs) +{ + char flags[4]; + protocol->prepare_for_resend(); + protocol->store(cs->csname, system_charset_info); + protocol->store(cs->name, system_charset_info); + protocol->store_short((longlong) cs->number); + flags[0]='\0'; + if (cs->state & MY_CS_PRIMARY) + strcat(flags,"def"); + protocol->store(flags, system_charset_info); + protocol->store_short((longlong) cs->strxfrm_multiply); + return protocol->write(); +} + +int mysqld_show_collations(THD *thd, const char *wild) +{ + char buff[8192]; + String packet2(buff,sizeof(buff),thd->charset()); + List field_list; + CHARSET_INFO **cs; + Protocol *protocol= thd->protocol; + char flags[64]; + + DBUG_ENTER("mysqld_show_charsets"); + + field_list.push_back(new Item_empty_string("Charset",30)); + field_list.push_back(new Item_empty_string("Collation",30)); + field_list.push_back(new Item_return_int("Id",11, FIELD_TYPE_SHORT)); + field_list.push_back(new Item_empty_string("Flags",30)); + field_list.push_back(new Item_return_int("strx_maxlen",3, FIELD_TYPE_SHORT)); + + if (protocol->send_fields(&field_list, 1)) + DBUG_RETURN(1); + + for ( cs= all_charsets ; cs < all_charsets+255 ; cs++ ) + { + CHARSET_INFO **cl; + for ( cl= all_charsets; cl < all_charsets+255 ;cl ++) + { + if (!cs[0] || !cl[0] || !my_charset_same(cs[0],cl[0]) || !(cs[0]->state & MY_CS_PRIMARY)) + continue; + if (cs[0] && !(wild && wild[0] && + wild_case_compare(system_charset_info,cl[0]->name,wild))) + { + if (write_collation(protocol, cl[0])) + goto err; + } + } + } + send_eof(thd); + DBUG_RETURN(0); +err: + DBUG_RETURN(1); +} + +static bool write_charset(Protocol *protocol, CHARSET_INFO *cs) +{ + protocol->prepare_for_resend(); + protocol->store(cs->csname, system_charset_info); + protocol->store(cs->name, system_charset_info); + protocol->store_short((longlong) cs->mbmaxlen); + return protocol->write(); +} + int mysqld_show_charsets(THD *thd, const char *wild) { char buff[8192]; @@ -1425,32 +1490,19 @@ int mysqld_show_charsets(THD *thd, const char *wild) DBUG_ENTER("mysqld_show_charsets"); - field_list.push_back(new Item_empty_string("CS_Name",30)); - field_list.push_back(new Item_empty_string("COL_Name",30)); - field_list.push_back(new Item_return_int("Id",11, FIELD_TYPE_SHORT)); - field_list.push_back(new Item_empty_string("Flags",30)); - field_list.push_back(new Item_return_int("strx_maxlen",3, FIELD_TYPE_TINY)); - field_list.push_back(new Item_return_int("mb_maxlen",3, FIELD_TYPE_TINY)); + field_list.push_back(new Item_empty_string("Charset",30)); + field_list.push_back(new Item_empty_string("Default collation",60)); + field_list.push_back(new Item_return_int("Maxlen",3, FIELD_TYPE_SHORT)); if (protocol->send_fields(&field_list, 1)) DBUG_RETURN(1); - for (cs=all_charsets ; cs < all_charsets+255 ; cs++ ) + for ( cs= all_charsets ; cs < all_charsets+255 ; cs++ ) { - if (cs[0] && !(wild && wild[0] && - wild_case_compare(system_charset_info,cs[0]->name,wild))) + if (cs[0] && (cs[0]->state & MY_CS_PRIMARY) && !(wild && wild[0] && + wild_case_compare(system_charset_info,cs[0]->name,wild))) { - protocol->prepare_for_resend(); - protocol->store(cs[0]->csname, system_charset_info); - protocol->store(cs[0]->name, system_charset_info); - protocol->store_short((longlong) cs[0]->number); - flags[0]='\0'; - if (cs[0]->state & MY_CS_PRIMARY) - strcat(flags,"pri"); - protocol->store(flags, system_charset_info); - protocol->store_tiny((longlong) cs[0]->strxfrm_multiply); - protocol->store_tiny((longlong) cs[0]->mbmaxlen); - if (protocol->write()) + if (write_charset(protocol, cs[0])) goto err; } } diff --git a/sql/sql_string.cc b/sql/sql_string.cc index ffa272713de..e29883c190b 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -30,7 +30,7 @@ CHARSET_INFO *system_charset_info= &my_charset_utf8; CHARSET_INFO *files_charset_info= &my_charset_utf8; -CHARSET_INFO *national_charset_info= &my_charset_utf8; +CHARSET_INFO *national_charset_info= &my_charset_latin1; extern gptr sql_alloc(unsigned size); extern void sql_element_free(void *ptr); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index af861875691..84c68d37c91 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3578,6 +3578,8 @@ show_param: } | charset wild { Lex->sql_command= SQLCOM_SHOW_CHARSETS; } + | COLLATION_SYM wild + { Lex->sql_command= SQLCOM_SHOW_COLLATIONS; } | LOGS_SYM { Lex->sql_command= SQLCOM_SHOW_LOGS; } | GRANTS FOR_SYM user