From afd0b37816835463ba5c7436732e77690b90c011 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Mon, 1 Dec 2003 17:19:10 +0400 Subject: [PATCH 01/13] SCRUM WL#1246 (Query cache in embedded library) --- libmysqld/Makefile.am | 4 +- libmysqld/emb_qcache.cc | 430 ++++++++++++++++++++++++++++++++++++++++ libmysqld/emb_qcache.h | 61 ++++++ libmysqld/lib_sql.cc | 9 + sql/sql_cache.cc | 41 +++- sql/sql_cache.h | 4 +- sql/sql_parse.cc | 6 +- 7 files changed, 535 insertions(+), 20 deletions(-) create mode 100644 libmysqld/emb_qcache.cc create mode 100644 libmysqld/emb_qcache.h diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index 95cbd4ec826..e51fb5e315e 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -33,10 +33,10 @@ INCLUDES= @MT_INCLUDES@ @bdb_includes@ -I$(top_srcdir)/include \ noinst_LIBRARIES = libmysqld_int.a pkglib_LIBRARIES = libmysqld.a SUBDIRS = . examples -libmysqld_sources= libmysqld.c lib_sql.cc +libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c -noinst_HEADERS = embedded_priv.h +noinst_HEADERS = embedded_priv.h emb_qcache.h sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \ ha_innodb.cc ha_berkeley.cc ha_heap.cc ha_isam.cc ha_isammrg.cc \ diff --git a/libmysqld/emb_qcache.cc b/libmysqld/emb_qcache.cc new file mode 100644 index 00000000000..0374ab58784 --- /dev/null +++ b/libmysqld/emb_qcache.cc @@ -0,0 +1,430 @@ +/* Copyright (C) 2000-2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include "mysql_priv.h" +#ifdef HAVE_QUERY_CACHE +#include +#include "emb_qcache.h" + +void Querycache_stream::store_char(char c) +{ + if (data_end == cur_data) + use_next_block(); + *(cur_data++)= c; +#ifndef DBUG_OFF + stored_size++; +#endif +} + +void Querycache_stream::store_short(ushort s) +{ +#ifndef DBUG_OFF + stored_size+= 2; +#endif + if (data_end - cur_data > 1) + { + int2store(cur_data, s); + cur_data+= 2; + return; + } + if (data_end == cur_data) + { + use_next_block(); + int2store(cur_data, s); + cur_data+= 2; + return; + } + *cur_data= ((byte *)(&s))[0]; + use_next_block(); + *(cur_data++)= ((byte *)(&s))[1]; +} + +void Querycache_stream::store_int(uint i) +{ +#ifndef DBUG_OFF + stored_size+= 4; +#endif + size_t rest_len= data_end - cur_data; + if (rest_len > 3) + { + int4store(cur_data, i); + cur_data+= 4; + return; + } + if (!rest_len) + { + use_next_block(); + int4store(cur_data, i); + cur_data+= 4; + return; + } + memcpy(cur_data, &i, rest_len); + use_next_block(); + memcpy(cur_data, ((byte*)&i)+rest_len, 4-rest_len); + cur_data+= 4-rest_len; +} + +void Querycache_stream::store_ll(ulonglong ll) +{ +#ifndef DBUG_OFF + stored_size+= 8; +#endif + size_t rest_len= data_end - cur_data; + if (rest_len > 7) + { + int8store(cur_data, ll); + cur_data+= 8; + return; + } + if (!rest_len) + { + use_next_block(); + int8store(cur_data, ll); + cur_data+= 8; + return; + } + memcpy(cur_data, &ll, rest_len); + use_next_block(); + memcpy(cur_data, ((byte*)&ll)+rest_len, 8-rest_len); + cur_data+= 8-rest_len; +} + +void Querycache_stream::store_str_only(const char *str, uint str_len) +{ +#ifndef DBUG_OFF + stored_size+= str_len; +#endif + do + { + size_t rest_len= data_end - cur_data; + if (rest_len > str_len) + { + memcpy(cur_data, str, str_len); + cur_data+= str_len; + return; + } + memcpy(cur_data, str, rest_len); + use_next_block(); + str_len-= rest_len; + str+= rest_len; + } while(str_len); +} + +void Querycache_stream::store_str(const char *str, uint str_len) +{ + store_int(str_len); + store_str_only(str, str_len); +} + +void Querycache_stream::store_safe_str(const char *str, uint str_len) +{ + if (str) + { + store_int(str_len+1); + store_str_only(str, str_len); + } + else + store_int(0); +} + +char Querycache_stream::load_char() +{ + if (cur_data == data_end) + use_next_block(); + return *(cur_data++); +} + +ushort Querycache_stream::load_short() +{ + ushort result; + if (data_end-cur_data > 1) + { + result= uint2korr(cur_data); + cur_data+= 2; + return result; + } + if (data_end == cur_data) + { + use_next_block(); + result= uint2korr(cur_data); + cur_data+= 2; + return result; + } + ((byte*)&result)[0]= *cur_data; + use_next_block(); + ((byte*)&result)[1]= *(cur_data++); + return result; +} + +uint Querycache_stream::load_int() +{ + int result; + size_t rest_len= data_end - cur_data; + if (rest_len > 3) + { + result= uint4korr(cur_data); + cur_data+= 4; + return result; + } + if (!rest_len) + { + use_next_block(); + result= uint4korr(cur_data); + cur_data+= 4; + return result; + } + memcpy(&result, cur_data, rest_len); + use_next_block(); + memcpy(((byte*)&result)+rest_len, cur_data, 4-rest_len); + cur_data+= 4-rest_len; + return result; +} + +ulonglong Querycache_stream::load_ll() +{ + ulonglong result; + size_t rest_len= data_end - cur_data; + if (rest_len > 7) + { + result= uint8korr(cur_data); + cur_data+= 8; + return result; + } + if (!rest_len) + { + use_next_block(); + result= uint8korr(cur_data); + cur_data+= 8; + return result; + } + memcpy(&result, cur_data, rest_len); + use_next_block(); + memcpy(((byte*)&result)+rest_len, cur_data, 8-rest_len); + cur_data+= 8-rest_len; + return result; +} + +void Querycache_stream::load_str_only(char *buffer, uint str_len) +{ + do + { + size_t rest_len= data_end - cur_data; + if (rest_len > str_len) + { + memcpy(buffer, cur_data, str_len); + cur_data+= str_len; + buffer+= str_len; + break; + } + memcpy(buffer, cur_data, rest_len); + use_next_block(); + str_len-= rest_len; + buffer+= rest_len; + } while(str_len); + *buffer= 0; +} + +char *Querycache_stream::load_str(MEM_ROOT *alloc, uint *str_len) +{ + char *result; + *str_len= load_int(); + if (!(result= alloc_root(alloc, *str_len + 1))) + return 0; + load_str_only(result, *str_len); + return result; +} + +int Querycache_stream::load_safe_str(MEM_ROOT *alloc, char **str, uint *str_len) +{ + if (!(*str_len= load_int())) + { + *str= NULL; + return 0; + } + (*str_len)--; + if (!(*str= alloc_root(alloc, *str_len + 1))) + return 1; + load_str_only(*str, *str_len); + return 0; +} + +int Querycache_stream::load_column(MEM_ROOT *alloc, char** column) +{ + int len; + if (!(len = load_int())) + { + *column= NULL; + return 0; + } + len--; + if (!(*column= (char *)alloc_root(alloc, len + 4 + 1))) + return 1; + int4store(*column, len); + (*column)+= 4; + load_str_only(*column, len); + return 1; +} + +uint emb_count_querycache_size(THD *thd) +{ + uint result; + MYSQL *mysql= thd->mysql; + MYSQL_FIELD *field= mysql->fields; + MYSQL_FIELD *field_end= field + mysql->field_count; + + *thd->data->prev_ptr= NULL; // this marks the last record + MYSQL_ROWS *cur_row= thd->data->data; + + result= 4+8 + (42 + 4*thd->data->rows)*mysql->field_count; + + for(; field < field_end; field++) + { + result+= field->name_length + field->table_length + + field->org_name_length + field->org_table_length + field->db_length + + field->catalog_length; + if (field->def) + result+= field->def_length; + } + + for (; cur_row; cur_row=cur_row->next) + { + MYSQL_ROW col= cur_row->data; + MYSQL_ROW col_end= col + mysql->field_count; + for (; col < col_end; col++) + if (*col) + result+= *(uint *)((*col) - sizeof(uint)); + } + return result; +} + +void emb_store_querycache_result(Querycache_stream *dst, THD *thd) +{ + MYSQL *mysql= thd->mysql; + MYSQL_FIELD *field= mysql->fields; + MYSQL_FIELD *field_end= field + mysql->field_count; + + *thd->data->prev_ptr= NULL; // this marks the last record + MYSQL_ROWS *cur_row= thd->data->data; + + dst->store_int((uint)mysql->field_count); + dst->store_ll((uint)thd->data->rows); + + for(; field < field_end; field++) + { + dst->store_int((uint)field->length); + dst->store_int((uint)field->max_length); + dst->store_char((char)field->type); + dst->store_short((ushort)field->flags); + dst->store_short((ushort)field->charsetnr); + dst->store_char((char)field->decimals); + dst->store_str(field->name, field->name_length); + dst->store_str(field->table, field->table_length); + dst->store_str(field->org_name, field->org_name_length); + dst->store_str(field->org_table, field->org_table_length); + dst->store_str(field->db, field->db_length); + dst->store_str(field->catalog, field->catalog_length); + + dst->store_safe_str(field->def, field->def_length); + } + + for (; cur_row; cur_row=cur_row->next) + { + MYSQL_ROW col= cur_row->data; + MYSQL_ROW col_end= col + mysql->field_count; + for (; col < col_end; col++) + { + uint len= *col ? *(uint *)((*col) - sizeof(uint)) : 0; + dst->store_safe_str(*col, len); + } + } + DBUG_ASSERT(emb_count_querycache_size(thd) == dst->stored_size); +} + +int emb_load_querycache_result(THD *thd, Querycache_stream *src) +{ + MYSQL *mysql= thd->mysql; + MYSQL_DATA *data; + MYSQL_FIELD *field; + MYSQL_FIELD *field_end; + MEM_ROOT *f_alloc= &mysql->field_alloc; + MYSQL_ROWS *row, *end_row; + MYSQL_ROWS **prev_row; + ulonglong rows; + MYSQL_ROW columns; + + mysql->field_count= src->load_int(); + rows= src->load_ll(); + + if (!(field= (MYSQL_FIELD *) + alloc_root(&mysql->field_alloc,mysql->field_count*sizeof(MYSQL_FIELD)))) + goto err; + mysql->fields= field; + for(field_end= field+mysql->field_count; field < field_end; field++) + { + field->length= src->load_int(); + field->max_length= (unsigned int)src->load_int(); + field->type= (enum enum_field_types)src->load_char(); + field->flags= (unsigned int)src->load_short(); + field->charsetnr= (unsigned int)src->load_short(); + field->decimals= (unsigned int)src->load_char(); + + if (!(field->name= src->load_str(f_alloc, &field->name_length)) || + !(field->table= src->load_str(f_alloc,&field->table_length)) || + !(field->org_name= src->load_str(f_alloc, &field->org_name_length)) || + !(field->org_table= src->load_str(f_alloc, &field->org_table_length))|| + !(field->db= src->load_str(f_alloc, &field->db_length)) || + !(field->catalog= src->load_str(f_alloc, &field->catalog_length)) || + src->load_safe_str(f_alloc, &field->def, &field->def_length)) + goto err; + } + + if (!rows) + return 0; + if (!(data= (MYSQL_DATA*)my_malloc(sizeof(MYSQL_DATA), + MYF(MY_WME | MY_ZEROFILL)))) + goto err; + thd->data= data; + init_alloc_root(&data->alloc, 8192,0); + row= (MYSQL_ROWS *)alloc_root(&data->alloc, rows * sizeof(MYSQL_ROWS) + + rows * (mysql->field_count+1)*sizeof(char*)); + end_row= row + rows; + columns= (MYSQL_ROW)end_row; + + data->rows= rows; + data->fields= mysql->field_count; + data->data= row; + + for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++) + { + *prev_row= row; + row->data= columns; + MYSQL_ROW col_end= columns + mysql->field_count; + uint len; + for (; columns < col_end; columns++) + src->load_column(&data->alloc, columns); + + *(columns++)= NULL; + } + *prev_row= NULL; + data->prev_ptr= prev_row; + + return 0; +err: + return 1; +} + +#endif /*HAVE_QUERY_CACHE*/ + diff --git a/libmysqld/emb_qcache.h b/libmysqld/emb_qcache.h new file mode 100644 index 00000000000..32ce19847ff --- /dev/null +++ b/libmysqld/emb_qcache.h @@ -0,0 +1,61 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +class Querycache_stream +{ + byte *cur_data; + byte *data_end; + Query_cache_block *block; + uint headers_len; +public: +#ifndef DBUG_OFF + uint stored_size; +#endif + Querycache_stream(Query_cache_block *ini_block, uint ini_headers_len) : + block(ini_block), headers_len(ini_headers_len) + { + use_next_block(); +#ifndef DBUG_OFF + stored_size= 0; +#endif + } + void use_next_block() + { + cur_data= ((byte*)block)+headers_len; + data_end= cur_data + (block->used-headers_len); + } + + void store_char(char c); + void store_short(ushort s); + void store_int(uint i); + void store_ll(ulonglong ll); + void store_str_only(const char *str, uint str_len); + void store_str(const char *str, uint str_len); + void store_safe_str(const char *str, uint str_len); + + char load_char(); + ushort load_short(); + uint load_int(); + ulonglong load_ll(); + void load_str_only(char *buffer, uint str_len); + char *load_str(MEM_ROOT *alloc, uint *str_len); + int load_safe_str(MEM_ROOT *alloc, char **str, uint *str_len); + int load_column(MEM_ROOT *alloc, char **column); +}; + +uint emb_count_querycache_size(THD *thd); +int emb_load_querycache_result(THD *thd, Querycache_stream *src); +void emb_store_querycache_result(Querycache_stream *dst, THD* thd); diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index d4cb916a89c..4e003b1d450 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -573,6 +573,9 @@ bool Protocol::send_fields(List *list, uint flag) 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, "std"); + client_field->catalog_length= 3; if (INTERNAL_NUM_FIELD(client_field)) client_field->flags|= NUM_FLAG; @@ -583,9 +586,15 @@ bool Protocol::send_fields(List *list, uint flag) String tmp(buff, sizeof(buff), default_charset_info), *res; if (!(res=item->val_str(&tmp))) + { client_field->def= strdup_root(field_alloc, ""); + client_field->def_length= 0; + } else + { client_field->def= strdup_root(field_alloc, tmp.ptr()); + client_field->def_length= tmp.length(); + } } else client_field->def=0; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 396764cd532..3c77d72947f 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -308,6 +308,10 @@ TODO list: #include "../myisammrg/myrg_def.h" #endif +#ifdef EMBEDDED_LIBRARY +#include "emb_qcache.h" +#endif + #if defined(EXTRA_DEBUG) && !defined(DBUG_OFF) #define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \ pthread_mutex_lock(M);} @@ -646,20 +650,24 @@ void query_cache_abort(NET *net) } -void query_cache_end_of_result(NET *net) +void query_cache_end_of_result(THD *thd) { DBUG_ENTER("query_cache_end_of_result"); +#ifdef EMBEDDED_LIBRARY + query_cache_insert(&thd->net, (byte*)thd, + emb_count_querycache_size(thd)); +#endif #ifndef DBUG_OFF // Check if we have called query_cache.wreck() (which disables the cache) if (query_cache.query_cache_size == 0) DBUG_VOID_RETURN; #endif - if (net->query_cache_query != 0) // Quick check on unlocked structure + if (thd->net.query_cache_query != 0) // Quick check on unlocked structure { STRUCT_LOCK(&query_cache.structure_guard_mutex); Query_cache_block *query_block = ((Query_cache_block*) - net->query_cache_query); + thd->net.query_cache_query); if (query_block) { DUMP(&query_cache); @@ -691,7 +699,7 @@ void query_cache_end_of_result(NET *net) // Cache was flushed or resized and query was deleted => do nothing STRUCT_UNLOCK(&query_cache.structure_guard_mutex); } - net->query_cache_query=0; + thd->net.query_cache_query=0; DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0);); } DBUG_VOID_RETURN; @@ -1052,23 +1060,29 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) /* Send cached result to client */ +#ifndef EMBEDDED_LIBRARY do { DBUG_PRINT("qcache", ("Results (len %lu, used %lu, headers %lu)", - result_block->length, result_block->used, - result_block->headers_len()+ - ALIGN_SIZE(sizeof(Query_cache_result)))); - + result_block->length, result_block->used, + result_block->headers_len()+ + ALIGN_SIZE(sizeof(Query_cache_result)))); + Query_cache_result *result = result_block->result(); -#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/ if (net_real_write(&thd->net, result->data(), result_block->used - result_block->headers_len() - ALIGN_SIZE(sizeof(Query_cache_result)))) break; // Client aborted -#endif result_block = result_block->next; } while (result_block != first_result_block); +#else + { + Querycache_stream qs(result_block, result_block->headers_len() + + ALIGN_SIZE(sizeof(Query_cache_result))); + emb_load_querycache_result(thd, &qs); + } +#endif /*!EMBEDDED_LIBRARY*/ thd->limit_found_rows = query->found_rows(); @@ -1784,18 +1798,23 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block, Query_cache_block *block = *result_block; uint headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) + ALIGN_SIZE(sizeof(Query_cache_result))); +#ifndef EMBEDDED_LIBRARY // Now fill list of blocks that created by allocate_data_chain do { block->type = type; ulong length = block->used - headers_len; DBUG_PRINT("qcache", ("write %lu byte in block 0x%lx",length, - (ulong)block)); + (ulong)block)); memcpy((void*)(((byte*) block)+headers_len), (void*) rest, length); rest += length; block = block->next; type = Query_cache_block::RES_CONT; } while (block != *result_block); +#else + Querycache_stream qs(*result_block, headers_len); + emb_store_querycache_result(&qs, (THD*)data); +#endif /*!EMBEDDED_LIBRARY*/ } else { diff --git a/sql/sql_cache.h b/sql/sql_cache.h index 68e69ab523f..ac4f465bf79 100644 --- a/sql/sql_cache.h +++ b/sql/sql_cache.h @@ -392,7 +392,7 @@ protected: void destroy(); friend void query_cache_insert(NET *net, const char *packet, ulong length); - friend void query_cache_end_of_result(NET *net); + friend void query_cache_end_of_result(THD *thd); friend void query_cache_abort(NET *net); /* @@ -416,7 +416,7 @@ protected: extern Query_cache query_cache; extern TYPELIB query_cache_type_typelib; -void query_cache_end_of_result(NET *net); +void query_cache_end_of_result(THD *thd); void query_cache_abort(NET *net); #endif diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c50bfc43862..cc4fe60580c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3886,9 +3886,7 @@ mysql_parse(THD *thd, char *inBuf, uint length) else { mysql_execute_command(thd); -#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/ - query_cache_end_of_result(&thd->net); -#endif + query_cache_end_of_result(thd); } } } @@ -3896,9 +3894,7 @@ mysql_parse(THD *thd, char *inBuf, uint length) { DBUG_PRINT("info",("Command aborted. Fatal_error: %d", thd->is_fatal_error)); -#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/ query_cache_abort(&thd->net); -#endif } thd->proc_info="freeing items"; free_items(thd->free_list); /* Free strings used by items */ From 210a87507cc5501a6921dcb199a4db4c90e956c5 Mon Sep 17 00:00:00 2001 From: "bar@bar.intranet.mysql.r18.ru" <> Date: Mon, 29 Dec 2003 19:58:18 +0400 Subject: [PATCH 02/13] latin1.xml, Index.xml: Modern Spanish collation --- sql/share/charsets/Index.xml | 3 ++- sql/share/charsets/latin1.xml | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/sql/share/charsets/Index.xml b/sql/share/charsets/Index.xml index 3661784325c..f21e03de8b2 100644 --- a/sql/share/charsets/Index.xml +++ b/sql/share/charsets/Index.xml @@ -1,6 +1,6 @@ - + This file lists all of the available character sets. @@ -100,6 +100,7 @@ To make maintaining easier please: + binary compiled diff --git a/sql/share/charsets/latin1.xml b/sql/share/charsets/latin1.xml index 9e11be39ad6..178fd07e7f6 100644 --- a/sql/share/charsets/latin1.xml +++ b/sql/share/charsets/latin1.xml @@ -209,6 +209,27 @@ + + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 51 53 57 5B 65 67 69 6B 75 77 79 7B 7D 81 + 8F 91 93 95 98 9A A4 A6 A8 AA AF B3 B4 B5 B6 B7 + B8 41 51 53 57 5B 65 67 69 6B 75 77 79 7B 7D 81 + 8F 91 93 95 98 9A A4 A6 A8 AA AF B9 BA BB BC BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + 41 41 41 41 41 41 41 53 5B 5B 5B 5B 6B 6B 6B 6B + 57 7F 81 81 81 81 81 BD 81 9A 9A 9A 9A AA B1 97 + 41 41 41 41 41 41 41 53 5B 5B 5B 5B 6B 6B 6B 6B + 57 7F 81 81 81 81 81 BE 81 9A 9A 9A 9A AA B1 AA + + + From 934f08c5d1088f133e174682091fa9c60e6d83ec Mon Sep 17 00:00:00 2001 From: "jani@rhols221.adsl.netsonic.fi" <> Date: Tue, 30 Dec 2003 17:58:39 +0200 Subject: [PATCH 03/13] Fixed Bug#1472, mysql \h output out of order. --- client/mysql.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index d2bed5519bf..e3945e8aa2f 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -227,11 +227,12 @@ typedef struct { } COMMANDS; static COMMANDS commands[] = { - { "help", 'h', com_help, 1, "Display this help." }, { "?", '?', com_help, 1, "Synonym for `help'." }, { "clear", 'c', com_clear, 0, "Clear command."}, { "connect",'r', com_connect,1, "Reconnect to the server. Optional arguments are db and host." }, + { "delimiter", 'd', com_delimiter, 1, + "Set query delimiter. " }, #ifdef USE_POPEN { "edit", 'e', com_edit, 0, "Edit command with $EDITOR."}, #endif @@ -239,6 +240,7 @@ static COMMANDS commands[] = { "Send command to mysql server, display result vertically."}, { "exit", 'q', com_quit, 0, "Exit mysql. Same as quit."}, { "go", 'g', com_go, 0, "Send command to mysql server." }, + { "help", 'h', com_help, 1, "Display this help." }, #ifdef USE_POPEN { "nopager",'n', com_nopager,0, "Disable pager, print to stdout." }, #endif @@ -261,8 +263,6 @@ static COMMANDS commands[] = { "Set outfile [to_outfile]. Append everything into given outfile." }, { "use", 'u', com_use, 1, "Use another database. Takes database name as argument." }, - { "delimiter", 'd', com_delimiter, 1, - "Set query delimiter. " }, /* Get bash-like expansion for some commands */ { "create table", 0, 0, 0, ""}, { "create database", 0, 0, 0, ""}, @@ -1577,8 +1577,8 @@ static int com_help(String *buffer __attribute__((unused)), char *line __attribute__((unused))) { - reg1 int i; - char * help_arg= strchr(line,' '); + reg1 int i, j; + char * help_arg= strchr(line,' '), buff[32], *end; if (help_arg) return com_server_help(buffer,line,help_arg+1); @@ -1591,8 +1591,11 @@ com_help(String *buffer __attribute__((unused)), put_info("Note that all text commands must be first on line and end with ';'",INFO_INFO); for (i = 0; commands[i].name; i++) { + end= strmov(buff, commands[i].name); + for (j= strlen(commands[i].name); j < 10; j++) + end= strmov(end, " "); if (commands[i].func) - tee_fprintf(stdout, "%s\t(\\%c)\t%s\n", commands[i].name, + tee_fprintf(stdout, "%s(\\%c) %s\n", buff, commands[i].cmd_char, commands[i].doc); } if (connected && mysql_get_server_version(&mysql) >= 40100) From 39559d4817d27fbeaf85196d2129bed8b9a00f2d Mon Sep 17 00:00:00 2001 From: "bar@bar.intranet.mysql.r18.ru" <> Date: Wed, 31 Dec 2003 19:01:03 +0400 Subject: [PATCH 04/13] #2244 User variables collation conflict is not detected --- mysql-test/r/user_var.result | 42 ++++++++++++++++++++++++++++++++++++ mysql-test/t/user_var.test | 28 ++++++++++++++++++++++++ sql/item_func.cc | 6 +++++- 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index fc3dc4eddcd..a9351d2f1fb 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -120,3 +120,45 @@ select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i; 1 3 2 0 3 6 3 0 drop table t1; +set @a=_latin2'test'; +select charset(@a),collation(@a),coercibility(@a); +charset(@a) collation(@a) coercibility(@a) +latin2 latin2_general_ci 3 +select @a=_latin2'TEST'; +@a=_latin2'TEST' +1 +select @a=_latin2'TEST' collate latin2_bin; +@a=_latin2'TEST' collate latin2_bin +0 +set @a=_latin2'test' collate latin2_general_ci; +select charset(@a),collation(@a),coercibility(@a); +charset(@a) collation(@a) coercibility(@a) +latin2 latin2_general_ci 0 +select @a=_latin2'TEST'; +@a=_latin2'TEST' +1 +select @a=_latin2'TEST' collate latin2_bin; +ERROR HY000: Illegal mix of collations (latin2_general_ci,EXPLICIT) and (latin2_bin,EXPLICIT) for operation '=' +select charset(@a:=_latin2'test'); +charset(@a:=_latin2'test') +latin2 +select collation(@a:=_latin2'test'); +collation(@a:=_latin2'test') +latin2_general_ci +select coercibility(@a:=_latin2'test'); +coercibility(@a:=_latin2'test') +3 +select collation(@a:=_latin2'test' collate latin2_bin); +collation(@a:=_latin2'test' collate latin2_bin) +latin2_bin +select coercibility(@a:=_latin2'test' collate latin2_bin); +coercibility(@a:=_latin2'test' collate latin2_bin) +0 +select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST'; +(@a:=_latin2'test' collate latin2_bin) = _latin2'TEST' +0 +select charset(@a),collation(@a),coercibility(@a); +charset(@a) collation(@a) coercibility(@a) +latin2 latin2_bin 0 +select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST' collate latin2_general_ci; +ERROR HY000: Illegal mix of collations (latin2_bin,EXPLICIT) and (latin2_general_ci,EXPLICIT) for operation '=' diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index 39742d20c7c..32ed6fe33db 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -71,3 +71,31 @@ select @a:=0; select @a, @a:=@a+count(*), count(*), @a from t1 group by i; select @a:=0; select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i; drop table t1; +# +# Bug #2244: User variables didn't copy collation and derivation +# attributes from values they were initialized to. +# + +set @a=_latin2'test'; +select charset(@a),collation(@a),coercibility(@a); +select @a=_latin2'TEST'; +select @a=_latin2'TEST' collate latin2_bin; + +set @a=_latin2'test' collate latin2_general_ci; +select charset(@a),collation(@a),coercibility(@a); +select @a=_latin2'TEST'; +--error 1266 +select @a=_latin2'TEST' collate latin2_bin; + +# +# Check the same invoking Item_set_user_var +# +select charset(@a:=_latin2'test'); +select collation(@a:=_latin2'test'); +select coercibility(@a:=_latin2'test'); +select collation(@a:=_latin2'test' collate latin2_bin); +select coercibility(@a:=_latin2'test' collate latin2_bin); +select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST'; +select charset(@a),collation(@a),coercibility(@a); +--error 1266 +select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST' collate latin2_general_ci; diff --git a/sql/item_func.cc b/sql/item_func.cc index a251be402ce..5af64ca0be4 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2163,6 +2163,7 @@ bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables, is different from query_id). */ entry->update_query_id= thd->query_id; + entry->collation.set(args[0]->collation); cached_result_type= args[0]->result_type(); return 0; } @@ -2174,6 +2175,7 @@ Item_func_set_user_var::fix_length_and_dec() maybe_null=args[0]->maybe_null; max_length=args[0]->max_length; decimals=args[0]->decimals; + collation.set(args[0]->collation); } @@ -2488,7 +2490,9 @@ void Item_func_get_user_var::fix_length_and_dec() if (!(var_entry= get_variable(&thd->user_vars, name, 0))) null_value= 1; - + else + collation.set(var_entry->collation); + if (!(opt_bin_log && is_update_query(thd->lex->sql_command))) return; From 1c74cd9bf515ac1f1cfef6ed58ad2aa77b76be2c Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Thu, 1 Jan 2004 01:51:36 +0200 Subject: [PATCH 05/13] row0purge.c: Fix bug: if purge of a table was not possible because its .ibd file was missing, trx->dict_operation_lock_mode was left to a wrong value, causing an assertion failure --- innobase/row/row0purge.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c index a455722f15a..d5895f20461 100644 --- a/innobase/row/row0purge.c +++ b/innobase/row/row0purge.c @@ -534,6 +534,8 @@ row_purge_parse_undo_rec( node->table = NULL; + row_mysql_unfreeze_data_dictionary(trx); + return(FALSE); } From 7bb74b6592583656512571e4af1b04d36849d020 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Fri, 2 Jan 2004 16:21:58 +0200 Subject: [PATCH 06/13] log0recv.h, log0recv.c: Merge a log replay change required by ibbackup --- innobase/include/log0recv.h | 2 ++ innobase/log/log0recv.c | 24 ++++++++++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/innobase/include/log0recv.h b/innobase/include/log0recv.h index 5991960e8ae..c972c3ce977 100644 --- a/innobase/include/log0recv.h +++ b/innobase/include/log0recv.h @@ -15,6 +15,8 @@ Created 9/20/1997 Heikki Tuuri #include "hash0hash.h" #include "log0log.h" +extern ibool recv_replay_file_ops; + /*********************************************************************** Reads the checkpoint info needed in hot backup. */ diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index b01474753bd..01679a374b0 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -34,6 +34,11 @@ Created 9/20/1997 Heikki Tuuri #include "dict0boot.h" #include "fil0fil.h" +/* This is set to FALSE if the backup was originally taken with the +ibbackup --include regexp option: then we do not want to create tables in +directories which were not included */ +ibool recv_replay_file_ops = TRUE; + /* Log records are stored in the hash table in chunks at most of this size; this must be less than UNIV_PAGE_SIZE as it is stored in the buffer pool */ #define RECV_DATA_BLOCK_SIZE (MEM_MAX_ALLOC_IN_BUF - sizeof(recv_data_t)) @@ -1974,18 +1979,21 @@ loop: || type == MLOG_FILE_RENAME || type == MLOG_FILE_DELETE)) { #ifdef UNIV_HOTBACKUP - /* In ibbackup --apply-log, replay an .ibd file - operation, if possible; note that - fil_path_to_mysql_datadir is set in ibbackup to - point to the datadir we should use there */ + if (recv_replay_file_ops) { + + /* In ibbackup --apply-log, replay an .ibd file + operation, if possible; note that + fil_path_to_mysql_datadir is set in ibbackup to + point to the datadir we should use there */ - if (NULL == fil_op_log_parse_or_replay(body, end_ptr, - type, TRUE, space)) { - fprintf(stderr, + if (NULL == fil_op_log_parse_or_replay(body, + end_ptr, type, TRUE, space)) { + fprintf(stderr, "InnoDB: Error: file op log record of type %lu space %lu not complete in\n" "InnoDB: the replay phase. Path %s\n", (ulint)type, space, (char*)(body + 2)); - ut_a(0); + ut_a(0); + } } #endif /* In normal mysqld crash recovery we do not try to From 5ec1adee44d99c61be5c73f7d461bb3af46bab3b Mon Sep 17 00:00:00 2001 From: "jani@rhols221.adsl.netsonic.fi" <> Date: Mon, 5 Jan 2004 21:45:14 +0200 Subject: [PATCH 07/13] Fixed Bug#2205. --- client/mysql.cc | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index e3945e8aa2f..2ce0d769924 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2436,8 +2436,9 @@ com_delimiter(String *buffer __attribute__((unused)), char *line) static int com_use(String *buffer __attribute__((unused)), char *line) { - char *tmp; - char buff[256]; + char *tmp, buff[FN_REFLEN + 1]; + MYSQL_RES *res; + MYSQL_ROW row; bzero(buff, sizeof(buff)); strmov(buff, line); @@ -2447,6 +2448,31 @@ com_use(String *buffer __attribute__((unused)), char *line) put_info("USE must be followed by a database name", INFO_ERROR); return 0; } + + /* + We need to recheck the current database, because it may change + under our feet, for example if DROP DATABASE or RENAME DATABASE + (latter one not yet available by the time the comment was written) + */ + current_db= 0; // Let's reset current_db, assume it's gone + /* + We don't care about in case of an error below because current_db + was just set to 0. + */ + if (!mysql_query(&mysql, "SELECT DATABASE()") && + (res= mysql_use_result(&mysql))) + { + row= mysql_fetch_row(res); + if (row[0] && + (!current_db || cmp_database(charset_info, current_db, row[0]))) + { + my_free(current_db, MYF(MY_ALLOW_ZERO_PTR)); + current_db= my_strdup(row[0], MYF(MY_WME)); + } + (void) mysql_fetch_row(res); // Read eof + mysql_free_result(res); + } + if (!current_db || cmp_database(charset_info, current_db, tmp)) { if (one_database) From fe6250488e1ce90cb5725724138b5dfdab6871bb Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Tue, 6 Jan 2004 13:10:57 +0200 Subject: [PATCH 08/13] srv0start.c: Add comment that the insert buffer format changed between 4.0 and 4.1.1, but the undo log format did not --- innobase/srv/srv0start.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 5fe66f515bc..9dd270b6e15 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1603,6 +1603,19 @@ NetWare. */ fflush(stderr); if (trx_doublewrite_must_reset_space_ids) { + /* Actually, we did not change the undo log format between + 4.0 and 4.1.1, and we would not need to run purge to + completion. Note also that the purge algorithm in 4.1.1 + can process the the history list again even after a full + purge, because our algorithm does not cut the end of the + history list in all cases so that it would become empty + after a full purge. That mean that we may purge 4.0 type + undo log even after this phase. + + The insert buffer record format changed between 4.0 and + 4.1.1. It is essential that the insert buffer is emptied + here! */ + fprintf(stderr, "InnoDB: You are upgrading to an InnoDB version which allows multiple\n" "InnoDB: tablespaces. Wait that purge and insert buffer merge run to\n" From 41d0719cc33e6df60577dca52cc114e1a1cae615 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Tue, 6 Jan 2004 20:03:06 +0200 Subject: [PATCH 09/13] srv0start.c: More instructions about a downgrade 4.1.1 -> 4.0.18 --- innobase/srv/srv0start.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 9dd270b6e15..d7a14b8a9ec 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1638,8 +1638,9 @@ NetWare. */ fprintf(stderr, "InnoDB: You have now successfully upgraded to the multiple tablespaces\n" -"InnoDB: format. You should not downgrade again to an earlier version of\n" -"InnoDB: InnoDB!\n"); +"InnoDB: format. You should NOT DOWNGRADE again to an earlier version of\n" +"InnoDB: InnoDB! But if you absolutely need to downgrade, see section 4.6 of\n" +"InnoDB: http://www.innodb.com/ibman.php for instructions.\n"); } if (srv_force_recovery == 0) { From d6545ace0aa9a06cbbb33f8cc8b2be88e449306b Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Wed, 7 Jan 2004 14:45:04 +0400 Subject: [PATCH 10/13] SCRUM WL#1246 (Query cache in embedded library) Small fix - code removed that prevents using query cache in embedded library --- include/mysql_embed.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/mysql_embed.h b/include/mysql_embed.h index df358e29872..7a169d4133e 100644 --- a/include/mysql_embed.h +++ b/include/mysql_embed.h @@ -32,6 +32,4 @@ #undef MYSQL_SERVER_SUFFIX #define MYSQL_SERVER_SUFFIX "-embedded" -#undef HAVE_QUERY_CACHE /* Cache dosn't work yet */ - #endif /* EMBEDDED_LIBRARY */ From 2e7a5d3e7452040dafe37aacfb7786d380fee0c9 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Wed, 7 Jan 2004 16:41:09 +0400 Subject: [PATCH 11/13] SCRUM WL#1246 (Query cache in embedded library) Some fixes after testing --- libmysqld/emb_qcache.cc | 32 ++++++++++++++++++++++++-------- sql/sql_cache.cc | 8 ++++---- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/libmysqld/emb_qcache.cc b/libmysqld/emb_qcache.cc index 0374ab58784..4dac154ab80 100644 --- a/libmysqld/emb_qcache.cc +++ b/libmysqld/emb_qcache.cc @@ -284,11 +284,18 @@ uint emb_count_querycache_size(THD *thd) MYSQL *mysql= thd->mysql; MYSQL_FIELD *field= mysql->fields; MYSQL_FIELD *field_end= field + mysql->field_count; + MYSQL_ROWS *cur_row=NULL; + my_ulonglong n_rows=0; - *thd->data->prev_ptr= NULL; // this marks the last record - MYSQL_ROWS *cur_row= thd->data->data; - - result= 4+8 + (42 + 4*thd->data->rows)*mysql->field_count; + if (!field) + return 0; + if (thd->data) + { + *thd->data->prev_ptr= NULL; // this marks the last record + cur_row= thd->data->data; + n_rows= thd->data->rows; + } + result= 4+8 + (42 + 4*n_rows)*mysql->field_count; for(; field < field_end; field++) { @@ -315,12 +322,21 @@ void emb_store_querycache_result(Querycache_stream *dst, THD *thd) MYSQL *mysql= thd->mysql; MYSQL_FIELD *field= mysql->fields; MYSQL_FIELD *field_end= field + mysql->field_count; - - *thd->data->prev_ptr= NULL; // this marks the last record - MYSQL_ROWS *cur_row= thd->data->data; + MYSQL_ROWS *cur_row= NULL; + my_ulonglong n_rows= 0; + + if (!field) + return; + + if (thd->data) + { + *thd->data->prev_ptr= NULL; // this marks the last record + cur_row= thd->data->data; + n_rows= thd->data->rows; + } dst->store_int((uint)mysql->field_count); - dst->store_ll((uint)thd->data->rows); + dst->store_ll((uint)n_rows); for(; field < field_end; field++) { diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index aad8d0a5d2c..7c31281c926 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -653,10 +653,6 @@ void query_cache_abort(NET *net) void query_cache_end_of_result(THD *thd) { DBUG_ENTER("query_cache_end_of_result"); -#ifdef EMBEDDED_LIBRARY - query_cache_insert(&thd->net, (byte*)thd, - emb_count_querycache_size(thd)); -#endif #ifndef DBUG_OFF // Check if we have called query_cache.wreck() (which disables the cache) @@ -665,6 +661,10 @@ void query_cache_end_of_result(THD *thd) if (thd->net.query_cache_query != 0) // Quick check on unlocked structure { +#ifdef EMBEDDED_LIBRARY + query_cache_insert(&thd->net, (byte*)thd, + emb_count_querycache_size(thd)); +#endif STRUCT_LOCK(&query_cache.structure_guard_mutex); Query_cache_block *query_block = ((Query_cache_block*) thd->net.query_cache_query); From 334856444774152ac68464408f8d0fd1bc5f4002 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Wed, 7 Jan 2004 21:30:15 +0400 Subject: [PATCH 12/13] Fix for 1224 (USER() CURRENT_USER() functions in embedded library) Now we return user@host for USER() in embedded library CURRENT_USER returns empty string if library compiled with NO_EMBEDDED_ACCESS_CHECKS --- libmysqld/embedded_priv.h | 9 +++++---- libmysqld/lib_sql.cc | 22 ++++++++++++++++++---- libmysqld/libmysqld.c | 17 +++++++---------- sql/sql_class.cc | 4 +++- 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/libmysqld/embedded_priv.h b/libmysqld/embedded_priv.h index 673531c0c14..1608f4ed4ad 100644 --- a/libmysqld/embedded_priv.h +++ b/libmysqld/embedded_priv.h @@ -23,9 +23,10 @@ #include C_MODE_START -extern void lib_connection_phase(NET *net, int phase); -extern void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db); -extern void *create_embedded_thd(int client_flag, char *db); -extern MYSQL_METHODS embedded_methods; +void lib_connection_phase(NET *net, int phase); +void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db); +void *create_embedded_thd(int client_flag, char *db); +int check_embedded_connection(MYSQL *mysql); void free_old_query(MYSQL *mysql); +extern MYSQL_METHODS embedded_methods; C_MODE_END diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 5f478fc8041..2d451d6cecd 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -478,7 +478,17 @@ void *create_embedded_thd(int client_flag, char *db) return thd; } -#ifndef NO_EMBEDDED_ACCESS_CHECKS +#ifdef NO_EMBEDDED_ACCESS_CHECKS +int check_embedded_connection(MYSQL *mysql) +{ + THD *thd= (THD*)mysql->thd; + thd->host= (char*)my_localhost; + thd->host_or_ip= thd->host; + thd->user= mysql->user; + return 0; +} + +#else int check_embedded_connection(MYSQL *mysql) { THD *thd= (THD*)mysql->thd; @@ -486,9 +496,13 @@ int check_embedded_connection(MYSQL *mysql) char scramble_buff[SCRAMBLE_LENGTH]; int passwd_len; - thd->host= mysql->options.client_ip ? - mysql->options.client_ip : (char*)my_localhost; - thd->ip= thd->host; + if (mysql->options.client_ip) + { + thd->host= mysql->options.client_ip; + thd->ip= thd->host; + } + else + thd->host= (char*)my_localhost; thd->host_or_ip= thd->host; if (acl_check_host(thd->host,thd->ip)) diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index 69fdf14eca4..95f745aef5f 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -124,17 +124,14 @@ static inline int mysql_init_charset(MYSQL *mysql) return 0; } -int check_embedded_connection(MYSQL *mysql); - MYSQL * STDCALL mysql_real_connect(MYSQL *mysql,const char *host, const char *user, const char *passwd, const char *db, uint port, const char *unix_socket,ulong client_flag) { char *db_name; -#ifndef NO_EMBEDDED_ACCESS_CHECKS char name_buff[USERNAME_LENGTH]; -#endif + DBUG_ENTER("mysql_real_connect"); DBUG_PRINT("enter",("host: %s db: %s user: %s", host ? host : "(Null)", @@ -165,10 +162,10 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, if (!db || !db[0]) db=mysql->options.db; -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (!user || !user[0]) user=mysql->options.user; +#ifndef NO_EMBEDDED_ACCESS_CHECKS if (!passwd) { passwd=mysql->options.password; @@ -177,16 +174,18 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, passwd=getenv("MYSQL_PWD"); /* get it from environment */ #endif } + mysql->passwd= passwd ? my_strdup(passwd,MYF(0)) : NULL; +#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/ if (!user || !user[0]) { read_user_name(name_buff); - if (!name_buff[0]) + if (name_buff[0]) user= name_buff; } + if (!user) + user= ""; mysql->user=my_strdup(user,MYF(0)); - mysql->passwd= passwd ? my_strdup(passwd,MYF(0)) : NULL; -#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/ port=0; unix_socket=0; @@ -196,10 +195,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, init_embedded_mysql(mysql, client_flag, db_name); -#ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_embedded_connection(mysql)) goto error; -#endif if (mysql_init_charset(mysql)) goto error; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 60220ffc889..89b812eb205 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -323,12 +323,14 @@ THD::~THD() #endif DBUG_PRINT("info", ("freeing host")); +#ifndef EMBEDDED_LIBRARY if (host != my_localhost) // If not pointer to constant safeFree(host); if (user != delayed_user) safeFree(user); - safeFree(db); safeFree(ip); +#endif + safeFree(db); free_root(&warn_root,MYF(0)); free_root(&transaction.mem_root,MYF(0)); mysys_var=0; // Safety (shouldn't be needed) From 1bd4091470529bb0a1ea94c48abaf3c29b2cf426 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Thu, 8 Jan 2004 18:56:21 +0200 Subject: [PATCH 13/13] row0mysql.c: Fix typo --- innobase/row/row0mysql.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index d5472219d09..cf7a3efcdfc 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1447,7 +1447,7 @@ row_create_table_for_mysql( fprintf(stderr, " InnoDB: Error: table %s already exists in InnoDB internal\n" "InnoDB: data dictionary. Have you deleted the .frm file\n" - "InnoDB: and not used DROPT ABLE? Have you used DROP DATABASE\n" + "InnoDB: and not used DROP TABLE? Have you used DROP DATABASE\n" "InnoDB: for InnoDB tables in MySQL version <= 3.23.43?\n" "InnoDB: See the Restrictions section of the InnoDB manual.\n", table->name);