diff options
author | unknown <hf@deer.(none)> | 2004-12-21 10:05:58 +0400 |
---|---|---|
committer | unknown <hf@deer.(none)> | 2004-12-21 10:05:58 +0400 |
commit | fee2e57b675ba2e07bb9833ffbe18996fbf97ccb (patch) | |
tree | 5b4be1d54e8bacb1475e40f727a51cf4a942721e /libmysqld | |
parent | 4630d406d11a8e7c0e8dc4b8601fc8dd94e8a343 (diff) | |
download | mariadb-git-fee2e57b675ba2e07bb9833ffbe18996fbf97ccb.tar.gz |
Fix to perform correctly with charsets in embedded server
BitKeeper/deleted/.del-ctype_recoding.result.es~45c6fe567949af:
Delete: mysql-test/r/ctype_recoding.result.es
BitKeeper/deleted/.del-func_test.result.es~4de135264090aa14:
Delete: mysql-test/r/func_test.result.es
BitKeeper/deleted/.del-ps_2myisam.result.es~5132bde9c07c41e8:
Delete: mysql-test/r/ps_2myisam.result.es
BitKeeper/deleted/.del-ps_3innodb.result.es~a3613f0e86132472:
Delete: mysql-test/r/ps_3innodb.result.es
BitKeeper/deleted/.del-ps_4heap.result.es~956ae2c46b66b6ed:
Delete: mysql-test/r/ps_4heap.result.es
BitKeeper/deleted/.del-ps_5merge.result.es~6093a834fec21efe:
Delete: mysql-test/r/ps_5merge.result.es
BitKeeper/deleted/.del-ps_6bdb.result.es~57b94c3756e3d093:
Delete: mysql-test/r/ps_6bdb.result.es
libmysqld/lib_sql.cc:
Charset conversion implemented
mysql-test/r/query_cache.result.es:
correct test result provided
tests/client_test.c:
now it works
Diffstat (limited to 'libmysqld')
-rw-r--r-- | libmysqld/lib_sql.cc | 78 |
1 files changed, 52 insertions, 26 deletions
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 8092d87b97c..a9503c644a8 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -591,6 +591,32 @@ err: C_MODE_END +static char *dup_str_aux(MEM_ROOT *root, const char *from, uint length, + CHARSET_INFO *fromcs, CHARSET_INFO *tocs) +{ + uint32 dummy32; + uint dummy_err; + char *result; + + /* 'tocs' is set 0 when client issues SET character_set_results=NULL */ + if (tocs && String::needs_conversion(0, fromcs, tocs, &dummy32)) + { + uint new_len= (tocs->mbmaxlen * length) / fromcs->mbminlen + 1; + result= (char *)alloc_root(root, new_len); + length= copy_and_convert(result, new_len, + tocs, from, length, fromcs, &dummy_err); + } + else + { + result= (char *)alloc_root(root, length + 1); + memcpy(result, from, length); + } + + result[length]= 0; + return result; +} + + bool Protocol::send_fields(List<Item> *list, uint flag) { List_iterator_fast<Item> it(*list); @@ -598,6 +624,8 @@ bool Protocol::send_fields(List<Item> *list, uint flag) MYSQL_FIELD *client_field; MYSQL *mysql= thd->mysql; MEM_ROOT *field_alloc; + CHARSET_INFO *thd_cs= thd->variables.character_set_results; + CHARSET_INFO *cs= system_charset_info; DBUG_ENTER("send_fields"); @@ -616,12 +644,29 @@ bool Protocol::send_fields(List<Item> *list, uint flag) Send_field server_field; item->make_field(&server_field); - client_field->db= strdup_root(field_alloc, server_field.db_name); - client_field->table= strdup_root(field_alloc, server_field.table_name); - client_field->name= strdup_root(field_alloc, server_field.col_name); - client_field->org_table= strdup_root(field_alloc, server_field.org_table_name); - client_field->org_name= strdup_root(field_alloc, server_field.org_col_name); - client_field->length= server_field.length; + client_field->db= dup_str_aux(field_alloc, server_field.db_name, + strlen(server_field.db_name), cs, thd_cs); + client_field->table= dup_str_aux(field_alloc, server_field.table_name, + strlen(server_field.table_name), cs, thd_cs); + client_field->name= dup_str_aux(field_alloc, server_field.col_name, + strlen(server_field.col_name), cs, thd_cs); + client_field->org_table= dup_str_aux(field_alloc, server_field.org_table_name, + strlen(server_field.org_table_name), cs, thd_cs); + client_field->org_name= dup_str_aux(field_alloc, server_field.org_col_name, + strlen(server_field.org_col_name), cs, thd_cs); + if (item->collation.collation == &my_charset_bin || thd_cs == NULL) + { + /* No conversion */ + client_field->charsetnr= server_field.charsetnr; + client_field->length= server_field.length; + } + else + { + /* With conversion */ + client_field->charsetnr= thd_cs->number; + uint char_len= server_field.length / item->collation.collation->mbmaxlen; + client_field->length= char_len * thd_cs->mbmaxlen; + } client_field->type= server_field.type; client_field->flags= server_field.flags; client_field->decimals= server_field.decimals; @@ -630,9 +675,8 @@ bool Protocol::send_fields(List<Item> *list, uint flag) client_field->name_length= strlen(client_field->name); client_field->org_name_length= strlen(client_field->org_name); client_field->org_table_length= strlen(client_field->org_table); - client_field->charsetnr= server_field.charsetnr; - client_field->catalog= strdup_root(field_alloc, "def"); + client_field->catalog= dup_str_aux(field_alloc, "def", 3, cs, thd_cs); client_field->catalog_length= 3; if (INTERNAL_NUM_FIELD(client_field)) @@ -804,21 +848,3 @@ 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) -{ - if (!(*next_field=alloc_root(alloc, length + 1))) - return true; - convert->store_dest(*next_field, from, length); - (*next_field)[length]= 0; - if (next_mysql_field->max_length < length) - next_mysql_field->max_length=length; - ++next_field; - ++next_mysql_field; - - return false; -} -#endif - |