From 59f9fc4fe2d503af1bfb414496f3b507a91ce31b Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Thu, 20 Sep 2001 21:04:48 +0300 Subject: [PATCH 01/15] mem0mem.ic Changes to eliminate unnecessary Purify warnings ut0mem.h Changes to eliminate unnecessary Purify warnings ut0mem.ic Changes to eliminate unnecessary Purify warnings srv0start.c Changes to eliminate unnecessary Purify warnings mem0pool.c Changes to eliminate unnecessary Purify warnings ut0mem.c Changes to eliminate unnecessary Purify warnings --- innobase/include/mem0mem.ic | 12 +++- innobase/include/ut0mem.h | 35 ++++++++-- innobase/include/ut0mem.ic | 7 -- innobase/mem/mem0pool.c | 6 +- innobase/srv/srv0start.c | 2 + innobase/ut/ut0mem.c | 132 ++++++++++++++++++++++++++++++++---- 6 files changed, 167 insertions(+), 27 deletions(-) diff --git a/innobase/include/mem0mem.ic b/innobase/include/mem0mem.ic index 8b8449469ef..edc3ab17f2a 100644 --- a/innobase/include/mem0mem.ic +++ b/innobase/include/mem0mem.ic @@ -170,7 +170,9 @@ mem_heap_alloc( buf = (byte*)buf + MEM_FIELD_HEADER_SIZE; #endif - +#ifdef UNIV_SET_MEM_TO_ZERO + memset(buf, '\0', n); +#endif return(buf); } @@ -494,8 +496,14 @@ mem_alloc_func( ) { #ifndef UNIV_MEM_DEBUG + void* buf; - return(mem_area_alloc(n, mem_comm_pool)); + buf = mem_area_alloc(n, mem_comm_pool); + +#ifdef UNIV_SET_MEM_TO_ZERO + memset(buf, '\0', n); +#endif + return(buf); #else diff --git a/innobase/include/ut0mem.h b/innobase/include/ut0mem.h index fa46514fe16..8e5a4fda0d3 100644 --- a/innobase/include/ut0mem.h +++ b/innobase/include/ut0mem.h @@ -26,12 +26,39 @@ int ut_memcmp(void* str1, void* str2, ulint n); -void* -ut_malloc(ulint n); +/************************************************************************** +Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is +defined and set_to_zero is TRUE. */ + +void* +ut_malloc_low( +/*==========*/ + /* out, own: allocated memory */ + ulint n, /* in: number of bytes to allocate */ + ibool set_to_zero); /* in: TRUE if allocated memory should be set + to zero if UNIV_SET_MEM_TO_ZERO is defined */ +/************************************************************************** +Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is +defined. */ + +void* +ut_malloc( +/*======*/ + /* out, own: allocated memory */ + ulint n); /* in: number of bytes to allocate */ +/************************************************************************** +Frees a memory bloock allocated with ut_malloc. */ -UNIV_INLINE void -ut_free(void* ptr); +ut_free( +/*====*/ + void* ptr); /* in, own: memory block */ +/************************************************************************** +Frees all allocated memory not freed yet. */ + +void +ut_free_all_mem(void); +/*=================*/ UNIV_INLINE char* diff --git a/innobase/include/ut0mem.ic b/innobase/include/ut0mem.ic index fc4b6bd8be5..7ae9bc8bd74 100644 --- a/innobase/include/ut0mem.ic +++ b/innobase/include/ut0mem.ic @@ -27,13 +27,6 @@ ut_memcmp(void* str1, void* str2, ulint n) return(memcmp(str1, str2, n)); } -UNIV_INLINE -void -ut_free(void* ptr) -{ - free(ptr); -} - UNIV_INLINE char* ut_strcpy(char* dest, char* sour) diff --git a/innobase/mem/mem0pool.c b/innobase/mem/mem0pool.c index e8c02d812c4..6c3a4adebae 100644 --- a/innobase/mem/mem0pool.c +++ b/innobase/mem/mem0pool.c @@ -170,7 +170,11 @@ mem_pool_create( pool = ut_malloc(sizeof(mem_pool_t)); - pool->buf = ut_malloc(size); + /* We do not set the memory to zero (FALSE) in the pool, + but only when allocated at a higher level in mem0mem.c. + This is to avoid masking useful Purify warnings. */ + + pool->buf = ut_malloc_low(size, FALSE); pool->size = size; mutex_create(&(pool->mutex)); diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index c4002767226..15d99ab3001 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -916,5 +916,7 @@ innobase_shutdown_for_mysql(void) logs_empty_and_mark_files_at_shutdown(); + ut_free_all_mem(); + return((int) DB_SUCCESS); } diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c index 492f57670a9..ebeefe0c297 100644 --- a/innobase/ut/ut0mem.c +++ b/innobase/ut/ut0mem.c @@ -14,30 +14,136 @@ Created 5/11/1994 Heikki Tuuri #include "mem0mem.h" + +/* This struct is placed first in every allocated memory block */ +typedef struct ut_mem_block_struct ut_mem_block_t; + +struct ut_mem_block_struct{ + UT_LIST_NODE_T(ut_mem_block_t) mem_block_list;/* mem block list node */ +}; + + +/* List of all memory blocks allocated from the operating system +with malloc */ +UT_LIST_BASE_NODE_T(ut_mem_block_t) ut_mem_block_list; + +os_fast_mutex_t ut_list_mutex; /* this protects the list */ + +ibool ut_mem_block_list_inited = FALSE; + +/************************************************************************** +Initializes the mem block list at database startup. */ +static +void +ut_mem_block_list_init(void) +/*========================*/ +{ + os_fast_mutex_init(&ut_list_mutex); + UT_LIST_INIT(ut_mem_block_list); + ut_mem_block_list_inited = TRUE; +} + +/************************************************************************** +Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is +defined and set_to_zero is TRUE. */ + void* -ut_malloc(ulint n) +ut_malloc_low( +/*==========*/ + /* out, own: allocated memory */ + ulint n, /* in: number of bytes to allocate */ + ibool set_to_zero) /* in: TRUE if allocated memory should be set + to zero if UNIV_SET_MEM_TO_ZERO is defined */ { void* ret; - /* - ret = VirtualAlloc(NULL, n, MEM_COMMIT, PAGE_READWRITE); - */ - ret = malloc(n); + ut_ad((sizeof(ut_mem_block_t) % 8) == 0); /* check alignment ok */ + + if (!ut_mem_block_list_inited) { + ut_mem_block_list_init(); + } + + os_fast_mutex_lock(&ut_list_mutex); + + ret = malloc(n + sizeof(ut_mem_block_t)); if (ret == NULL) { fprintf(stderr, - "Innobase: Fatal error: cannot allocate memory!\n"); - fprintf(stderr, - "Innobase: Cannot continue operation!\n"); - fprintf(stderr, - "Innobase: Check if you can increase the swap file of your\n"); - fprintf(stderr, - "Innobase: operating system.\n"); + "InnoDB: Fatal error: cannot allocate %lu bytes of\n" + "InnoDB: memory with malloc!\n" + "InnoDB: Operating system errno: %lu\n" + "InnoDB: Cannot continue operation!\n" + "InnoDB: Check if you should increase the swap file or\n" + "InnoDB: ulimits of your operating system.\n", n, errno); + + os_fast_mutex_unlock(&ut_list_mutex); exit(1); } - return(ret); + if (set_to_zero) { +#ifdef UNIV_SET_MEM_TO_ZERO + memset(ret, '\0', n + sizeof(ut_mem_block_t)); +#endif + } + + UT_LIST_ADD_FIRST(mem_block_list, ut_mem_block_list, + ((ut_mem_block_t*)ret)); + os_fast_mutex_unlock(&ut_list_mutex); + + return((void*)((byte*)ret + sizeof(ut_mem_block_t))); +} + +/************************************************************************** +Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is +defined. */ + +void* +ut_malloc( +/*======*/ + /* out, own: allocated memory */ + ulint n) /* in: number of bytes to allocate */ +{ + return(ut_malloc_low(n, TRUE)); +} +/************************************************************************** +Frees a memory bloock allocated with ut_malloc. */ + +void +ut_free( +/*====*/ + void* ptr) /* in, own: memory block */ +{ + ut_mem_block_t* block; + + block = (ut_mem_block_t*)((byte*)ptr - sizeof(ut_mem_block_t)); + + os_fast_mutex_lock(&ut_list_mutex); + + UT_LIST_REMOVE(mem_block_list, ut_mem_block_list, block); + free(block); + + os_fast_mutex_unlock(&ut_list_mutex); +} + +/************************************************************************** +Frees all allocated memory not freed yet. */ + +void +ut_free_all_mem(void) +/*=================*/ +{ + ut_mem_block_t* block; + + os_fast_mutex_lock(&ut_list_mutex); + + while (block = UT_LIST_GET_FIRST(ut_mem_block_list)) { + + UT_LIST_REMOVE(mem_block_list, ut_mem_block_list, block); + free(block); + } + + os_fast_mutex_unlock(&ut_list_mutex); } /************************************************************************** From 0b064c3b0903ced19a97e4526e344226a42cb27f Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Thu, 20 Sep 2001 21:14:49 +0300 Subject: [PATCH 02/15] univ.i Changes to eliminate unnecessary Purify warnings (documentation of flag UNIV_SET_MEM_TO_ZERO) --- innobase/include/univ.i | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/innobase/include/univ.i b/innobase/include/univ.i index f3e3b22bb3d..9fc9f85f633 100644 --- a/innobase/include/univ.i +++ b/innobase/include/univ.i @@ -61,8 +61,12 @@ subdirectory of 'mysql'. */ /* DEBUG VERSION CONTROL ===================== */ +/* The following flag will make InnoDB to initialize +all memory it allocates to zero. It hides Purify +warnings about reading unallocated memory unless +memory is read outside the allocated blocks. */ /* -#define UNIV_SYNC_DEBUG +#define UNIV_INIT_MEM_TO_ZERO */ /* Make a non-inline debug version */ @@ -72,7 +76,7 @@ subdirectory of 'mysql'. */ #define UNIV_SEARCH_DEBUG #define UNIV_IBUF_DEBUG - +#define UNIV_SYNC_DEBUG #define UNIV_SYNC_PERF_STAT #define UNIV_SEARCH_PERF_STAT */ From e2389946dd46fb5cf0fa92532c757d683d83c61b Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Thu, 20 Sep 2001 21:38:46 +0300 Subject: [PATCH 03/15] os0sync.h Define os_fast_mutex functions also in Windows os0sync.ic Define os_fast_mutex functions also in Windows --- innobase/include/os0sync.h | 2 +- innobase/include/os0sync.ic | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/innobase/include/os0sync.h b/innobase/include/os0sync.h index 89e3f953b50..78374cf8ede 100644 --- a/innobase/include/os0sync.h +++ b/innobase/include/os0sync.h @@ -160,6 +160,7 @@ os_fast_mutex_trylock( was reserved by another thread */ os_fast_mutex_t* fast_mutex); /* in: mutex to acquire */ +#endif /************************************************************** Releases ownership of a fast mutex. */ UNIV_INLINE @@ -188,7 +189,6 @@ void os_fast_mutex_free( /*===============*/ os_fast_mutex_t* fast_mutex); /* in: mutex to free */ -#endif #ifndef UNIV_NONINL #include "os0sync.ic" diff --git a/innobase/include/os0sync.ic b/innobase/include/os0sync.ic index 8be9a783593..057ad424dee 100644 --- a/innobase/include/os0sync.ic +++ b/innobase/include/os0sync.ic @@ -38,6 +38,7 @@ os_fast_mutex_trylock( return((ulint) pthread_mutex_trylock(fast_mutex)); #endif } +#endif /************************************************************** Releases ownership of a fast mutex. */ @@ -53,4 +54,3 @@ os_fast_mutex_unlock( pthread_mutex_unlock(fast_mutex); #endif } -#endif From df1045ee3c5c25eb62fb1cb8a065fa1bf0d8b902 Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Thu, 20 Sep 2001 21:43:58 +0300 Subject: [PATCH 04/15] os0sync.c Define os_fast_mutex functions also in Windows --- innobase/os/os0sync.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/innobase/os/os0sync.c b/innobase/os/os0sync.c index c5dd603100d..8da142cd4a6 100644 --- a/innobase/os/os0sync.c +++ b/innobase/os/os0sync.c @@ -422,7 +422,6 @@ os_mutex_free( #endif } -#ifndef _WIN32 /************************************************************* Initializes an operating system fast mutex semaphore. */ @@ -472,4 +471,3 @@ os_fast_mutex_free( #endif } -#endif From e390a995737f136c594a7c792caa12061690800f Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Sat, 22 Sep 2001 17:40:57 +0300 Subject: [PATCH 05/15] Added support of INSERT to MERGE tables Fixes for embedded libary and openssl --- BUILD/compile-pentium-debug-max | 2 +- Build-tools/Do-all-build-steps | 1 - acinclude.m4 | 8 +-- client/client_priv.h | 1 + client/mysql.cc | 33 ++++------- include/Makefile.am | 4 +- include/myisammrg.h | 15 ++++- include/mysql.h | 43 +++++++------- include/mysql_com.h | 10 ++-- {sql => include}/mysql_embed.h | 3 + include/violite.h | 102 ++++++++++++++------------------ libmysql/libmysql.c | 1 + libmysqld/examples/Makefile.am | 2 +- libmysqld/lib_sql.cc | 1 + libmysqld/lib_vio.c | 3 +- libmysqld/libmysqld.c | 38 ++---------- myisammrg/Makefile.am | 2 +- myisammrg/myrg_create.c | 10 +++- myisammrg/myrg_open.c | 52 +++++++++------- myisammrg/myrg_static.c | 4 ++ myisammrg/myrg_write.c | 30 ++++++++++ mysql-test/t/union.test | 2 +- sql/Makefile.am | 2 +- sql/gen_lex_hash.cc | 12 ++-- sql/ha_myisammrg.cc | 23 ++++++- sql/handler.h | 8 ++- sql/lex.h | 1 + sql/mini_client.cc | 2 +- sql/net_serv.cc | 1 + sql/sql_show.cc | 1 - sql/sql_yacc.yy | 11 +++- 31 files changed, 235 insertions(+), 193 deletions(-) rename {sql => include}/mysql_embed.h (94%) create mode 100644 myisammrg/myrg_write.c diff --git a/BUILD/compile-pentium-debug-max b/BUILD/compile-pentium-debug-max index 4149267811d..ccd6faa0448 100755 --- a/BUILD/compile-pentium-debug-max +++ b/BUILD/compile-pentium-debug-max @@ -8,6 +8,6 @@ c_warnings="$c_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings" extra_configs="$pentium_configs $debug_configs" -extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-embedded-server" +extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-vio --with-openssl --with-embedded-server" . "$path/FINISH.sh" diff --git a/Build-tools/Do-all-build-steps b/Build-tools/Do-all-build-steps index e17e6acf305..ad3868733fa 100755 --- a/Build-tools/Do-all-build-steps +++ b/Build-tools/Do-all-build-steps @@ -65,7 +65,6 @@ aclocal; autoheader; aclocal; automake; autoconf --enable-thread-safe-client \ --with-berkeley-db \ --with-innodb \ - --with-openssl \ --with-vio \ --without-pstack \ --with-extra-tools \ diff --git a/acinclude.m4 b/acinclude.m4 index ca711a7c641..d7e492856bb 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -690,8 +690,7 @@ fi AC_DEFUN(MYSQL_CHECK_VIO, [ AC_ARG_WITH([vio], - [\ - --with-vio Include the Virtual IO support], + [ --with-vio Include the Virtual IO support], [vio="$withval"], [vio=no]) @@ -712,8 +711,7 @@ AC_DEFUN(MYSQL_CHECK_VIO, [ AC_DEFUN(MYSQL_CHECK_OPENSSL, [ AC_MSG_CHECKING(for OpenSSL) AC_ARG_WITH([openssl], - [\ - --with-openssl Include the OpenSSL support], + [ --with-openssl Include the OpenSSL support], [openssl="$withval"], [openssl=no]) @@ -722,7 +720,7 @@ AC_MSG_CHECKING(for OpenSSL) if test -n "$vio_dir" then AC_MSG_RESULT(yes) - openssl_libs="-lssl -lcrypto -L/usr/local/ssl/lib" + openssl_libs="-L/usr/local/ssl/lib -lssl -lcrypto" openssl_includes="-I/usr/local/ssl/include" else AC_MSG_ERROR([OpenSSL requires Virtual IO support (--with-vio)]) diff --git a/client/client_priv.h b/client/client_priv.h index 64ded3ed7f3..b015e378127 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/client/mysql.cc b/client/mysql.cc index 6c947d90d76..6382fd66f35 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -303,6 +303,7 @@ int main(int argc,char *argv[]) exit(1); glob_buffer.realloc(512); completion_hash_init(&ht,50); + bzero((char*) &mysql, sizeof(mysql)); if (sql_connect(current_host,current_db,current_user,opt_password, opt_silent)) { @@ -326,11 +327,13 @@ int main(int argc,char *argv[]) put_info((char*) glob_buffer.ptr(),INFO_INFO); #ifdef HAVE_OPENSSL - if(mysql.net.vio->ssl_ && SSL_get_cipher(mysql.net.vio->ssl_)) { + if (mysql.net.vio->ssl_ && SSL_get_cipher(mysql.net.vio->ssl_)) + { sprintf((char*) glob_buffer.ptr(), - "SSL cipher in use is %s\n", SSL_get_cipher(mysql.net.vio->ssl_)); + "SSL cipher in use is %s\n", SSL_get_cipher(mysql.net.vio->ssl_)); put_info((char*) glob_buffer.ptr(),INFO_INFO); - } else + } + else put_info("SSL is not in use\n",INFO_INFO); #endif /* HAVE_OPENSSL */ @@ -373,13 +376,7 @@ int main(int argc,char *argv[]) sig_handler mysql_end(int sig) { - if (connected) - mysql_close(&mysql); -#ifdef HAVE_OPENSSL - else - mysql_ssl_clear(&mysql); /* SSL data structres should be freed - even if connection was not made */ -#endif + mysql_close(&mysql); #ifdef HAVE_READLINE if (!status.batch && !quick && !opt_html && !opt_xml) { @@ -2208,16 +2205,8 @@ static int sql_real_connect(char *host,char *database,char *user,char *password, uint silent) { - if (connected) - { /* if old is open, close it first */ - mysql_close(&mysql); - connected= 0; - } -#ifdef HAVE_OPENSSL - else - mysql_ssl_clear(&mysql); /* SSL data structres should be freed - even if connection was not made */ -#endif + mysql_close(&mysql); + connected= 0; mysql_init(&mysql); if (opt_connect_timeout) { @@ -2569,7 +2558,7 @@ static void mysql_end_timer(ulong start_time,char *buff) strmov(strend(buff),")"); } -#ifndef EMBEDDED_SERVER +#ifndef EMBEDDED_LIBRARY /* Keep sql_string library happy */ gptr sql_alloc(unsigned int Size) @@ -2581,4 +2570,4 @@ void sql_element_free(void *ptr) { my_free((gptr) ptr,MYF(0)); } -#endif /* EMBEDDED_SERVER */ +#endif /* EMBEDDED_LIBRARY */ diff --git a/include/Makefile.am b/include/Makefile.am index 0821afeb01d..aaf11db7a50 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -16,8 +16,8 @@ # MA 02111-1307, USA BUILT_SOURCES = mysql_version.h m_ctype.h my_config.h -pkginclude_HEADERS = dbug.h m_string.h my_sys.h mysql.h mysql_com.h \ - mysqld_error.h my_list.h \ +pkginclude_HEADERS = dbug.h m_string.h my_sys.h my_list.h \ + mysql.h mysql_com.h mysqld_error.h mysql_embed.h \ my_pthread.h my_no_pthread.h raid.h errmsg.h \ my_global.h my_net.h \ sslopt-case.h sslopt-longopts.h sslopt-usage.h \ diff --git a/include/myisammrg.h b/include/myisammrg.h index a797c954614..1ae825b4b94 100644 --- a/include/myisammrg.h +++ b/include/myisammrg.h @@ -34,6 +34,13 @@ extern "C" { #define MYRG_NAME_EXT ".MRG" +/* In which table to INSERT rows */ +#define MERGE_INSERT_DISABLED 0 +#define MERGE_INSERT_TO_FIRST 1 +#define MERGE_INSERT_TO_LAST 2 + +extern TYPELIB merge_insert_method; + /* Param to/from myrg_info */ typedef struct st_mymerge_info /* Struct from h_info */ @@ -44,7 +51,7 @@ typedef struct st_mymerge_info /* Struct from h_info */ ulonglong data_file_length; uint reclength; /* Recordlength */ int errkey; /* With key was dupplicated on err */ - uint options; /* HA_OPTIONS_... used */ + uint options; /* HA_OPTION_... used */ } MYMERGE_INFO; typedef struct st_myrg_table_info @@ -56,6 +63,7 @@ typedef struct st_myrg_table_info typedef struct st_myrg_info { MYRG_TABLE *open_tables,*current_table,*end_table,*last_used_table; + uint merge_insert_method; ulonglong records; /* records in tables */ ulonglong del; /* Removed records */ ulonglong data_file_length; @@ -81,10 +89,11 @@ extern int myrg_rkey(MYRG_INFO *file,byte *buf,int inx,const byte *key, extern int myrg_rrnd(MYRG_INFO *file,byte *buf,ulonglong pos); extern int myrg_rsame(MYRG_INFO *file,byte *record,int inx); extern int myrg_update(MYRG_INFO *file,const byte *old,byte *new_rec); +extern int myrg_write(MYRG_INFO *info,byte *rec); extern int myrg_status(MYRG_INFO *file,MYMERGE_INFO *x,int flag); extern int myrg_lock_database(MYRG_INFO *file,int lock_type); -extern int myrg_create(const char *name,const char **table_names, - my_bool fix_names); +extern int myrg_create(const char *name, const char **table_names, + uint insert_method, my_bool fix_names); extern int myrg_extra(MYRG_INFO *file,enum ha_extra_function function); extern ha_rows myrg_records_in_range(MYRG_INFO *info,int inx, const byte *start_key,uint start_key_len, diff --git a/include/mysql.h b/include/mysql.h index 3e3a6f35e56..a1bd96540e8 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -48,32 +48,15 @@ typedef char my_bool; #endif typedef char * gptr; -#ifndef ST_USED_MEM_DEFINED -#define ST_USED_MEM_DEFINED -typedef struct st_used_mem { /* struct for once_alloc */ - struct st_used_mem *next; /* Next block in use */ - unsigned int left; /* memory left in block */ - unsigned int size; /* size of block */ -} USED_MEM; -typedef struct st_mem_root { - USED_MEM *free; - USED_MEM *used; - USED_MEM *pre_alloc; - unsigned int min_malloc; - unsigned int block_size; - - void (*error_handler)(void); -} MEM_ROOT; -#endif - #ifndef my_socket_defined #ifdef __WIN__ #define my_socket SOCKET #else typedef int my_socket; -#endif -#endif -#endif +#endif /* __WIN__ */ +#endif /* my_socket_defined */ +#endif /* _global_h */ + #include "mysql_com.h" #include "mysql_version.h" @@ -118,6 +101,24 @@ typedef struct st_mysql_rows { typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */ +#ifndef ST_USED_MEM_DEFINED +#define ST_USED_MEM_DEFINED +typedef struct st_used_mem { /* struct for once_alloc */ + struct st_used_mem *next; /* Next block in use */ + unsigned int left; /* memory left in block */ + unsigned int size; /* size of block */ +} USED_MEM; +typedef struct st_mem_root { + USED_MEM *free; + USED_MEM *used; + USED_MEM *pre_alloc; + unsigned int min_malloc; + unsigned int block_size; + + void (*error_handler)(void); +} MEM_ROOT; +#endif + typedef struct st_mysql_data { my_ulonglong rows; unsigned int fields; diff --git a/include/mysql_com.h b/include/mysql_com.h index ce134fcab2c..63fbc05b0cb 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -113,10 +113,12 @@ typedef struct st_net { unsigned int last_errno,max_packet,timeout,pkt_nr; unsigned char error; my_bool return_errno,compress; - my_bool no_send_ok; /* needed if we are doing several - queries in one command ( as in LOAD TABLE ... FROM MASTER ), - and do not want to confuse the client with OK at the wrong time - */ + /* + The following variable is set if we are doing several queries in one + command ( as in LOAD TABLE ... FROM MASTER ), + and do not want to confuse the client with OK at the wrong time + */ + my_bool no_send_ok; unsigned long remain_in_buf,length, buf_length, where_b; unsigned int *return_status; unsigned char reading_or_writing; diff --git a/sql/mysql_embed.h b/include/mysql_embed.h similarity index 94% rename from sql/mysql_embed.h rename to include/mysql_embed.h index 4bfaca547a8..77f6f3fa32c 100644 --- a/sql/mysql_embed.h +++ b/include/mysql_embed.h @@ -22,5 +22,8 @@ #undef HAVE_PSTACK /* No stacktrace */ #undef HAVE_DLOPEN /* No udf functions */ +#undef HAVE_OPENSSL +#undef HAVE_VIO +#define DONT_USE_RAID #endif /* EMBEDDED_LIBRARY */ diff --git a/include/violite.h b/include/violite.h index 49791c6b68a..947b874c46a 100644 --- a/include/violite.h +++ b/include/violite.h @@ -33,67 +33,59 @@ extern "C" { #endif /* __cplusplus */ enum enum_vio_type { VIO_CLOSED, VIO_TYPE_TCPIP, VIO_TYPE_SOCKET, - VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL}; + VIO_TYPE_NAMEDPIPE, VIO_TYPE_SSL}; #ifndef __WIN__ #define HANDLE void * #endif -Vio* vio_new(my_socket sd, - enum enum_vio_type type, - my_bool localhost); +Vio* vio_new(my_socket sd, enum enum_vio_type type, my_bool localhost); #ifdef __WIN__ -Vio* vio_new_win32pipe(HANDLE hPipe); +Vio* vio_new_win32pipe(HANDLE hPipe); #endif -void vio_delete(Vio* vio); +void vio_delete(Vio* vio); #ifdef EMBEDDED_LIBRARY void vio_reset(Vio *vio); #else void vio_reset(Vio* vio, enum enum_vio_type type, - my_socket sd, HANDLE hPipe, - my_bool localhost); + my_socket sd, HANDLE hPipe, my_bool localhost); #endif /* * vio_read and vio_write should have the same semantics * as read(2) and write(2). */ -int vio_read( Vio* vio, - gptr buf, int size); -int vio_write( Vio* vio, - const gptr buf, - int size); +int vio_read(Vio *vio, gptr buf, int size); +int vio_write(Vio *vio, const gptr buf, int size); /* * Whenever the socket is set to blocking mode or not. */ -int vio_blocking( Vio* vio, - my_bool onoff); -my_bool vio_is_blocking( Vio* vio); +int vio_blocking(Vio *vio, my_bool onoff); +my_bool vio_is_blocking(Vio *vio); /* * setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible. */ - int vio_fastsend( Vio* vio); +int vio_fastsend(Vio *vio); /* * setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible. */ -int vio_keepalive( Vio* vio, - my_bool onoff); +int vio_keepalive(Vio *vio, my_bool onoff); /* * Whenever we should retry the last read/write operation. */ -my_bool vio_should_retry( Vio* vio); +my_bool vio_should_retry(Vio *vio); /* * When the workday is over... */ -int vio_close(Vio* vio); +int vio_close(Vio* vio); /* * Short text description of the socket for those, who are curious.. */ -const char* vio_description( Vio* vio); +const char* vio_description(Vio *vio); /* Return the type of the connection */ - enum enum_vio_type vio_type(Vio* vio); +enum enum_vio_type vio_type(Vio* vio); /* Return last error number */ int vio_errno(Vio*vio); @@ -117,8 +109,8 @@ my_bool vio_poll_read(Vio *vio,uint timeout); } #endif #endif /* vio_violite_h_ */ -#ifdef HAVE_VIO -#ifndef DONT_MAP_VIO + +#if defined(HAVE_VIO) && !defined(DONT_MAP_VIO) #define vio_delete(vio) (vio)->viodelete(vio) #define vio_errno(vio) (vio)->vioerrno(vio) #define vio_read(vio, buf, size) (vio)->read(vio,buf,size) @@ -132,9 +124,7 @@ my_bool vio_poll_read(Vio *vio,uint timeout); #define vio_peer_addr(vio, buf) (vio)->peer_addr(vio, buf) #define vio_in_addr(vio, in) (vio)->in_addr(vio, in) #define vio_poll_read(vio,timeout) (vio)->poll_read(vio,timeout) -#endif /* !DONT_MAP_VIO */ -#endif /* HAVE_VIO */ - +#endif /* defined(HAVE_VIO) && !defined(DONT_MAP_VIO) */ #ifdef HAVE_OPENSSL #define HEADER_DES_LOCL_H dummy_something @@ -142,17 +132,16 @@ my_bool vio_poll_read(Vio *vio,uint timeout); #include #include "my_net.h" /* needed because of struct in_addr */ - #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ -void vio_ssl_delete(Vio* vio); +void vio_ssl_delete(Vio* vio); -int vio_ssl_read(Vio* vio,gptr buf, int size); -int vio_ssl_write(Vio* vio,const gptr buf,int size); -int vio_ssl_blocking(Vio* vio,my_bool onoff); -my_bool vio_ssl_is_blocking(Vio* vio); +int vio_ssl_read(Vio* vio,gptr buf, int size); +int vio_ssl_write(Vio* vio,const gptr buf,int size); +int vio_ssl_blocking(Vio* vio,my_bool onoff); +my_bool vio_ssl_is_blocking(Vio* vio); /* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible. */ int vio_ssl_fastsend(Vio* vio); @@ -170,8 +159,6 @@ void vio_ssl_in_addr(Vio *vio, struct in_addr *in); /* Return 1 if there is data to be read */ my_bool vio_ssl_poll_read(Vio *vio,uint timeout); -#ifdef HAVE_OPENSSL - /* Single copy for server */ struct st_VioSSLAcceptorFd { @@ -200,16 +187,14 @@ struct st_VioSSLConnectorFd void sslaccept(struct st_VioSSLAcceptorFd*, Vio*); void sslconnect(struct st_VioSSLConnectorFd*, Vio*); -#else /* HAVE_OPENSSL */ -/* This dummy is required to maintain proper size of st_mysql in mysql.h */ -struct st_VioSSLConnectorFd {}; -#endif /* HAVE_OPENSSL */ -struct st_VioSSLConnectorFd *new_VioSSLConnectorFd( - const char* key_file,const char* cert_file,const char* ca_file,const char* ca_path); -struct st_VioSSLAcceptorFd *new_VioSSLAcceptorFd( - const char* key_file,const char* cert_file,const char* ca_file,const char* ca_path); +struct st_VioSSLConnectorFd +*new_VioSSLConnectorFd(const char* key_file, const char* cert_file, + const char* ca_file, const char* ca_path); +struct st_VioSSLAcceptorFd +*new_VioSSLAcceptorFd(const char* key_file, const char* cert_file, + const char* ca_file,const char* ca_path); Vio* new_VioSSL(struct st_VioSSLAcceptorFd* fd, Vio* sd,int state); - + #ifdef __cplusplus } #endif @@ -229,19 +214,19 @@ struct st_vio char desc[30]; /* String description */ #ifdef HAVE_VIO /* function pointers. They are similar for socket/SSL/whatever */ - void (*viodelete)(Vio*); - int(*vioerrno)(Vio*); - int(*read)(Vio*, gptr, int); - int(*write)(Vio*, gptr, int); - int(*vioblocking)(Vio*, my_bool); - my_bool(*is_blocking)(Vio*); - int(*viokeepalive)(Vio*, my_bool); - int(*fastsend)(Vio*); - my_bool(*peer_addr)(Vio*, gptr); - void(*in_addr)(Vio*, struct in_addr*); - my_bool(*should_retry)(Vio*); - int(*vioclose)(Vio*); - my_bool(*poll_read)(Vio*,uint); + void (*viodelete)(Vio*); + int (*vioerrno)(Vio*); + int (*read)(Vio*, gptr, int); + int (*write)(Vio*, gptr, int); + int (*vioblocking)(Vio*, my_bool); + my_bool (*is_blocking)(Vio*); + int (*viokeepalive)(Vio*, my_bool); + int (*fastsend)(Vio*); + my_bool (*peer_addr)(Vio*, gptr); + void (*in_addr)(Vio*, struct in_addr*); + my_bool (*should_retry)(Vio*); + int (*vioclose)(Vio*); + my_bool (*poll_read)(Vio*,uint); #ifdef HAVE_OPENSSL BIO* bio_; @@ -252,4 +237,3 @@ struct st_vio #endif /* HAVE_VIO */ }; #endif /* EMBEDDED_LIBRARY */ - diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index eb0e2f1820a..03162bc1dfa 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -2014,6 +2014,7 @@ mysql_close(MYSQL *mysql) mysql_close(tmp); tmp = tmp1; } + mysql->rpl_pivot=0; } if (mysql != mysql->master) mysql_close(mysql->master); diff --git a/libmysqld/examples/Makefile.am b/libmysqld/examples/Makefile.am index b687a528c6f..75487302e46 100644 --- a/libmysqld/examples/Makefile.am +++ b/libmysqld/examples/Makefile.am @@ -7,7 +7,7 @@ link_sources: @LN_CP_F@ $(srcdir)/../../client/$$f $(srcdir)/$$f; \ done; -DEFS = -DEMBEDDED_SERVER +DEFS = -DEMBEDDED_LIBRARY INCLUDES = -I$(top_srcdir)/include $(openssl_includes) \ -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/client LIBS = @LIBS@ diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index f07150c9845..e7da577ab0c 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -13,6 +13,7 @@ * */ #include "my_global.h" +#include "mysql_embed.h" #include "my_pthread.h" #include "sys/types.h" #include "../regex/regex.h" diff --git a/libmysqld/lib_vio.c b/libmysqld/lib_vio.c index e86e6c7e8da..37f77eaaad5 100644 --- a/libmysqld/lib_vio.c +++ b/libmysqld/lib_vio.c @@ -23,12 +23,13 @@ */ #include +#include "mysql_embed.h" +#include "mysql.h" #ifndef HAVE_VIO /* is Vio suppored by the Vio lib ? */ #include #include -#include "mysql.h" #include #include #include diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index cb8b2f02773..8931bc3cd48 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -15,19 +15,19 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#define DONT_USE_RAID #include #if defined(__WIN__) || defined(_WIN32) || defined(_WIN64) #include #include #endif +#include "mysql_embed.h" +#include "mysql.h" +#include "mysql_version.h" +#include "mysqld_error.h" #include #include #include #include -#include "mysql.h" -#include "mysql_version.h" -#include "mysqld_error.h" #include "errmsg.h" #include #include @@ -88,7 +88,6 @@ static int read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, static void end_server(MYSQL *mysql); static void read_user_name(char *name); static void append_wild(char *to,char *end,const char *wild); -static my_bool mysql_reconnect(MYSQL *mysql); static int send_file_to_server(MYSQL *mysql,const char *filename); static sig_handler pipe_sig_handler(int sig); static ulong mysql_sub_escape_string(CHARSET_INFO *charset_info, char *to, @@ -1346,35 +1345,6 @@ error: } -static my_bool mysql_reconnect(MYSQL *mysql) -{ - MYSQL tmp_mysql; - DBUG_ENTER("mysql_reconnect"); - - if (!mysql->reconnect || - (mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info) - { - /* Allov reconnect next time */ - mysql->server_status&= ~SERVER_STATUS_IN_TRANS; - DBUG_RETURN(1); - } - mysql_init(&tmp_mysql); - tmp_mysql.options=mysql->options; - if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd, - mysql->db, mysql->port, mysql->unix_socket, - mysql->client_flag)) - DBUG_RETURN(1); - tmp_mysql.free_me=mysql->free_me; - mysql->free_me=0; - bzero((char*) &mysql->options,sizeof(mysql->options)); - mysql_close(mysql); - *mysql=tmp_mysql; - net_clear(&mysql->net); - mysql->affected_rows= ~(my_ulonglong) 0; - DBUG_RETURN(0); -} - - /************************************************************************** ** Change user and database **************************************************************************/ diff --git a/myisammrg/Makefile.am b/myisammrg/Makefile.am index b09d7d70191..8b05bc5f386 100644 --- a/myisammrg/Makefile.am +++ b/myisammrg/Makefile.am @@ -21,7 +21,7 @@ libmyisammrg_a_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \ myrg_rrnd.c myrg_update.c myrg_delete.c myrg_rsame.c \ myrg_panic.c myrg_close.c myrg_create.c myrg_static.c \ myrg_rkey.c myrg_rfirst.c myrg_rlast.c myrg_rnext.c \ - myrg_rprev.c myrg_queue.c + myrg_rprev.c myrg_queue.c myrg_write.c OMIT_DEPENDENCIES = pthread.h stdio.h __stdio.h stdlib.h __stdlib.h math.h\ __math.h time.h __time.h unistd.h __unistd.h types.h \ xtypes.h ac-types.h posix.h string.h __string.h \ diff --git a/myisammrg/myrg_create.c b/myisammrg/myrg_create.c index 113831b9d7f..5c6638b6ef2 100644 --- a/myisammrg/myrg_create.c +++ b/myisammrg/myrg_create.c @@ -23,7 +23,8 @@ a NULL-pointer last */ -int myrg_create(const char *name, const char **table_names, my_bool fix_names) +int myrg_create(const char *name, const char **table_names, + uint insert_method, my_bool fix_names) { int save_errno; uint errpos; @@ -50,6 +51,13 @@ int myrg_create(const char *name, const char **table_names, my_bool fix_names) goto err; } } + if (insert_method != MERGE_INSERT_DISABLED) + { + end=strxmov(buff,"#INSERT_METHOD=", + get_type(&merge_insert_method,insert_method),"\n",NullS); + if (my_write(file,buff,(uint) (end-buff),MYF(MY_WME | MY_NABP))) + goto err; + } if (my_close(file,MYF(0))) goto err; DBUG_RETURN(0); diff --git a/myisammrg/myrg_open.c b/myisammrg/myrg_open.c index 9fa89b315ff..60523c90ff4 100644 --- a/myisammrg/myrg_open.c +++ b/myisammrg/myrg_open.c @@ -14,7 +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 */ -/* open a MYMERGE_-database */ +/* open a MyISAM MERGE table */ #include "mymrgdef.h" #include @@ -23,17 +23,14 @@ #include "mrg_static.c" #endif -/* open a MYMERGE_-database. - +/* + open a MyISAM MERGE table if handle_locking is 0 then exit with error if some database is locked if handle_locking is 1 then wait if database is locked */ -MYRG_INFO *myrg_open( -const char *name, -int mode, -int handle_locking) +MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) { int save_errno,i,errpos; uint files,dir_length,length,options; @@ -63,25 +60,34 @@ int handle_locking) { if ((end=buff+length)[-1] == '\n') end[-1]='\0'; - if (buff[0] && buff[0] != '#') /* Skipp empty lines and comments */ + if (!buff[0]) + continue; /* Skip empty lines */ + if (buff[0] == '#') { - if (!test_if_hard_path(buff)) - { - VOID(strmake(name_buff+dir_length,buff, - sizeof(name_buff)-1-dir_length)); - VOID(cleanup_dirname(buff,name_buff)); + if( !strncmp(buff+1,"INSERT_METHOD=",14)) + { /* Lookup insert method */ + int tmp=find_type(buff+15,&merge_insert_method,2); + info.merge_insert_method = (uint) (tmp >= 0 ? tmp : 0); } - if (!(isam=mi_open(buff,mode,test(handle_locking)))) - goto err; - files++; - last_isam=isam; - if (info.reclength && info.reclength != isam->s->base.reclength) - { - my_errno=HA_ERR_WRONG_IN_RECORD; - goto err; - } - info.reclength=isam->s->base.reclength; + continue; /* Skip comments */ } + + if (!test_if_hard_path(buff)) + { + VOID(strmake(name_buff+dir_length,buff, + sizeof(name_buff)-1-dir_length)); + VOID(cleanup_dirname(buff,name_buff)); + } + if (!(isam=mi_open(buff,mode,test(handle_locking)))) + goto err; + files++; + last_isam=isam; + if (info.reclength && info.reclength != isam->s->base.reclength) + { + my_errno=HA_ERR_WRONG_IN_RECORD; + goto err; + } + info.reclength=isam->s->base.reclength; } if (!(m_info= (MYRG_INFO*) my_malloc(sizeof(MYRG_INFO)+ files*sizeof(MYRG_TABLE), diff --git a/myisammrg/myrg_static.c b/myisammrg/myrg_static.c index 88eb095382b..ad57ea847d5 100644 --- a/myisammrg/myrg_static.c +++ b/myisammrg/myrg_static.c @@ -24,3 +24,7 @@ #endif LIST *myrg_open_list=0; +static const char *merge_insert_methods[] = +{ "FIRST", "LAST", NullS }; +TYPELIB merge_insert_method= { array_elements(merge_insert_methods),"", + merge_insert_methods}; diff --git a/myisammrg/myrg_write.c b/myisammrg/myrg_write.c new file mode 100644 index 00000000000..b1b0b33f73d --- /dev/null +++ b/myisammrg/myrg_write.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2001 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 */ + +/* Write a row to a MyISAM MERGE table */ + +#include "mymrgdef.h" + +int myrg_write(register MYRG_INFO *info, byte *rec) +{ + /* [phi] MERGE_WRITE_DISABLED is handled by the else case */ + if (info->merge_insert_method == MERGE_INSERT_TO_FIRST) + return mi_write(info->open_tables[0].table,rec); + else if (info->merge_insert_method == MERGE_INSERT_TO_LAST) + return mi_write(info->end_table[-1].table,rec); + else /* unsupported insertion method */ + return (my_errno=HA_ERR_WRONG_COMMAND); +} diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 4c67ec10bb3..5c4a62d5c41 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -61,7 +61,7 @@ CREATE TABLE t1 ( INSERT INTO t1 (pseudo,pseudo1,same) VALUES ('joce', 'testtt', 1),('joce', 'tsestset', 1),('dekad', 'joce', 1); SELECT pseudo FROM t1 WHERE pseudo1='joce' UNION SELECT pseudo FROM t1 WHERE pseudo='joce'; SELECT pseudo1 FROM t1 WHERE pseudo1='joce' UNION SELECT pseudo1 FROM t1 WHERE pseudo='joce'; -SELECT * FROM t1 WHERE pseudo1='joce' UNION SELECT * FROM t1 WHERE pseudo='joce' order by pseudo desc; +SELECT * FROM t1 WHERE pseudo1='joce' UNION SELECT * FROM t1 WHERE pseudo='joce' order by pseudo desc,pseudo1 desc; SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION SELECT pseudo FROM t1 WHERE pseudo1='joce'; SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION ALL SELECT pseudo FROM t1 WHERE pseudo1='joce'; SELECT pseudo1 FROM t1 WHERE pseudo='joce' UNION SELECT 1; diff --git a/sql/Makefile.am b/sql/Makefile.am index f6d7888691d..ea29aa2e5a7 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -57,7 +57,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ sql_select.h structs.h table.h sql_udf.h hash_filo.h\ lex.h lex_symbol.h sql_acl.h sql_crypt.h md5.h \ log_event.h mini_client.h sql_repl.h slave.h \ - stacktrace.h sql_sort.h mysql_embed.h + stacktrace.h sql_sort.h mysqld_SOURCES = sql_lex.cc sql_handler.cc \ item.cc item_sum.cc item_buff.cc item_func.cc \ item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \ diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 722f5226980..cfd859acf06 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -216,7 +216,7 @@ you have to change 'main' to print out the new function\n"); return(1); } - if (opt_verbose) + if (opt_verbose > 1) fprintf (stderr,"Info: Possible add values: %d\n",found-type_count); for (prime=primes; (function_mod=*prime) ; prime++) @@ -376,7 +376,7 @@ static int get_options(int argc, char **argv) opt_search=1; break; case 'v': - opt_verbose=1; + opt_verbose++; break; case 'V': usage(1); exit(0); case 'I': @@ -473,7 +473,7 @@ int main(int argc,char **argv) MY_INIT(argv[0]); - start_value=2250933L; best_t1=2721579L; best_t2=4627039L; best_type=3; /* mode=4567 add=4 type: 0 */ + start_value=4198729L; best_t1=6245075L; best_t2=3686256L; best_type=4; /* mode=5839 add=1 type: 0 */ if (get_options(argc,(char **) argv)) exit(1); @@ -493,7 +493,7 @@ int main(int argc,char **argv) printf("start_value=%ldL; best_t1=%ldL; best_t2=%ldL; best_type=%d; /* mode=%d add=%d type: %d */\n", start_value, best_t1,best_t2,best_type,best_mod,best_add, best_functype); - + best_start_value=start_value; for (uint i=1 ; i <= opt_count ; i++) { if (i % 10 == 0) @@ -516,6 +516,10 @@ int main(int argc,char **argv) best_start_value,best_t1,best_t2,best_type,best_mod,best_add, best_functype); } + if (opt_verbose && (i % 20000) == 0) + printf("\nstart_value=%ldL; best_t1=%ldL; best_t2=%ldL; best_type=%d; /* mode=%d add=%d type: %d */\n", + best_start_value,best_t1,best_t2,best_type,best_mod,best_add, + best_functype); } } diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index abcf81806ad..92c1372a7a1 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -66,7 +66,13 @@ int ha_myisammrg::close(void) int ha_myisammrg::write_row(byte * buf) { - return (my_errno=HA_ERR_WRONG_COMMAND); + statistic_increment(ha_write_count,&LOCK_status); + if (table->time_stamp) + update_timestamp(buf+table->time_stamp-1); + if (table->next_number_field && buf == table->record[0]) + return (my_errno=HA_ERR_WRONG_COMMAND); + // update_auto_increment(); - [phi] have to check this before allowing it + return myrg_write(file,buf); } int ha_myisammrg::update_row(const byte * old_data, byte * new_data) @@ -217,6 +223,7 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd, void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info) { + // [phi] auto_increment stuff is missing (but currently not needed) DBUG_ENTER("ha_myisammrg::update_create_info"); if (!(create_info->used_fields & HA_CREATE_USED_UNION)) { @@ -241,6 +248,10 @@ void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info) } *create_info->merge_list.next=0; } + if (!(create_info->used_fields & HA_CREATE_USED_INSERT_METHOD)) + { + create_info->merge_insert_method = file->merge_insert_method; + } DBUG_VOID_RETURN; err: @@ -263,12 +274,20 @@ int ha_myisammrg::create(const char *name, register TABLE *form, *pos++= tables->real_name; *pos=0; DBUG_RETURN(myrg_create(fn_format(buff,name,"","",2+4+16), - (const char **) table_names, (my_bool) 0)); + (const char **) table_names, + create_info->merge_insert_method, + (my_bool) 0)); } void ha_myisammrg::append_create_info(String *packet) { char buff[FN_REFLEN]; + if (file->merge_insert_method != MERGE_INSERT_DISABLED) + { + packet->append(" INSERT_METHOD=",15); + const char *tmp = get_type(&merge_insert_method,file->merge_insert_method); + packet->append(tmp); + } packet->append(" UNION=(",8); MYRG_TABLE *table,*first; diff --git a/sql/handler.h b/sql/handler.h index 5cf39daeadf..dee71e8ebda 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -120,9 +120,10 @@ enum row_type { ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, ROW_TYPE_DYNAMIC, /* struct to hold information about the table that should be created */ /* Bits in used_fields */ -#define HA_CREATE_USED_AUTO 1 -#define HA_CREATE_USED_RAID 2 -#define HA_CREATE_USED_UNION 4 +#define HA_CREATE_USED_AUTO 1 +#define HA_CREATE_USED_RAID 2 +#define HA_CREATE_USED_UNION 4 +#define HA_CREATE_USED_INSERT_METHOD 8 typedef struct st_thd_trans { void *bdb_tid; @@ -150,6 +151,7 @@ typedef struct st_ha_create_information bool if_not_exists; ulong used_fields; SQL_LIST merge_list; + uint merge_insert_method; } HA_CREATE_INFO; diff --git a/sql/lex.h b/sql/lex.h index ca797e5b894..5decf089e68 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -178,6 +178,7 @@ static SYMBOL symbols[] = { { "INNODB", SYM(INNOBASE_SYM),0,0}, { "INSERT", SYM(INSERT),0,0}, { "INSERT_ID", SYM(INSERT_ID),0,0}, + { "INSERT_METHOD", SYM(INSERT_METHOD),0,0}, { "INT", SYM(INT_SYM),0,0}, { "INTEGER", SYM(INT_SYM),0,0}, { "INTERVAL", SYM(INTERVAL_SYM),0,0}, diff --git a/sql/mini_client.cc b/sql/mini_client.cc index 1afe4c97b8e..d60a3bce880 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -22,7 +22,6 @@ in case we decide to make them external at some point */ -#define DONT_USE_RAID #if defined(__WIN__) #include #include @@ -41,6 +40,7 @@ inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __a #endif #include +#include #include #include #include diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 43650f365bb..59fee295b60 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -31,6 +31,7 @@ #include #endif #include +#include "mysql_embed.h" #include #include #include diff --git a/sql/sql_show.cc b/sql/sql_show.cc index b51e9ab5a73..67713b85720 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -17,7 +17,6 @@ /* Function with list databases, tables or fields */ -#include "my_global.h" #include "mysql_priv.h" #include "sql_select.h" // For select_describe #include "sql_acl.h" diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6d80234082d..1995c1295f1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -27,6 +27,7 @@ #include "sql_acl.h" #include "lex_symbol.h" #include +#include extern void yyerror(const char*); int yylex(void *yylval); @@ -390,6 +391,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token IDENTIFIED_SYM %token IF %token INSERT_ID +%token INSERT_METHOD %token INTERVAL_SYM %token LAST_INSERT_ID %token LEFT @@ -490,7 +492,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); table_option opt_if_not_exists %type - ULONG_NUM raid_types + ULONG_NUM raid_types merge_insert_types %type ulonglong_num @@ -796,6 +798,7 @@ create_table_option: table_list->next=0; lex->create_info.used_fields|= HA_CREATE_USED_UNION; } + | INSERT_METHOD EQ merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;} | DATA_SYM DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.data_file_name= $4.str; } | INDEX DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.index_file_name= $4.str; } @@ -819,6 +822,11 @@ raid_types: | RAID_0_SYM { $$= RAID_TYPE_0; } | ULONG_NUM { $$=$1;} +merge_insert_types: + NO_SYM { $$= MERGE_INSERT_DISABLED; } + | FIRST_SYM { $$= MERGE_INSERT_TO_FIRST; } + | LAST_SYM { $$= MERGE_INSERT_TO_LAST; } + opt_select_from: /* empty */ | select_from select_lock_type @@ -2862,6 +2870,7 @@ keyword: | ISAM_SYM {} | ISSUER_SYM {} | INNOBASE_SYM {} + | INSERT_METHOD {} | LAST_SYM {} | LEVEL_SYM {} | LOCAL_SYM {} From 5d9be4de24ab02436edbe2c75e96704a31c522b2 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Sat, 22 Sep 2001 17:40:59 +0300 Subject: [PATCH 06/15] Portability fix --- client/mysqltest.c | 22 +++++++++------------- sql/gen_lex_hash.cc | 5 +++-- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 1361dc843ed..9a2d3e4c137 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -46,19 +46,15 @@ #define MTEST_VERSION "1.10" #include +#include #include #include #include #include +#include #include -#ifdef OS2 -#include -#else - #include -#endif #include #include -#include #include #include #include @@ -1067,18 +1063,18 @@ int close_connection(struct st_query* q) p++; *p = 0; - for(con = cons; con < next_con; con++) + for (con = cons; con < next_con; con++) { if (!strcmp(con->name, name)) { - if(q->type == Q_DIRTY_CLOSE) + if (q->type == Q_DIRTY_CLOSE) + { + if (con->mysql.net.vio) { - if(con->mysql.net.vio) - { - vio_delete(con->mysql.net.vio); - con->mysql.net.vio = 0; - } + vio_delete(con->mysql.net.vio); + con->mysql.net.vio = 0; } + } mysql_close(&con->mysql); DBUG_RETURN(0); diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index cfd859acf06..6530e5dd4cf 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -26,7 +26,8 @@ #include "mysql_version.h" #include "lex.h" -bool opt_search=0,opt_verbose=0; +bool opt_search=0; +int opt_verbose=0; ulong opt_count=100000; #define max_allowed_array 8000 // Don't generate bigger arrays than this @@ -473,7 +474,7 @@ int main(int argc,char **argv) MY_INIT(argv[0]); - start_value=4198729L; best_t1=6245075L; best_t2=3686256L; best_type=4; /* mode=5839 add=1 type: 0 */ + start_value=1060872L; best_t1=7930739L; best_t2=4311642L; best_type=3; /* mode=5333 add=6 type: 0 */ if (get_options(argc,(char **) argv)) exit(1); From 3b774da463986509975aacb933acd7f4fb31a774 Mon Sep 17 00:00:00 2001 From: "Miguel@light.local" <> Date: Tue, 25 Sep 2001 01:13:19 -0300 Subject: [PATCH 07/15] Changes on NT service for a more faster stop of the service on Win2k and free the main thread of the service. --- BitKeeper/etc/logging_ok | 22 +--------------------- sql/mysqld.cc | 2 +- sql/nt_servc.cc | 3 ++- 3 files changed, 4 insertions(+), 23 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 390c414d29c..efa9faefd05 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -1,21 +1 @@ -davida@isil.mysql.com -heikki@donna.mysql.fi -jani@hynda.mysql.fi -jani@janikt.pp.saunalahti.fi -jcole@tetra.spaceapes.com -miguel@light.local -monty@bitch.mysql.fi -monty@hundin.mysql.fi -monty@tik.mysql.fi -monty@work.mysql.com -mwagner@evoq.mwagner.org -paul@central.snake.net -paul@teton.kitebird.com -sasha@mysql.sashanet.com -serg@serg.mysql.com -tim@bitch.mysql.fi -tim@threads.polyesthetic.msg -tim@white.box -tim@work.mysql.com -tonu@x153.internalnet -tfr@sarvik.tfr.cafe.ee +Miguel@light.local diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a124eea7807..435ee51a0e0 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2006,7 +2006,7 @@ The server will not act as a slave."); { if(start_mode) { - if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0) + if (WaitForSingleObject(hEventShutdown,1000)==WAIT_TIMEOUT) Service.Stop(); } else diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc index 5884300fe95..3a36f5740a9 100644 --- a/sql/nt_servc.cc +++ b/sql/nt_servc.cc @@ -246,7 +246,8 @@ void NTService::ServiceMain(DWORD argc, LPTSTR *argv) WaitForSingleObject (pService->hExitEvent, INFINITE); // wait for thread to exit - WaitForSingleObject (pService->hThreadHandle, 30000); + if (WaitForSingleObject (pService->hThreadHandle, 1000)==WAIT_TIMEOUT) + CloseHandle(pService->hThreadHandle); pService->Exit(0); } From 3e4ff5dcccb7d1e016d12048de2ee94f972d6d13 Mon Sep 17 00:00:00 2001 From: "paul@central.snake.net" <> Date: Thu, 27 Sep 2001 12:25:36 -0500 Subject: [PATCH 08/15] manual.texi correct date error in manual. --- BitKeeper/etc/logging_ok | 1 + Docs/manual.texi | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index efa9faefd05..02c76aa4b4a 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -1 +1,2 @@ Miguel@light.local +paul@central.snake.net diff --git a/Docs/manual.texi b/Docs/manual.texi index 6dd44a79288..8b51e73f9a2 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -12788,7 +12788,7 @@ this may be different than what you are used to.) @item Claws @tab Gwen @tab cat @tab m @tab 1994-03-17 @tab @item Buffy @tab Harold @tab dog @tab f @tab 1989-05-13 @tab @item Fang @tab Benny @tab dog @tab m @tab 1990-08-27 @tab -@item Bowser @tab Diane @tab dog @tab m @tab 1989-08-31 @tab 1995-07-29 +@item Bowser @tab Diane @tab dog @tab m @tab 1998-08-31 @tab 1995-07-29 @item Chirpy @tab Gwen @tab bird @tab f @tab 1998-09-11 @tab @item Whistler @tab Gwen @tab bird @tab @tab 1997-12-09 @tab @item Slim @tab Benny @tab snake @tab m @tab 1996-04-29 @tab From 0a03293ed0a7fbbb676cd555d6907f4d70704386 Mon Sep 17 00:00:00 2001 From: "paul@teton.kitebird.com" <> Date: Thu, 27 Sep 2001 12:31:40 -0500 Subject: [PATCH 09/15] manual.texi correct date error in tutorial. --- Docs/manual.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index c88455289c8..d0947065b2d 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -12844,7 +12844,7 @@ this may be different than what you are used to.) @item Claws @tab Gwen @tab cat @tab m @tab 1994-03-17 @tab @item Buffy @tab Harold @tab dog @tab f @tab 1989-05-13 @tab @item Fang @tab Benny @tab dog @tab m @tab 1990-08-27 @tab -@item Bowser @tab Diane @tab dog @tab m @tab 1989-08-31 @tab 1995-07-29 +@item Bowser @tab Diane @tab dog @tab m @tab 1998-08-31 @tab 1995-07-29 @item Chirpy @tab Gwen @tab bird @tab f @tab 1998-09-11 @tab @item Whistler @tab Gwen @tab bird @tab @tab 1997-12-09 @tab @item Slim @tab Benny @tab snake @tab m @tab 1996-04-29 @tab From 89f92db6b8a33832a1adb8ecb65fa883e688479c Mon Sep 17 00:00:00 2001 From: "paul@central.snake.net" <> Date: Thu, 27 Sep 2001 12:31:59 -0500 Subject: [PATCH 10/15] manual.texi typo fixes. --- Docs/manual.texi | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 8b51e73f9a2..46e7ffcf6c7 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -17191,7 +17191,7 @@ knowing your 'scrambled' password is enough to be able to connect to the MySQL server! @end itemize -MySQL users and they privileges are normally created with the +MySQL users and their privileges are normally created with the @code{GRANT} command. @xref{GRANT}. When you login to a MySQL server with a command line client you @@ -17217,13 +17217,14 @@ mysql -u monty -p database_name Note that in the last example the password is @strong{NOT} 'database_name'. -If you want to use the @code{-p} option to supply a password you should do like this: +If you want to use the @code{-p} option to supply a password you should do so +like this: @example mysql -u monty -pguess database_name @end example -On some system the library call that MySQL uses to prompt for a +On some systems, the library call that MySQL uses to prompt for a password will automatically cut the password to 8 characters. Internally MySQL doesn't have any limit for the length of the password. From a80e32a4073eaa7428347af5fda8ca6b873d90bb Mon Sep 17 00:00:00 2001 From: "paul@teton.kitebird.com" <> Date: Thu, 27 Sep 2001 12:36:28 -0500 Subject: [PATCH 11/15] manual.texi typo fixes. --- Docs/manual.texi | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index d0947065b2d..908230a4745 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -17248,7 +17248,7 @@ knowing your 'scrambled' password is enough to be able to connect to the MySQL server! @end itemize -MySQL users and they privileges are normally created with the +MySQL users and their privileges are normally created with the @code{GRANT} command. @xref{GRANT}. When you login to a MySQL server with a command line client you @@ -17274,13 +17274,14 @@ mysql -u monty -p database_name Note that in the last example the password is @strong{NOT} 'database_name'. -If you want to use the @code{-p} option to supply a password you should do like this: +If you want to use the @code{-p} option to supply a password you should do so +like this: @example mysql -u monty -pguess database_name @end example -On some system the library call that MySQL uses to prompt for a +On some systems, the library call that MySQL uses to prompt for a password will automatically cut the password to 8 characters. Internally MySQL doesn't have any limit for the length of the password. From 99b58a5aa9ae729d95b00650b8360820bafe3887 Mon Sep 17 00:00:00 2001 From: "monty@tik.mysql.fi" <> Date: Thu, 27 Sep 2001 21:35:35 +0300 Subject: [PATCH 12/15] Cleaned up udf_example.cc and mysql_fix_privilege_tables --- acinclude.m4 | 2 +- scripts/mysql_fix_privilege_tables.sh | 13 ++++++------- sql/udf_example.cc | 25 +++++++++++++++---------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 86eed5e69c7..1eb95e1e9c9 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1106,7 +1106,7 @@ changequote([, ])dnl AC_DEFUN(AC_SYS_LARGEFILE, [AC_REQUIRE([AC_CANONICAL_HOST]) AC_ARG_ENABLE(largefile, - [ --disable-large-files Omit support for large files]) + [ --disable-largefile Omit support for large files]) if test "$enable_largefile" != no; then AC_CHECK_TOOL(GETCONF, getconf) AC_SYS_LARGEFILE_FLAGS(CFLAGS) diff --git a/scripts/mysql_fix_privilege_tables.sh b/scripts/mysql_fix_privilege_tables.sh index 8e9ef509d66..86312fdab52 100644 --- a/scripts/mysql_fix_privilege_tables.sh +++ b/scripts/mysql_fix_privilege_tables.sh @@ -3,8 +3,8 @@ echo "This scripts updates the mysql.user, mysql.db, mysql.host and the" echo "mysql.func table to MySQL 3.22.14 and above." echo "" -echo "This is needed if you want to use the new GRANT functions or" -echo "want to use the more secure passwords." +echo "This is needed if you want to use the new GRANT functions," +echo "CREATE AGGREAGATE FUNCTION or want to use the more secure passwords in 3.23" echo "" echo "If you get Access denied errors, you should run this script again" echo "and give the MySQL root user password as a argument!" @@ -15,13 +15,12 @@ host="localhost" # Fix old password format, add File_priv and func table echo "" echo "If your tables are already up to date or partially up to date you will" -echo "get some warnings about 'Duplicated column name' or" -echo "'Table 'func' already exists'. You can safely ignore these!" +echo "get some warnings about 'Duplicated column name'. You can safely ignore these!" @bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <h_name) - result); return result; } +#endif // defined(HAVE_GETHOSTBYADDR_R) && defined(HAVE_SOLARIS_STYLE_GETHOST) /* ** Syntax for the new aggregate commands are: @@ -777,13 +790,6 @@ char *reverse_lookup(UDF_INIT *initid, UDF_ARGS *args, char *result, ** (this example is provided by Andreas F. Bobak ) */ -extern "C" { -my_bool avgcost_init( UDF_INIT* initid, UDF_ARGS* args, char* message ); -void avgcost_deinit( UDF_INIT* initid ); -void avgcost_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); -void avgcost_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); -double avgcost( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); -} struct avgcost_data { @@ -810,7 +816,7 @@ avgcost_init( UDF_INIT* initid, UDF_ARGS* args, char* message ) return 1; } - if ((args->arg_type[0] != INT_RESULT) && (args->arg_type[1] != REAL_RESULT) ) + if ((args->arg_type[0] != INT_RESULT) || (args->arg_type[1] != REAL_RESULT) ) { strcpy( message, @@ -917,5 +923,4 @@ avgcost( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* error ) return data->totalprice/double(data->totalquantity); } -#endif // defined(HAVE_GETHOSTBYADDR_R) && defined(HAVE_SOLARIS_STYLE_GETHOST) #endif /* HAVE_DLOPEN */ From e05bf277d6529b61bf74cf0b8b3e6efd994869a0 Mon Sep 17 00:00:00 2001 From: "monty@tik.mysql.fi" <> Date: Thu, 27 Sep 2001 21:45:48 +0300 Subject: [PATCH 13/15] Final fixes for INSERT into MERGE tables. Move MAX_BLOB_WIDTH to be global Added full support for unsigned BIGINT Fixed spelling errors --- BUILD/compile-pentium-debug-max | 2 +- Docs/manual.texi | 285 ++++++++++++++++++++------------ acinclude.m4 | 13 +- configure.in | 10 +- include/mysql_com.h | 2 + myisammrg/myrg_create.c | 2 +- myisammrg/myrg_static.c | 2 +- mysql-test/r/bigint.result | 16 ++ mysql-test/r/merge.result | 202 ++++++++++++++++++++++ mysql-test/r/type_ranges.result | 2 +- mysql-test/t/bigint.test | 15 ++ mysql-test/t/merge.test | 56 ++++++- mysys/typelib.c | 3 +- sql/field.h | 7 +- sql/ha_berkeley.cc | 2 +- sql/ha_gemini.cc | 2 +- sql/ha_myisam.cc | 2 +- sql/ha_myisammrg.cc | 8 +- sql/item.cc | 6 +- sql/item.h | 1 + sql/item_func.cc | 28 +++- sql/item_strfunc.cc | 4 +- sql/item_sum.cc | 131 +++++++++++---- sql/item_sum.h | 4 +- sql/mf_iocache.cc | 2 +- sql/mysql_priv.h | 1 - sql/mysqld.cc | 6 +- sql/opt_range.cc | 2 +- sql/sql_base.cc | 11 +- sql/sql_insert.cc | 4 +- sql/sql_lex.h | 2 +- sql/sql_parse.cc | 4 +- sql/sql_select.cc | 4 +- sql/structs.h | 2 +- sql/time.cc | 2 +- sql/unireg.cc | 6 +- 36 files changed, 653 insertions(+), 198 deletions(-) diff --git a/BUILD/compile-pentium-debug-max b/BUILD/compile-pentium-debug-max index ccd6faa0448..4149267811d 100755 --- a/BUILD/compile-pentium-debug-max +++ b/BUILD/compile-pentium-debug-max @@ -8,6 +8,6 @@ c_warnings="$c_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings" extra_configs="$pentium_configs $debug_configs" -extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-vio --with-openssl --with-embedded-server" +extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-embedded-server" . "$path/FINISH.sh" diff --git a/Docs/manual.texi b/Docs/manual.texi index c88455289c8..b1815b4eac9 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -4368,6 +4368,7 @@ precision, @code{IF}, and @code{ELT()} with @code{BIGINT} or @code{DOUBLE} precision and the rest with @code{DOUBLE} precision. One should try to avoid using bigger unsigned long long values than 63 bits (9223372036854775807) for anything else than bit fields! +MySQL 4.0 has better @code{BIGINT} handling than 3.23. @item All string columns, except @code{BLOB} and @code{TEXT} columns, automatically @@ -5690,6 +5691,15 @@ implemented in the 4.0 tree. @xref{News-4.0.x}. @itemize @bullet @item +Allow users to change startup options without taking down the server. +@item +Fail safe replication. +@item +More functions for full-text search. +@xref{Fulltext Features to Appear in MySQL 4.0}. +@item +New key cache +@item New table definition file format (@code{.frm} files) This will enable us to not run out of bits when adding more table options. One will still be able to use the old @code{.frm} file format with 4.0. All newly created @@ -5698,19 +5708,6 @@ tables will, however, use the new format. The new file format will enable us to add new column types, more options for keys and @code{FOREIGN KEY} support. @item -@code{mysqld} as a library. This will have the same interface as the -standard MySQL client (with an extra function to just set up -startup parameters) but will be faster (no TCP/IP or socket overhead), -smaller and much easier to use for embedded products. - -One will be able to define at link time if one wants to use the -client/server model or a stand-alone application just by defining which -library to link with. - -The @code{mysqld} will support all standard MySQL features and -one can use it in a threaded client to run different queries in each -thread. -@item Replication should work with @code{RAND()} and user variables @code{@@var}. @item Online backup with very low performance penalty. The online backup will @@ -5720,15 +5717,8 @@ Allow @code{DELETE} on @code{MyISAM} tables to use the record cache. To do this, we need to update the threads record cache when we update the @code{.MYD} file. @item -Better replication. -@item -More functions for full-text search. -@xref{Fulltext Features to Appear in MySQL 4.0}. -@item Character set casts and syntax for handling multiple character sets. @item -Allow users to change startup options without taking down the server. -@item Help for all commands from the client. @item Secure connections (with SSL). @@ -5737,8 +5727,6 @@ Secure connections (with SSL). expansions of column names) should not open the table, but only the definition file. This will require less memory and be much faster. @item -New key cache -@item When using @code{SET CHARACTER SET} we should translate the whole query at once and not only strings. This will enable users to use the translated characters in database, table and column names. @@ -5760,11 +5748,12 @@ of @code{analyze} is run on all sub tables. @itemize @bullet @item -Fail safe replication. -@item Subqueries. @code{select id from t where grp in (select grp from g where u > 100)} @item +Atomic multi-table updates, eg @code{update items,month set +items.price=month.price where items.id=month.id;}; +@item Derived tables. @example select a.col1, b.col2 from (select max(col1) as col1 from root_table ) a, @@ -6046,9 +6035,6 @@ if it exists and @code{INSERT} a new row if the row didn't exist. @item Implement function: @code{get_changed_tables(timeout,table1,table2,...)} @item -Atomic multi-table updates, eg @code{update items,month set -items.price=month.price where items.id=month.id;}; -@item Change reading through tables to use memmap when possible. Now only compressed tables use memmap. @item @@ -6144,8 +6130,6 @@ Nothing; In the long run we plan to be fully ANSI 92 / ANSI 99 compliant. @end itemize - - @node Installing, Tutorial, Introduction, Top @chapter MySQL Installation @@ -9349,7 +9333,7 @@ you have to use @code{mysqldump}. Old clients should work with a Version 4.0 server without any problems. The following lists tell what you have to watch out for when upgrading to -Version 4.0; +version 4.0; @itemize @bullet @item @@ -9366,6 +9350,15 @@ from a table and you don't care of how many rows where deleted. You will get an error if you have an active @code{LOCK TABLES} or transaction when trying to execute @code{TRUNCATE TABLE} or @code{DROP DATABASE}. +@item +You should use integers to store values in BIGINT columns (instead of using +strings as you did in MySQL 3.23). Using strings will still work, but using +integers is more efficient. +@item +Format of @code{SHOW OPEN TABLE} has changed. +@item +Multithreaded clients should use @code{mysql_thread_init()} and +@code{mysql_thread_end()}. @xref{Threaded clients}. @end itemize @node Upgrading-from-3.22, Upgrading-from-3.21, Upgrading-from-3.23, Upgrade @@ -20270,19 +20263,13 @@ operations. @item @code{table_cache} The number of open tables for all threads. Increasing this value increases the number of file descriptors that @code{mysqld} requires. -MySQL needs two file descriptors for each unique open table. -See below for comments on file descriptor limits. You can check if you -need to increase the table cache by checking the @code{Opened_tables} -variable. @xref{SHOW}. If this variable is big and you don't do -@code{FLUSH TABLES} a lot (which just forces all tables to be closed and -reopenend), then you should increase the value of this variable. +You can check if you need to increase the table cache by checking the +@code{Opened_tables} variable. @xref{SHOW}. If this variable is big and +you don't do @code{FLUSH TABLES} a lot (which just forces all tables to +be closed and reopenend), then you should increase the value of this +variable. -Make sure that your operating system can handle the number of open file -descriptors implied by the @code{table_cache} setting. If @code{table_cache} -is set too high, MySQL may run out of file descriptors and refuse -connections, fail to perform queries, and be very unreliable. - -For information about how the table cache works, see @ref{Table cache}. +For more information about the table cache, see @ref{Table cache}. @item @code{table_type} The default table type @@ -26430,6 +26417,16 @@ at least @code{200 * n}, where @code{n} is the maximum number of tables in a join. You also need to reserve some extra file descriptors for temporary tables and files. +Make sure that your operating system can handle the number of open file +descriptors implied by the @code{table_cache} setting. If +@code{table_cache} is set too high, MySQL may run out of file +descriptors and refuse connections, fail to perform queries, and be very +unreliable. You also have to take into account that the MyISAM table +handler needs two file descriptors for each unique open table. You can +in increase the number of file descriptors available for MySQL with +the @code{--open-files-limit=#} startup option. @xref{Not enough file +handles}. + The cache of open tables can grow to a maximum of @code{table_cache} (default 64; this can be changed with the @code{-O table_cache=#} option to @code{mysqld}). A table is never closed, except when the @@ -26461,6 +26458,12 @@ use of the table takes only one file descriptor. The extra descriptor for the first open is used for the index file; this descriptor is shared among all threads. +If you are opening a table with the @code{HANDLER table_name OPEN} +statement, a dedicated table object is allocated for the thread. +This table object is not shared by other threads an will not be closed +until the thread calls @code{HANDLER table_name CLOSE} or the thread dies. +@xref{HANDLER}. + You can check if your table cache is too small by checking the mysqld variable @code{opened_tables}. If this is quite big, even if you haven't done a lot of @code{FLUSH TABLES}, you should increase your table @@ -28116,14 +28119,23 @@ values, so you shouldn't use unsigned big integers larger than @code{9223372036854775807} (63 bits) except with bit functions! If you do that, some of the last digits in the result may be wrong because of rounding errors when converting the @code{BIGINT} to a @code{DOUBLE}. + +MySQL 4.0 can handle @code{BIGINT} in the following cases: +@itemize @bullet +@item +Use integers to store big unsigned values in a @code{BIGINT} column. +@item +In @code{MIN(big_int_column)} and @code{MAX(big_int_column)}. +@item +When using operators (@code{+}, @code{-}, @code{*} etc) where +both operands are integers. +@end itemize + @item You can always store an exact integer value in a @code{BIGINT} column by storing it as a string, as there is in this case there will be no intermediate double representation. @item -In MySQL 4.0 you can use integers to store big unsigned values in a -@code{BIGINT} string. -@item @samp{-}, @samp{+}, and @samp{*} will use @code{BIGINT} arithmetic when both arguments are @code{INTEGER} values! This means that if you multiply two big integers (or results from functions that return @@ -33818,6 +33830,7 @@ or DELAY_KEY_WRITE = @{0 | 1@} or ROW_FORMAT= @{ default | dynamic | fixed | compressed @} or RAID_TYPE= @{1 | STRIPED | RAID0 @} RAID_CHUNKS=# RAID_CHUNKSIZE=# or UNION = (table_name,[table_name...]) +or INSERT_METHOD= @{NO | FIRST | LAST @} or DATA DIRECTORY="directory" or INDEX DIRECTORY="directory" @@ -34160,13 +34173,13 @@ original tables, MySQL will not allow concurrent inserts during @code{CREATE TABLE .... SELECT}. @item The @code{RAID_TYPE} option will help you to break the 2G/4G limit for -the MyISAM data file (not the index file) on -operating systems that don't support big files. You can get also more speed -from the I/O bottleneck by putting @code{RAID} directories on different -physical disks. @code{RAID_TYPE} will work on any OS, as long as you have -configured MySQL with @code{--with-raid}. For now the only allowed -@code{RAID_TYPE} is @code{STRIPED} (@code{1} and @code{RAID0} are aliases -for this). +the MyISAM data file (not the index file) on operating systems that +don't support big files. +You can get more speed from the I/O bottleneck by putting +@code{RAID} directories on different physical disks. @code{RAID_TYPE} +will work on any OS, as long as you have configured MySQL with +@code{--with-raid}. For now the only allowed @code{RAID_TYPE} is +@code{STRIPED} (@code{1} and @code{RAID0} are aliases for this). If you specify @code{RAID_TYPE=STRIPED} for a @code{MyISAM} table, @code{MyISAM} will create @code{RAID_CHUNKS} subdirectories named 00, @@ -34182,6 +34195,12 @@ tables as one. This only works with MERGE tables. @xref{MERGE}. For the moment you need to have @code{SELECT}, @code{UPDATE}, and @code{DELETE} privileges on the tables you map to a @code{MERGE} table. All mapped tables must be in the same database as the @code{MERGE} table. + +@item +If you want to insert data in a @code{MERGE} table, you have to specify with +@code{INSERT_METHOD} into with table the row should be inserted. +@xref{MERGE}. + @item In the created table the @code{PRIMARY} key will be placed first, followed by all @code{UNIQUE} keys and then the normal keys. This helps the @@ -35005,6 +35024,8 @@ interface, bypassing SQL optimizer. Thus, it is faster then SELECT. The first form of @code{HANDLER} statement opens a table, making in accessible via the following @code{HANDLER ... READ} routines. +This table object is not shared by other threads an will not be closed +until the thread calls @code{HANDLER table_name CLOSE} or the thread dies. The second form fetches one (or, specified by @code{LIMIT} clause) row where the index specified complies to the condition and @code{WHERE} @@ -35023,8 +35044,8 @@ in data file) matching @code{WHERE} condition. It is faster than The last form closes the table, opened with @code{HANDLER ... OPEN}. @code{HANDLER} is somewhat low-level statement, for example it does not -provide consistency. That is @code{HANDLER ... OPEN} does @strong{not} -takes a snapshot of the table, and does @strong{not} locks the table. The +provide consistency. That is @code{HANDLER ... OPEN} does @strong{NOT} +takes a snapshot of the table, and does @strong{NOT} locks the table. The above means, that after @code{HANDLER ... OPEN} table data can be modified (by this or other thread) and these modifications may appear only partially in @code{HANDLER ... NEXT} or @code{HANDLER ... PREV} scans. @@ -35885,7 +35906,7 @@ specification. Note that @code{DELETE FROM merge_table} used without a @code{WHERE} will only clear the mapping for the table, not delete everything in the -mapped tables. (We plan to fix this in 4.0). +mapped tables. (We plan to fix this in 4.1). With identical tables we mean that all tables are created with identical column and key information. You can't put a MERGE over tables where the @@ -35945,11 +35966,12 @@ The disadvantages with @code{MERGE} tables are: @itemize @bullet @item -You can't use @code{INSERT} on @code{MERGE} tables, as MySQL -can't know in which of the tables we should insert the row. -@item You can only use identical @code{MyISAM} tables for a @code{MERGE} table. @item +@code{AUTO_INCREMENT} columns are not automaticly updated on @code{INSERT}. +@item +@code{REPLACE} doesn't work. +@item @code{MERGE} tables uses more file descriptors. If you are using a @strong{MERGE} that maps over 10 tables and 10 users are using this, you are using 10*10 + 10 file descriptors. (10 data files for 10 users @@ -35971,6 +35993,14 @@ mapped by a @code{MERGE} table that is 'open'. If you do this, the get unexpected results. @end itemize +When you create a @code{MERGE} table you have to specify with +@code{UNION(list-of-tables)} which tables you want to use as +one. Optionally you can specify with @code{INSERT_METHOD} if you want +insert for the @code{MERGE} table to happen in the first or last table +in the @code{UNION} list. If you don't specify @code{INSERT_METHOD} or +specify @code{NO}, then all @code{INSERT} commands on the @code{MERGE} +table will return an error. + The following example shows you how to use @code{MERGE} tables: @example @@ -35978,7 +36008,7 @@ CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, message CHAR(20)); CREATE TABLE t2 (a INT AUTO_INCREMENT PRIMARY KEY, message CHAR(20)); INSERT INTO t1 (message) VALUES ("Testing"),("table"),("t1"); INSERT INTO t2 (message) VALUES ("Testing"),("table"),("t2"); -CREATE TABLE total (a INT NOT NULL, message CHAR(20), KEY(a)) TYPE=MERGE UNION=(t1,t2); +CREATE TABLE total (a INT NOT NULL, message CHAR(20), KEY(a)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST; @end example Note that we didn't create a @code{UNIQUE} or @code{PRIMARY KEY} in the @@ -38908,19 +38938,37 @@ Note that if you are using MySQL Version 3.22, you must to apply the MDAC patch and use MyODBC 2.50.32 or 2.50.34 and above to go around this problem. @item -Set the ``Return matching rows'' MyODBC option field when connecting to -MySQL. -@item -You should have a primary key in the table. If not, new or updated rows -may show up as @code{#Deleted#}. +For all Access versions, you should enable the MyODBC option flag +@code{Return matching rows}. For Access 2.0, you should additionally enable +@code{Simulate ODBC 1.0}. @item You should have a timestamp in all tables you want to be able to update. For maximum portability @code{TIMESTAMP(14)} or simple @code{TIMESTAMP} is recommended instead of other @code{TIMESTAMP(X)} variations. @item -Only use double float fields. Access fails when comparing with single floats. -The symptom usually is that new or updated rows may show up as @code{#Deleted#} -or that you can't find or update rows. +You should have a primary key in the table. If not, new or updated rows +may show up as @code{#DELETED#}. +@item +Only use @code{DOUBLE} float fields. Access fails when comparing with +single floats. The symptom usually is that new or updated rows may show +up as @code{#DELETED#} or that you can't find or update rows. +@item +If you are linking a table through MyODBC, which has @code{BIGINT} as +one of the column, then the results will be displayed as @code{#DELETED}. The +work around solution is: +@itemize @bullet +@item +Have one more dummy column with @code{TIMESTAMP} as the data type, preferably +@code{TIMESTAMP(14)}. +@item +Check the @code{'Change BIGINT columns to INT'} in connection options dialog in +ODBC DSN Administrator +@item +Delete the table link from access and re-create it. +@end itemize + +It still displays the previous records as @code{#DELETED#}, but newly +added/updated records will be displayed properly. @item If you still get the error @code{Another user has changed your data} after adding a @code{TIMESTAMP} column, the following trick may help you: @@ -38931,6 +38979,10 @@ set the @code{DefaultValue} property for the @code{TIMESTAMP} column to @code{NOW()}. It may be a good idea to hide the @code{TIMESTAMP} column from view so your users are not confused. @item +In some cases, Access may generate illegal SQL queries that +MySQL can't understand. You can fix this by selecting +@code{"Query|SQLSpecific|Pass-Through"} from the Access menu. +@item Access on NT will report @code{BLOB} columns as @code{OLE OBJECTS}. If you want to have @code{MEMO} columns instead, you should change the column to @code{TEXT} with @code{ALTER TABLE}. @@ -38938,19 +38990,9 @@ column to @code{TEXT} with @code{ALTER TABLE}. Access can't always handle @code{DATE} columns properly. If you have a problem with these, change the columns to @code{DATETIME}. @item -In some cases, Access may generate illegal SQL queries that -MySQL can't understand. You can fix this by selecting -@code{"Query|SQLSpecific|Pass-Through"} from the Access menu. -@item -If you have in Access a column defined as BYTE, Access will try to export this -as @code{TINYINT} instead of @code{TINYINT UNSIGNED}. This will give you -problems if you have values > 127 in the column! -@item -If you are using Access 7.0, You should use the option flag @code{Return -matching rows}. -@item -If you are using Access 2.0, You should use the option flags @code{Return -matching rows} and @code{Simulate ODBC 1.0}. +If you have in Access a column defined as @code{BYTE}, Access will try +to export this as @code{TINYINT} instead of @code{TINYINT UNSIGNED}. +This will give you problems if you have values > 127 in the column! @end itemize @cindex ADO program @@ -42971,6 +43013,10 @@ functions}. For the UDF mechanism to work, functions must be written in C or C++, your operating system must support dynamic loading and you must have compiled @code{mysqld} dynamically (not statically). +Note that to make @code{AGGREGATE} work, you must have a +@code{mysql.func} table that contains the column @code{type}. If this +is not the case, you should run the script +@code{mysql_fix_privilege_tables} to get this fixed. @node Adding UDF, Adding native function, CREATE FUNCTION, Adding functions @@ -43135,6 +43181,10 @@ digits. For real functions, the default is 13 plus the number of decimals indicated by @code{initid->decimals}. (For numeric functions, the length includes any sign or decimal point characters.) +If you want to return a blob, you can set this to 65K or 16M; This +memory is not allocated but used to decide which column type to use if +there is a need to temporary store the data. + @item char *ptr A pointer that the function can use for its own purposes. For example, functions can use @code{initid->ptr} to communicate allocated memory @@ -43275,7 +43325,8 @@ terminal screen. The return value of the main function @code{xxx()} is the function value, for @code{long long} and @code{double} functions. A string functions should return a pointer to the result and store the length of the string in the -@code{length} arguments. @code{result} is a buffer at least 255 bytes long. +@code{length} arguments. + Set these to the contents and length of the return value. For example: @example @@ -43283,8 +43334,12 @@ memcpy(result, "result string", 13); *length = 13; @end example -If your string functions that needs to return a string longer than 255 -bytes, you must allocate the space for it with @code{malloc()} in your +The @code{result} buffer that is passed to the calc function is 255 byte +big. If your result fits in this, you don't have to worry about memory +allocation for results. + +If your string function needs to return a string longer than 255 bytes, +you must allocate the space for it with @code{malloc()} in your @code{xxx_init()} function or your @code{xxx()} function and free it in your @code{xxx_deinit()} function. You can store the allocated memory in the @code{ptr} slot in the @code{UDF_INIT} structure for reuse by @@ -43389,6 +43444,7 @@ mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so"; mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so"; mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so"; mysql> CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so"; +mysql> CREATE AGGREGATE FUNCTION avgcost RETURNS REAL SONAME "udf_example.so"; @end example Functions can be deleted using @code{DROP FUNCTION}: @@ -43399,6 +43455,7 @@ mysql> DROP FUNCTION myfunc_double; mysql> DROP FUNCTION myfunc_int; mysql> DROP FUNCTION lookup; mysql> DROP FUNCTION reverse_lookup; +mysql> DROP FUNCTION avgcost; @end example The @code{CREATE FUNCTION} and @code{DROP FUNCTION} statements update the @@ -47308,6 +47365,9 @@ Configure updates for Tru64, large file support and better TCP wrappers support. @item John Birrell Emulation of pthread_mutex() for OS/2. +@item Benjamin Pflugmann +Extended @code{MERGE} tables to handle @code{INSERTS}. Active member +on the MySQL mailing lists. @end table Other contributors, bugfinders, and testers: James H. Thompson, Maurizio @@ -47434,16 +47494,16 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. @itemize @bullet @item -Added documentation for @code{libmysqld}, the embedded -MySQL server library. Also added example programs (a -@code{mysql} client and @code{mysqltest} test program) which use -@code{libmysqld}. +Added documentation for @code{libmysqld}, the embedded MySQL server +library. Also added example programs (a @code{mysql} client and +@code{mysqltest} test program) which use @code{libmysqld}. @item Removed @code{my_thread_init()} and @code{my_thread_end()} from mysql_com.h, and added @code{mysql_thread_init()} and @code{mysql_thread_end()} to mysql.h. @item -Fixed handling of big unsigned bigint constants. +Unsigned @code{BIGINT} constants now work. @code{MIN()} and @code{MAX()} +now handles signed and unsigned @code{BIGINT} numbers correctly. @item New character set @code{latin_de} which provides correct German sorting. @item @@ -47454,45 +47514,40 @@ the number of deleted rows. @code{DROP DATABASE} now executes a @code{DROP TABLE} on all tables in the database, which fixes a problem with InnoDB tables. @item +Added support for @code{UNION}. +@item +A new @code{HANDLER} interface to @code{MyISAM} tables. +@item +Added support for @code{INSERT} on @code{MERGE} tables. Patch from +Benjamin Pflugmann. +@item Changed @code{WEEK(#,0)} to match the calender in the USA. @item -Cleaned up global lock handling for @code{FLUSH TABLES WITH READ LOCK} -@item -Fixed problem with @code{DATETIME = constant} in @code{WHERE} optimization. +@code{COUNT(DISTINCT)} is about 30% faster. @item Speed up all internal list handling. @item -Added support for @code{UNION}. -@item -Allow ANSI SQL syntax @code{X'hexadecimal-number'} +Creating full text indexes are now much faster. @item Tree-like cache to speed up bulk inserts and @code{myisam_bulk_insert_tree_size} variable. @item -Added @code{ALTER TABLE table_name DISABLE KEYS} and -@code{ALTER TABLE table_name ENABLE KEYS} commands. +Searching on packed (@code{CHAR}/@code{VARCHAR}) keys are now much faster. +@item +Optimized queries of type: +@code{SELECT DISTINCT * from table_name ORDER by key_part1 LIMIT #} +@item +@code{ORDER BY ... DESC} can now use keys. @item @code{LOAD DATA FROM MASTER} "auto-magically" sets up a slave. @item Renamed @code{safe_mysqld} to @code{mysqld_safe}. @item -Allow one to use @code{IN} instead of @code{FROM} in @code{SHOW} commands. -@item -@code{SHOW INDEXES} is now a synonym for @code{SHOW INDEX}. -@item Added support for symbolic links to @code{MyISAM} tables. Symlink handling is now enabled by default for Windows. @item @code{LOAD DATA FROM MASTER} "auto-magically" sets up a slave. @item -A new @code{HANDLER} interface to @code{MyISAM} tables. -@item -@code{COUNT(DISTINCT)} is about 30% faster. -@item -Creating full text indexes are now much faster. -@item -Searching on packed (@code{CHAR}/@code{VARCHAR}) keys are now much faster. -@item Added @code{SQL_CALC_FOUND_ROWS} and @code{FOUND_ROWS()}. This makes it possible to know how many rows a query would have returned without a @code{LIMIT} clause. @@ -47505,8 +47560,18 @@ Added @code{IDENTITY} as a synonym for @code{AUTO_INCREMENT} (like Sybase). @item Added @code{ORDER BY} syntax to @code{UPDATE} and @code{DELETE}. @item -Optimized queries of type: -@code{SELECT DISTINCT * from table_name ORDER by key_part1 LIMIT #} +@code{SHOW INDEXES} is now a synonym for @code{SHOW INDEX}. +@item +Added @code{ALTER TABLE table_name DISABLE KEYS} and +@code{ALTER TABLE table_name ENABLE KEYS} commands. +@item +Allow one to use @code{IN} instead of @code{FROM} in @code{SHOW} commands. +@item +Allow ANSI SQL syntax @code{X'hexadecimal-number'} +@item +Cleaned up global lock handling for @code{FLUSH TABLES WITH READ LOCK} +@item +Fixed problem with @code{DATETIME = constant} in @code{WHERE} optimization. @end itemize diff --git a/acinclude.m4 b/acinclude.m4 index d7e492856bb..8a7413b9b08 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -715,6 +715,8 @@ AC_MSG_CHECKING(for OpenSSL) [openssl="$withval"], [openssl=no]) + openssl_libs="" + openssl_includes="" if test "$openssl" = "yes" then if test -n "$vio_dir" @@ -722,14 +724,12 @@ AC_MSG_CHECKING(for OpenSSL) AC_MSG_RESULT(yes) openssl_libs="-L/usr/local/ssl/lib -lssl -lcrypto" openssl_includes="-I/usr/local/ssl/include" + AC_DEFINE(HAVE_OPENSSL) else - AC_MSG_ERROR([OpenSSL requires Virtual IO support (--with-vio)]) + AC_MSG_RESULT("disabled because --with-vio wasn't used") fi - AC_DEFINE(HAVE_OPENSSL) else AC_MSG_RESULT(no) - openssl_libs="" - openssl_includes="" fi NON_THREADED_CLIENT_LIBS="$NON_THREADED_CLIENT_LIBS $openssl_libs" AC_SUBST(openssl_libs) @@ -748,16 +748,15 @@ dnl Call MYSQL_CHECK_ORBIT even if mysqlfs == no, so that @orbit_*@ dnl get substituted. MYSQL_CHECK_ORBIT + fs_dirs="" if test "$mysqlfs" = "yes" then if test -n "$orbit_exec_prefix" then fs_dirs=fs else - AC_MSG_ERROR([mysqlfs requires ORBit, the CORBA ORB]) + AC_MSG_RESULT("disabled because ORBIT, the CORBA ORB, wasn't found"]) fi - else - fs_dirs= fi AC_SUBST([fs_dirs]) ]) diff --git a/configure.in b/configure.in index 14816515e97..df9c6bbec4d 100644 --- a/configure.in +++ b/configure.in @@ -1758,11 +1758,15 @@ AC_ARG_WITH(extra-tools, [with_tools=yes] ) +tools_dirs="" if test "$with_tools" = "yes" then - tools_dirs="tools" -else - tools_dirs="" + if test "$THREAD_SAFE_CLIENT" = "no" + then + echo "Warning: extra-tools disabled because --enable-thread-safe-client wasn't used" + else + tools_dirs="tools" + fi fi AC_SUBST(tools_dirs) diff --git a/include/mysql_com.h b/include/mysql_com.h index 63fbc05b0cb..47908c5f7be 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -104,6 +104,8 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY, struct st_vio; /* Only C */ typedef struct st_vio Vio; +#define MAX_BLOB_WIDTH 8192 // Default width for blob + typedef struct st_net { Vio* vio; my_socket fd; /* For Perl DBI/dbd */ diff --git a/myisammrg/myrg_create.c b/myisammrg/myrg_create.c index 5c6638b6ef2..d1ea018741d 100644 --- a/myisammrg/myrg_create.c +++ b/myisammrg/myrg_create.c @@ -54,7 +54,7 @@ int myrg_create(const char *name, const char **table_names, if (insert_method != MERGE_INSERT_DISABLED) { end=strxmov(buff,"#INSERT_METHOD=", - get_type(&merge_insert_method,insert_method),"\n",NullS); + get_type(&merge_insert_method,insert_method-1),"\n",NullS); if (my_write(file,buff,(uint) (end-buff),MYF(MY_WME | MY_NABP))) goto err; } diff --git a/myisammrg/myrg_static.c b/myisammrg/myrg_static.c index ad57ea847d5..d667c5a5475 100644 --- a/myisammrg/myrg_static.c +++ b/myisammrg/myrg_static.c @@ -26,5 +26,5 @@ LIST *myrg_open_list=0; static const char *merge_insert_methods[] = { "FIRST", "LAST", NullS }; -TYPELIB merge_insert_method= { array_elements(merge_insert_methods),"", +TYPELIB merge_insert_method= { array_elements(merge_insert_methods)-1,"", merge_insert_methods}; diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result index 46ce0fda2c1..a29a9af06da 100644 --- a/mysql-test/r/bigint.result +++ b/mysql-test/r/bigint.result @@ -13,3 +13,19 @@ a 18446744073709551615 a 18446744073709551614 +min(big) max(big) max(big)-1 +-1 9223372036854775807 9223372036854775806 +min(big) max(big) max(big)-1 +-1 9223372036854775807 9223372036854775806 +min(big) max(big) max(big)-1 +12345678901234567 18446744073709551615 18446744073709551614 +min(big) max(big) max(big)-1 +12345678901234567 18446744073709551615 18446744073709551614 +min(big) max(big) max(big)-1 +12345678901234567 18446744073709551615 18446744073709551614 +min(big) max(big) max(big)-1 +12345678901234567 18446744073709551615 18446744073709551614 +min(big) max(big) max(big)-1 +-1 9223372036854775807 9223372036854775806 +min(big) max(big) max(big)-1 +-1 9223372036854775807 9223372036854775806 diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 653e25af799..704b541e25e 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -81,6 +81,56 @@ a 412 412 411 +a b +1 Testing +1 Testing +2 table +2 table +4 Testing +4 Testing +5 table +5 table +6 t2 +6 t1 +7 Testing +7 Testing +8 table +8 table +9 t2 +9 t2 +a b +1 Testing +1 Testing +2 table +2 table +4 Testing +4 Testing +5 table +5 table +9 t2 +9 t2 +a b +1 Testing +1 Testing +2 table +2 table +3 t2 +3 t2 +4 Testing +4 Testing +5 table +5 table +a b +1 Testing +1 Testing +2 table +2 table +3 t2 +3 t2 +4 Testing +4 Testing +5 table +5 table Table Create Table t3 CREATE TABLE `t3` ( `a` int(11) NOT NULL default '0', @@ -130,3 +180,155 @@ a a b 1 1 1 2 +Table Create Table +t3 CREATE TABLE `t3` ( + `a` int(11) NOT NULL default '0', + `b` int(11) NOT NULL default '0', + KEY `a` (`a`,`b`) +) TYPE=MyISAM +Table Create Table +t4 CREATE TABLE `t4` ( + `a` int(11) NOT NULL default '0', + `b` int(11) NOT NULL default '0', + KEY `a` (`a`,`b`) +) TYPE=MRG_MyISAM UNION=(t1,t2) +Table Create Table +t5 CREATE TABLE `t5` ( + `a` int(11) NOT NULL default '0', + `b` int(11) NOT NULL default '0', + KEY `a` (`a`,`b`) +) TYPE=MRG_MyISAM INSERT_METHOD=FIRST UNION=(t1,t2) +Table Create Table +t6 CREATE TABLE `t6` ( + `a` int(11) NOT NULL default '0', + `b` int(11) NOT NULL default '0', + KEY `a` (`a`,`b`) +) TYPE=MRG_MyISAM INSERT_METHOD=LAST UNION=(t1,t2) +a b +a b +1 1 +2 1 +1 2 +a b +2 2 +1 3 +2 3 +a b +1 4 +2 4 +a b +1 1 +1 2 +1 3 +1 4 +5 1 +5 2 +a b +2 1 +2 2 +2 3 +2 4 +6 1 +6 2 +a b +1 1 +1 2 +1 3 +1 4 +2 1 +2 2 +2 3 +2 4 +5 1 +5 2 +6 1 +6 2 +a b +3 1 +3 2 +3 3 +3 4 +Table Create Table +t4 CREATE TABLE `t4` ( + `a` int(11) NOT NULL default '0', + `b` int(11) NOT NULL default '0', + KEY `a` (`a`,`b`) +) TYPE=MRG_MyISAM UNION=(t1,t2,t3) +a b +1 1 +1 2 +1 3 +1 4 +2 1 +2 2 +2 3 +2 4 +3 1 +3 2 +3 3 +3 4 +5 1 +5 2 +6 1 +6 2 +Table Create Table +t4 CREATE TABLE `t4` ( + `a` int(11) NOT NULL default '0', + `b` int(11) NOT NULL default '0', + KEY `a` (`a`,`b`) +) TYPE=MRG_MyISAM INSERT_METHOD=FIRST UNION=(t1,t2,t3) +a b +1 1 +1 2 +1 3 +1 4 +4 1 +4 2 +5 1 +5 2 +a b +2 1 +2 2 +2 3 +2 4 +6 1 +6 2 +a b +3 1 +3 2 +3 3 +3 4 +a b +1 1 +1 2 +1 3 +1 4 +2 1 +2 2 +2 3 +2 4 +3 1 +3 2 +3 3 +3 4 +4 1 +4 2 +5 1 +5 2 +6 1 +6 2 +a b +1 1 +1 2 +1 3 +1 4 +2 1 +2 2 +2 3 +2 4 +4 1 +4 2 +5 1 +5 2 +6 1 +6 2 diff --git a/mysql-test/r/type_ranges.result b/mysql-test/r/type_ranges.result index abb8ef8cb09..96643cc8710 100644 --- a/mysql-test/r/type_ranges.result +++ b/mysql-test/r/type_ranges.result @@ -131,7 +131,7 @@ auto auto auto auto 16 16 Field Type Null Key Default Extra Privileges -auto bigint(17) PRI 0 select,insert,update,references +auto bigint(17) unsigned PRI 0 select,insert,update,references t1 bigint(1) 0 select,insert,update,references t2 char(1) select,insert,update,references t3 mediumtext select,insert,update,references diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test index 6470b6f6a30..52ae9ad35db 100644 --- a/mysql-test/t/bigint.test +++ b/mysql-test/t/bigint.test @@ -14,3 +14,18 @@ select * from t1 where a='18446744073709551615'; delete from t1 where a=18446744073709551615; select * from t1; drop table t1; + +create table t1 ( a int not null default 1, big bigint ); +insert into t1 (big) values (-1),(12345678901234567),(9223372036854775807),(18446744073709551615); +select min(big),max(big),max(big)-1 from t1; +select min(big),max(big),max(big)-1 from t1 group by a; +alter table t1 modify big bigint unsigned not null; +select min(big),max(big),max(big)-1 from t1; +select min(big),max(big),max(big)-1 from t1 group by a; +alter table t1 add key (big); +select min(big),max(big),max(big)-1 from t1; +select min(big),max(big),max(big)-1 from t1 group by a; +alter table t1 modify big bigint not null; +select min(big),max(big),max(big)-1 from t1; +select min(big),max(big),max(big)-1 from t1 group by a; +drop table t1; diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index 188f699cd64..5bd78769a05 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -2,7 +2,7 @@ # test of MERGE TABLES # -drop table if exists t1,t2,t3; +drop table if exists t1,t2,t3,t4,t5,t6; create table t1 (a int not null primary key auto_increment, message char(20)); create table t2 (a int not null primary key auto_increment, message char(20)); INSERT INTO t1 (message) VALUES ("Testing"),("table"),("t1"); @@ -31,6 +31,14 @@ select * from t3 where a > 10 and a < 20; explain select a from t3 order by a desc limit 10; select a from t3 order by a desc limit 10; select a from t3 order by a desc limit 300,10; +delete from t3 where a=3; +select * from t3 where a < 10; +delete from t3 where a >= 6 and a <= 8; +select * from t3 where a < 10; +update t3 set a=3 where a=9; +select * from t3 where a < 10; +update t3 set a=6 where a=7; +select * from t3 where a < 10; show create table t3; # The following should give errors @@ -114,3 +122,49 @@ insert into t2 values (1,1),(2,2),(0,0),(4,4),(5,5),(6,6); flush tables; select * from t3 where a=1 order by b limit 2; drop table t3,t1,t2; + +# +# [phi] testing INSERT_METHOD stuff +# + +drop table if exists t6, t5, t4, t3, t2, t1; +# first testing of common stuff with new parameters +create table t1 (a int not null, b int not null, key(a,b)); +create table t2 (a int not null, b int not null, key(a,b)); +create table t3 (a int not null, b int not null, key(a,b)) UNION=(t1,t2) INSERT_METHOD=NO; +create table t4 (a int not null, b int not null, key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=NO; +create table t5 (a int not null, b int not null, key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=FIRST; +create table t6 (a int not null, b int not null, key(a,b)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST; +show create table t3; +show create table t4; +show create table t5; +show create table t6; +insert into t1 values (1,1),(1,2),(1,3),(1,4); +insert into t2 values (2,1),(2,2),(2,3),(2,4); +select * from t3 order by b,a limit 3; +select * from t4 order by b,a limit 3; +select * from t5 order by b,a limit 3,3; +select * from t6 order by b,a limit 6,3; +# now testing inserts and where the data gets written +insert into t5 values (5,1),(5,2); +insert into t6 values (6,1),(6,2); +select * from t1 order by a,b; +select * from t2 order by a,b; +select * from t4 order by a,b; +# preperation for next test +insert into t3 values (3,1),(3,2),(3,3),(3,4); +select * from t3 order by a,b; +# now testing whether options are kept by alter table +alter table t4 UNION=(t1,t2,t3); +show create table t4; +select * from t4 order by a,b; +# testing switching off insert method and inserts again +alter table t4 INSERT_METHOD=FIRST; +show create table t4; +insert into t4 values (4,1),(4,2); +select * from t1 order by a,b; +select * from t2 order by a,b; +select * from t3 order by a,b; +select * from t4 order by a,b; +select * from t5 order by a,b; +drop table if exists t6, t5, t4, t3, t2, t1; diff --git a/mysys/typelib.c b/mysys/typelib.c index b18959442ae..f4b638e047e 100644 --- a/mysys/typelib.c +++ b/mysys/typelib.c @@ -84,7 +84,8 @@ int find_type(my_string x, TYPELIB *typelib, uint full_name) /* Get name of type nr 'nr' */ /* Warning first type is 1, 0 = empty field */ -void make_type(register my_string to, register uint nr, register TYPELIB *typelib) +void make_type(register my_string to, register uint nr, + register TYPELIB *typelib) { DBUG_ENTER("make_type"); if (!nr) diff --git a/sql/field.h b/sql/field.h index b9d8e1957c9..8f60b7e008b 100644 --- a/sql/field.h +++ b/sql/field.h @@ -415,10 +415,11 @@ public: unireg_check_arg, field_name_arg, table_arg, 0, zero_arg,unsigned_arg) {} - Field_longlong(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg) + Field_longlong(uint32 len_arg,bool maybe_null_arg, + const char *field_name_arg, + struct st_table *table_arg, bool unsigned_arg) :Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg,0,0,0) + NONE, field_name_arg, table_arg,0,0,unsigned_arg) {} enum Item_result result_type () const { return INT_RESULT; } enum_field_types type() const { return FIELD_TYPE_LONGLONG;} diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index e9cd3f57122..b10939227ff 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -90,7 +90,7 @@ const char *berkeley_lock_names[] = { "DEFAULT", "OLDEST","RANDOM","YOUNGEST",0 }; u_int32_t berkeley_lock_types[]= { DB_LOCK_DEFAULT, DB_LOCK_OLDEST, DB_LOCK_RANDOM }; -TYPELIB berkeley_lock_typelib= {array_elements(berkeley_lock_names),"", +TYPELIB berkeley_lock_typelib= {array_elements(berkeley_lock_names)-1,"", berkeley_lock_names}; static void berkeley_print_error(const char *db_errpfx, char *buffer); diff --git a/sql/ha_gemini.cc b/sql/ha_gemini.cc index e8130c55fc7..a60841c3fe6 100644 --- a/sql/ha_gemini.cc +++ b/sql/ha_gemini.cc @@ -68,7 +68,7 @@ ulong gemini_recovery_options = GEMINI_RECOVERY_FULL; /* bits in gemini_recovery_options */ const char *gemini_recovery_names[] = { "FULL", "NONE", "FORCE" }; -TYPELIB gemini_recovery_typelib= {array_elements(gemini_recovery_names),"", +TYPELIB gemini_recovery_typelib= {array_elements(gemini_recovery_names)-1,"", gemini_recovery_names}; const int start_of_name = 2; /* Name passed as .// diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 812e0b77077..36d06022d58 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -36,7 +36,7 @@ ulong myisam_recover_options= HA_RECOVER_NONE; /* bits in myisam_recover_options */ const char *myisam_recover_names[] = { "DEFAULT", "BACKUP", "FORCE", "QUICK", NullS}; -TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names),"", +TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"", myisam_recover_names}; diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 92c1372a7a1..88ae8d22f73 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -187,6 +187,11 @@ void ha_myisammrg::info(uint flag) int ha_myisammrg::extra(enum ha_extra_function operation) { + /* As this is just a mapping, we don't have to force the underlying + tables to be closed */ + if (operation == HA_EXTRA_FORCE_REOPEN || + operation == HA_EXTRA_PREPARE_FOR_DELETE) + return 0; return myrg_extra(file,operation); } @@ -285,8 +290,7 @@ void ha_myisammrg::append_create_info(String *packet) if (file->merge_insert_method != MERGE_INSERT_DISABLED) { packet->append(" INSERT_METHOD=",15); - const char *tmp = get_type(&merge_insert_method,file->merge_insert_method); - packet->append(tmp); + packet->append(get_type(&merge_insert_method,file->merge_insert_method-1)); } packet->append(" UNION=(",8); MYRG_TABLE *table,*first; diff --git a/sql/item.cc b/sql/item.cc index dbb9c4ec38d..5eae3a9b542 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -37,7 +37,7 @@ void item_init(void) Item::Item() { marker=0; - binary=maybe_null=null_value=with_sum_func=0; + binary=maybe_null=null_value=with_sum_func=unsigned_flag=0; name=0; decimals=0; max_length=0; next=current_thd->free_list; // Put in free list @@ -116,6 +116,7 @@ void Item_field::set_field(Field *field_par) table_name=field_par->table_name; field_name=field_par->field_name; binary=field_par->binary(); + unsigned_flag=test(field_par->flags & UNSIGNED_FLAG); } const char *Item_ident::full_name() const @@ -326,6 +327,8 @@ void Item::init_make_field(Send_field *tmp_field, tmp_field->type=field_type; tmp_field->length=max_length; tmp_field->decimals=decimals; + if (unsigned_flag) + tmp_field->flags |= UNSIGNED_FLAG; } /* ARGSUSED */ @@ -345,6 +348,7 @@ void Item_uint::make_field(Send_field *tmp_field) { init_make_field(tmp_field,FIELD_TYPE_LONGLONG); tmp_field->flags|= UNSIGNED_FLAG; + unsigned_flag=1; } void Item_real::make_field(Send_field *tmp_field) diff --git a/sql/item.h b/sql/item.h index 98abdc834d9..9ab41af3398 100644 --- a/sql/item.h +++ b/sql/item.h @@ -43,6 +43,7 @@ public: my_bool maybe_null; /* If item may be null */ my_bool null_value; /* if item is null */ my_bool binary; + my_bool unsigned_flag; my_bool with_sum_func; diff --git a/sql/item_func.cc b/sql/item_func.cc index 3ef5ed5d7a3..a4d0e1a7ed1 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -184,8 +184,10 @@ String *Item_num_func::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; /* purecov: inspected */ - else + else if (!unsigned_flag) str->set(nr); + else + str->set((ulonglong) nr); } else { @@ -213,18 +215,26 @@ String *Item_int_func::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; - else + else if (!unsigned_flag) str->set(nr); + else + str->set((ulonglong) nr); return str; } -/* Change from REAL_RESULT (default) to INT_RESULT if both arguments are integers */ +/* + Change from REAL_RESULT (default) to INT_RESULT if both arguments are + integers +*/ void Item_num_op::find_num_type(void) { if (args[0]->result_type() == INT_RESULT && args[1]->result_type() == INT_RESULT) + { hybrid_type=INT_RESULT; + unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag; + } } String *Item_num_op::val_str(String *str) @@ -234,8 +244,10 @@ String *Item_num_op::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; /* purecov: inspected */ - else + else if (!unsigned_flag) str->set(nr); + else + str->set((ulonglong) nr); } else { @@ -667,8 +679,10 @@ String *Item_func_min_max::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; - else + else if (!unsigned_flag) str->set(nr); + else + str->set((ulonglong) nr); return str; } case REAL_RESULT: @@ -1306,8 +1320,10 @@ String *Item_func_udf_int::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; - else + else if (!unsigned_flag) str->set(nr); + else + str->set((ulonglong) nr); return str; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 12561fe4326..355f28d5432 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -17,7 +17,7 @@ /* This file defines all string functions ** Warning: Some string functions doesn't always put and end-null on a String -** (This shouldn't be neaded) +** (This shouldn't be needed) */ #ifdef __GNUC__ @@ -384,7 +384,7 @@ void Item_func_reverse::fix_length_and_dec() /* ** Replace all occurences of string2 in string1 with string3. -** Don't reallocate val_str() if not neaded +** Don't reallocate val_str() if not needed */ /* TODO: Fix that this works with binary strings when using USE_MB */ diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 812fc636fef..712c0fa308e 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -52,6 +52,8 @@ void Item_sum::make_field(Send_field *tmp_field) tmp_field->flags=0; if (!maybe_null) tmp_field->flags|= NOT_NULL_FLAG; + if (unsigned_flag) + tmp_field->flags |= UNSIGNED_FLAG; tmp_field->length=max_length; tmp_field->decimals=decimals; tmp_field->type=(result_type() == INT_RESULT ? FIELD_TYPE_LONG : @@ -150,7 +152,7 @@ Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables) return 1; hybrid_type=item->result_type(); if (hybrid_type == INT_RESULT) - max_length=21; + max_length=20; else if (hybrid_type == REAL_RESULT) max_length=float_length(decimals); else @@ -158,6 +160,7 @@ Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables) decimals=item->decimals; maybe_null=item->maybe_null; binary=item->binary; + unsigned_flag=item->unsigned_flag; result_field=0; null_value=1; fix_length_and_dec(); @@ -323,12 +326,27 @@ double Item_sum_hybrid::val() { if (null_value) return 0.0; - if (hybrid_type == STRING_RESULT) - { + switch (hybrid_type) { + case STRING_RESULT: String *res; res=val_str(&str_value); return res ? atof(res->c_ptr()) : 0.0; + case INT_RESULT: + if (unsigned_flag) + return ulonglong2double(sum_int); + return (double) sum_int; + case REAL_RESULT: + return sum; } - return sum; + return 0; // Keep compiler happy +} + +longlong Item_sum_hybrid::val_int() +{ + if (null_value) + return 0; + if (hybrid_type == INT_RESULT) + return sum_int; + return (longlong) Item_sum_hybrid::val(); } @@ -337,25 +355,26 @@ Item_sum_hybrid::val_str(String *str) { if (null_value) return 0; - if (hybrid_type == STRING_RESULT) + switch (hybrid_type) { + case STRING_RESULT: return &value; - str->set(sum,decimals); - return str; + case REAL_RESULT: + str->set(sum,decimals); + break; + case INT_RESULT: + if (unsigned_flag) + str->set((ulonglong) sum_int); + else + str->set((longlong) sum_int); + break; + } + return str; // Keep compiler happy } - bool Item_sum_min::add() { - if (hybrid_type != STRING_RESULT) - { - double nr=args[0]->val(); - if (!args[0]->null_value && (null_value || nr < sum)) - { - sum=nr; - null_value=0; - } - } - else + switch (hybrid_type) { + case STRING_RESULT: { String *result=args[0]->val_str(&tmp_value); if (!args[0]->null_value && @@ -366,22 +385,39 @@ bool Item_sum_min::add() null_value=0; } } + break; + case INT_RESULT: + { + longlong nr=args[0]->val_int(); + if (!args[0]->null_value && (null_value || + (unsigned_flag && + (ulonglong) nr < (ulonglong) sum_int) || + (!unsigned_flag && nr < sum_int))) + { + sum_int=nr; + null_value=0; + } + } + break; + case REAL_RESULT: + { + double nr=args[0]->val(); + if (!args[0]->null_value && (null_value || nr < sum)) + { + sum=nr; + null_value=0; + } + } + break; + } return 0; } bool Item_sum_max::add() { - if (hybrid_type != STRING_RESULT) - { - double nr=args[0]->val(); - if (!args[0]->null_value && (null_value || nr > sum)) - { - sum=nr; - null_value=0; - } - } - else + switch (hybrid_type) { + case STRING_RESULT: { String *result=args[0]->val_str(&tmp_value); if (!args[0]->null_value && @@ -392,6 +428,31 @@ bool Item_sum_max::add() null_value=0; } } + break; + case INT_RESULT: + { + longlong nr=args[0]->val_int(); + if (!args[0]->null_value && (null_value || + (unsigned_flag && + (ulonglong) nr > (ulonglong) sum_int) || + (!unsigned_flag && nr > sum_int))) + { + sum_int=nr; + null_value=0; + } + } + break; + case REAL_RESULT: + { + double nr=args[0]->val(); + if (!args[0]->null_value && (null_value || nr > sum)) + { + sum=nr; + null_value=0; + } + } + break; + } return 0; } @@ -676,9 +737,17 @@ Item_sum_hybrid::min_max_update_int_field(int offset) nr=args[0]->val_int(); if (!args[0]->null_value) { - if (result_field->is_null(offset) || - (cmp_sign > 0 ? old_nr > nr : old_nr < nr)) + if (result_field->is_null(offset)) old_nr=nr; + else + { + bool res=(unsigned_flag ? + (ulonglong) old_nr > (ulonglong) nr : + old_nr > nr); + /* (cmp_sign > 0 && res) || (!(cmp_sign > 0) && !res) */ + if (cmp_sign > 0 ^ !res) + old_nr=nr; + } result_field->set_notnull(); } else if (result_field->is_null(offset)) @@ -1079,7 +1148,7 @@ void Item_udf_sum::reset() bool Item_udf_sum::add() { - DBUG_ENTER("Item_udf_sum::reset"); + DBUG_ENTER("Item_udf_sum::add"); udf.add(&null_value); DBUG_RETURN(0); } diff --git a/sql/item_sum.h b/sql/item_sum.h index 7356eeda28c..18b0c3ff577 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -271,6 +271,7 @@ class Item_sum_hybrid :public Item_sum protected: String value,tmp_value; double sum; + longlong sum_int; Item_result hybrid_type; int cmp_sign; table_map used_table_cache; @@ -286,12 +287,13 @@ class Item_sum_hybrid :public Item_sum void reset() { sum=0.0; + sum_int=0; value.length(0); null_value=1; add(); } double val(); - longlong val_int() { return (longlong) val(); } /* Real as default */ + longlong val_int(); void reset_field(); String *val_str(String *); void make_const() { used_table_cache=0; } diff --git a/sql/mf_iocache.cc b/sql/mf_iocache.cc index 24af439961e..40b98983291 100644 --- a/sql/mf_iocache.cc +++ b/sql/mf_iocache.cc @@ -81,7 +81,7 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize, if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1) { cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1; - use_async_io=0; /* No nead to use async */ + use_async_io=0; /* No need to use async */ } } } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 34fae62ad56..7a32a253d6c 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -71,7 +71,6 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); #define HASH_PASSWORD_LENGTH 16 #define HOST_CACHE_SIZE 128 #define MAX_ACCEPT_RETRY 10 // Test accept this many times -#define MAX_BLOB_WIDTH 8192 // Default width for blob #define MAX_FIELDS_BEFORE_HASH 32 #define USER_VARS_HASH_SIZE 16 #define STACK_MIN_SIZE 8192 // Abort if less stack during eval. diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 67b5ba882d2..5b25b1fe660 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -342,7 +342,7 @@ ulong opt_sql_mode = 0L; const char *sql_mode_names[] = { "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", "SERIALIZE","ONLY_FULL_GROUP_BY", NullS }; -TYPELIB sql_mode_typelib= {array_elements(sql_mode_names),"", +TYPELIB sql_mode_typelib= {array_elements(sql_mode_names)-1,"", sql_mode_names}; MY_BITMAP temp_pool; @@ -1738,7 +1738,7 @@ int main(int argc, char **argv) pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM); #if defined( SET_RLIMIT_NOFILE) || defined( OS2) - /* connections and databases neads lots of files */ + /* connections and databases needs lots of files */ { uint wanted_files=10+(uint) max(max_connections*5, max_connections+table_cache_size*2); @@ -1906,7 +1906,7 @@ The server will not act as a slave."); (void) pthread_kill(signal_thread,MYSQL_KILL_SIGNAL); #ifndef __WIN__ if (!opt_bootstrap) - (void) my_delete(pidfile_name,MYF(MY_WME)); // Not neaded anymore + (void) my_delete(pidfile_name,MYF(MY_WME)); // Not needed anymore #endif exit(1); } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 0831634a9a6..cc659623f1d 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -607,7 +607,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, if (limit < records) read_time=(double) records+scan_time+1; // Force to use index else if (read_time <= 2.0 && !force_quick_range) - DBUG_RETURN(0); /* No nead for quick select */ + DBUG_RETURN(0); /* No need for quick select */ DBUG_PRINT("info",("Time to scan table: %ld",(long) read_time)); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 89910d3745e..4c012804c3e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -15,7 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* Basic functions neaded by many modules */ +/* Basic functions needed by many modules */ #include "mysql_priv.h" #include "sql_acl.h" @@ -165,14 +165,15 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild) open_list=0; // Out of memory break; } - (*start_list)->table=(strmov((*start_list)->db=(char*) ((*start_list)+1), - entry->table_cache_key)+1, - entry->real_name); + strmov((*start_list)->table= + strmov(((*start_list)->db= (char*) ((*start_list)+1)), + entry->table_cache_key)+1, + entry->real_name); (*start_list)->in_use= entry->in_use ? 1 : 0; (*start_list)->locked= entry->locked_by_name ? 1 : 0; start_list= &(*start_list)->next; + *start_list=0; } - *start_list=0; VOID(pthread_mutex_unlock(&LOCK_open)); DBUG_RETURN(open_list); } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 1d2805d8e90..54c3e91bcc3 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -391,7 +391,7 @@ int write_record(TABLE *table,COPY_INFO *info) } else { - if (table->file->extra(HA_EXTRA_FLUSH_CACHE)) /* Not neaded with NISAM */ + if (table->file->extra(HA_EXTRA_FLUSH_CACHE)) /* Not needed with NISAM */ { error=my_errno; goto err; @@ -534,7 +534,7 @@ public: } ~delayed_insert() { - /* The following is not really neaded, but just for safety */ + /* The following is not really needed, but just for safety */ delayed_row *row; while ((row=rows.get())) delete row; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ff404cce0d6..ec147c38e9b 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -22,7 +22,7 @@ class Table_ident; class sql_exchange; class LEX_COLUMN; -// The following hack is neaded because mysql_yacc.cc does not define +// The following hack is needed because mysql_yacc.cc does not define // YYSTYPE before including this file #ifdef MYSQL_YACC diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c6e23eb927a..929891da889 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -855,7 +855,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, DBUG_PRINT("info",("query ready")); break; } - case COM_FIELD_LIST: // This isn't actually neaded + case COM_FIELD_LIST: // This isn't actually needed #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ break; @@ -2390,7 +2390,7 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, int *yystacksize) /**************************************************************************** - Initialize global thd variables neaded for query + Initialize global thd variables needed for query ****************************************************************************/ static void diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3aa534222e7..c122ba51a96 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3306,7 +3306,7 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type, item->name,table,item_sum->decimals); case INT_RESULT: return new Field_longlong(item_sum->max_length,maybe_null, - item->name,table); + item->name,table,item->unsigned_flag); case STRING_RESULT: if (item_sum->max_length > 255) return new Field_blob(item_sum->max_length,maybe_null, @@ -3357,7 +3357,7 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type, break; case INT_RESULT: new_field=new Field_longlong(item->max_length,maybe_null, - item->name,table); + item->name,table, item->unsigned_flag); break; case STRING_RESULT: if (item->max_length > 255) diff --git a/sql/structs.h b/sql/structs.h index 12ba5004a2e..469d3feea08 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -170,7 +170,7 @@ typedef struct st_lex_user { /* Bits in form->status */ #define STATUS_NO_RECORD (1+2) /* Record isn't usably */ #define STATUS_GARBAGE 1 -#define STATUS_NOT_FOUND 2 /* No record in database when neaded */ +#define STATUS_NOT_FOUND 2 /* No record in database when needed */ #define STATUS_NO_PARENT 4 /* Parent record wasn't found */ #define STATUS_NOT_READ 8 /* Record isn't read */ #define STATUS_UPDATED 16 /* Record is updated by formula */ diff --git a/sql/time.cc b/sql/time.cc index d1e0aee0fa4..440cba457f4 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -24,7 +24,7 @@ static ulong const days_at_timestart=719528; /* daynr at 1970.01.01 */ uchar *days_in_month= (uchar*) "\037\034\037\036\037\036\037\037\036\037\036\037"; - /* Init some variabels neaded when using my_local_time */ + /* Init some variabels needed when using my_local_time */ /* Currently only my_time_zone is inited */ static long my_time_zone=0; diff --git a/sql/unireg.cc b/sql/unireg.cc index c5bfbbbea88..b0dd3471a64 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -20,7 +20,7 @@ struct. In the following functions FIELD * is an ordinary field-structure with the following exeptions: - sc_length,typepos,row,kol,dtype,regnr and field nead not to be set. + sc_length,typepos,row,kol,dtype,regnr and field need not to be set. str is a (long) to record position where 0 is the first position. */ @@ -391,8 +391,8 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, int2store(forminfo+272,int_parts); int2store(forminfo+274,int_length); int2store(forminfo+276,time_stamp_pos); - int2store(forminfo+278,80); /* Columns neaded */ - int2store(forminfo+280,22); /* Rows neaded */ + int2store(forminfo+278,80); /* Columns needed */ + int2store(forminfo+280,22); /* Rows needed */ int2store(forminfo+282,null_fields); DBUG_RETURN(0); } /* pack_header */ From a4bc23add63c1eb20e6bb6cd65fa761b2ec2c19b Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Thu, 27 Sep 2001 22:02:37 +0300 Subject: [PATCH 14/15] Fixed bug in counting open files when using many files Fixed bug in JOIN --- Docs/manual.texi | 3 +++ mysql-test/r/join.result | 2 ++ mysql-test/r/null_key.result | 2 +- mysql-test/t/join.test | 23 +++++++++++++++++++++++ mysys/my_open.c | 5 ++--- sql/sql_select.cc | 24 ++++++++++++++---------- 6 files changed, 45 insertions(+), 14 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 6dd44a79288..050fd76ab47 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -46853,6 +46853,9 @@ not yet 100% confident in this code. @appendixsubsec Changes in release 3.23.43 @itemize @bullet @item +Fixed unlikely bug, which returned not matching rows, in SELECT with +many tables and multi-column indexes and 'range' type. +@item Fixed a unlikely core-dump bug when doing @code{EXPLAIN SELECT} when using many tables and @code{ORDER BY}. @item diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index 3c5a72edc68..7db456a1af5 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -20,3 +20,5 @@ id catid stateid countyid a 1 2 +a a b +2 2 3 diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result index ead1dc29326..d0d59cdebf8 100644 --- a/mysql-test/r/null_key.result +++ b/mysql-test/r/null_key.result @@ -11,7 +11,7 @@ t1 index NULL a 9 NULL 12 where used; Using index table type possible_keys key key_len ref rows Extra t1 range a,b a 9 NULL 3 where used; Using index table type possible_keys key key_len ref rows Extra -t1 ref a,b b 4 const 2 where used +t1 range a,b a 9 NULL 2 where used; Using index table type possible_keys key key_len ref rows Extra t1 ref a,b a 5 const 3 where used; Using index table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test index 6fff628ccb9..224db1dd8f0 100644 --- a/mysql-test/t/join.test +++ b/mysql-test/t/join.test @@ -89,3 +89,26 @@ select t1.a from t1 as t1 left join t1 as t2 using (a) left join t1 as t3 using --error 1116 select t1.a from t1 as t1 left join t1 as t2 using (a) left join t1 as t3 using (a) left join t1 as t4 using (a) left join t1 as t5 using (a) left join t1 as t6 using (a) left join t1 as t7 using (a) left join t1 as t8 using (a) left join t1 as t9 using (a) left join t1 as t10 using (a) left join t1 as t11 using (a) left join t1 as t12 using (a) left join t1 as t13 using (a) left join t1 as t14 using (a) left join t1 as t15 using (a) left join t1 as t16 using (a) left join t1 as t17 using (a) left join t1 as t18 using (a) left join t1 as t19 using (a) left join t1 as t20 using (a) left join t1 as t21 using (a) left join t1 as t22 using (a) left join t1 as t23 using (a) left join t1 as t24 using (a) left join t1 as t25 using (a) left join t1 as t26 using (a) left join t1 as t27 using (a) left join t1 as t28 using (a) left join t1 as t29 using (a) left join t1 as t30 using (a) left join t1 as t31 using (a) left join t1 as t32 using (a) left join t1 as t33 using (a) left join t1 as t34 using (a) left join t1 as t35 using (a) left join t1 as t36 using (a) left join t1 as t37 using (a) left join t1 as t38 using (a) left join t1 as t39 using (a) left join t1 as t40 using (a) left join t1 as t41 using (a) left join t1 as t42 using (a) left join t1 as t43 using (a) left join t1 as t44 using (a) left join t1 as t45 using (a) left join t1 as t46 using (a) left join t1 as t47 using (a) left join t1 as t48 using (a) left join t1 as t49 using (a) left join t1 as t50 using (a) left join t1 as t51 using (a) left join t1 as t52 using (a) left join t1 as t53 using (a) left join t1 as t54 using (a) left join t1 as t55 using (a) left join t1 as t56 using (a) left join t1 as t57 using (a) left join t1 as t58 using (a) left join t1 as t59 using (a) left join t1 as t60 using (a) left join t1 as t61 using (a) left join t1 as t62 using (a) left join t1 as t63 using (a) left join t1 as t64 using (a) left join t1 as t65 using (a); drop table t1; + +# +# Simple join test. This failed in 3.23.42, there should have been +# no matches, still three matches were found. +# + +CREATE TABLE t1 ( + a int(11) NOT NULL, + b int(11) NOT NULL, + PRIMARY KEY (a,b) +) TYPE=MyISAM; + +INSERT INTO t1 VALUES (1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(2,3); + +CREATE TABLE t2 ( + a int(11) default NULL +) TYPE=MyISAM; + +INSERT INTO t2 VALUES (2),(3); + +SELECT t1.a,t2.a,b FROM t1,t2 WHERE t1.a=t2.a AND (t1.a=1 OR t1.a=2) AND b>=1 AND b<=3; + +DROP TABLE t1, t2; diff --git a/mysys/my_open.c b/mysys/my_open.c index 2ed1af1eca1..748113528a1 100644 --- a/mysys/my_open.c +++ b/mysys/my_open.c @@ -75,8 +75,8 @@ int my_close(File fd, myf MyFlags) pthread_mutex_destroy(&my_file_info[fd].mutex); #endif my_file_info[fd].type = UNOPEN; - my_file_opened--; } + my_file_opened--; pthread_mutex_unlock(&THR_LOCK_open); DBUG_RETURN(err); } /* my_close */ @@ -96,9 +96,8 @@ File my_register_filename(File fd, const char *FileName, enum file_type my_error(EE_OUT_OF_FILERESOURCES, MYF(ME_BELL+ME_WAITTANG), FileName, my_errno); return(-1); -#else - thread_safe_increment(my_file_opened,&THR_LOCK_open); #endif + thread_safe_increment(my_file_opened,&THR_LOCK_open); return(fd); /* safeguard */ } pthread_mutex_lock(&THR_LOCK_open); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 56ba4baed30..e97fa3b0abf 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2258,7 +2258,20 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) { JOIN_TAB *tab=join->join_tab+i; table_map current_map= tab->table->map; + bool use_quick_range=0; used_tables|=current_map; + + if (tab->type == JT_REF && tab->quick && + tab->ref.key_length < tab->quick->max_used_key_length) + { + /* Range uses longer key; Use this instead of ref on key */ + tab->type=JT_ALL; + use_quick_range=1; + tab->use_quick=1; + tab->ref.key_parts=0; // Don't use ref key. + join->best_positions[i].records_read=tab->quick->records; + } + COND *tmp=make_cond_for_table(cond,used_tables,current_map); if (!tmp && tab->quick) { // Outer join @@ -2301,7 +2314,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) if (tab->const_keys && tab->table->reginfo.impossible_range) DBUG_RETURN(1); } - else if (tab->type == JT_ALL) + else if (tab->type == JT_ALL && ! use_quick_range) { if (tab->const_keys && tab->table->reginfo.impossible_range) @@ -2356,15 +2369,6 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) } } } - if (tab->type == JT_REF && sel->quick && - tab->ref.key_length < sel->quick->max_used_key_length) - { - /* Range uses longer key; Use this instead of ref on key */ - tab->type=JT_ALL; - tab->use_quick=1; - tab->ref.key_parts=0; // Don't use ref key. - join->best_positions[i].records_read=sel->quick->records; - } } } } From 384ae2eff0f543e775a9ae7b8b4e34cdde8f2347 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Fri, 28 Sep 2001 07:21:24 +0300 Subject: [PATCH 15/15] Fixed that one can always get a name for a compiled characterset --- Docs/manual.texi | 58 ++++++++++++++++++++++++++++++++++++++------- acinclude.m4 | 8 +++++-- include/m_ctype.h | 2 ++ mysys/charset.c | 35 +++++++++++---------------- sql/gen_lex_hash.cc | 2 +- 5 files changed, 72 insertions(+), 33 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index b1815b4eac9..5f1e4480005 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -19777,6 +19777,10 @@ joins that don't use keys properly. @item If @code{Threads_created} is big, you may want to increase the @code{thread_cache_size} variable. +@item +If @code{Created_tmp_disk_tables} is big, you may want to increase the +@code{tmp_table_size} variable to get the temporary tables memory based +instead of disk based. @end itemize @@ -20411,6 +20415,7 @@ Create Table: CREATE TABLE t ( * Character arrays:: The character definition arrays * String collating:: String Collating Support * Multi-byte characters:: Multi-byte Character Support +* Problems with character sets:: @end menu @@ -20744,7 +20749,7 @@ the maximum ratio the strings may grow during @code{my_strxfrm_MYSET} (it must be a positive integer). -@node Multi-byte characters, , String collating, Localization +@node Multi-byte characters, Problems with character sets, String collating, Localization @subsection Multi-byte Character Support @cindex characters, multi-byte @@ -20763,6 +20768,41 @@ You must specify the @code{mbmaxlen_MYSET=N} value in the special comment at the top of the source file. @code{N} should be set to the size in bytes of the largest character in the set. +@node Problems with character sets, , Multi-byte characters, Localization +@subsection Problems With Character Sets + +If you try to use a character set that is not compiled into your binary, +you can run into a couple of different problems: + +@itemize @bullet +@item +Your program has a wrong path to where the character sets are stored. +(Default @file{/usr/local/mysql/share/mysql/charsets}). +This can be fixed by using the @code{--character-sets-dir} +option to the program in question. +@item +The character set is a multi-byte-character set that can't be loaded +dynamicly. In this case you have to recompiled the program with the +support for the character set. +@item +The character set is a dynamic character set, but you don't have a +configure file for it. In this case you should install the configure +file for the character set from a new MySQL distribution. +@item +Your @file{Index} file doesn't contain the name for the character set. + +@example +ERROR 1105: File '/usr/local/share/mysql/charsets/?.conf' not found +(Errcode: 2) +@end example + +In this case you should either get a new @code{Index} file or add +by hand the name of any missing character sets. +@end itemize + +For MyISAM tables, you can check the character set name and number for a +table with @code{myisamchk -dvv table_name}. + @node Server-Side Scripts, Client-Side Scripts, Localization, MySQL Database Administration @section MySQL Server-Side Scripts and Utilities @@ -39313,7 +39353,7 @@ likely it is that we can fix the problem! * C API function overview:: C API Function Overview * C API functions:: C API Function Descriptions * C Thread functions:: C Thread Functions -* C Embedded Server functions:: C Embedded Server Functions +* C Embedded Server functions:: C Embedded Server functions. C Embedded Server Functions * C API problems:: Common questions and problems when using the C API * Building clients:: Building Client Programs * Threaded clients:: How to Make a Threaded Client @@ -42014,9 +42054,9 @@ You need to use the following functions when you want to create a threaded client. @xref{Threaded clients}. @menu -* my_init():: @code{my_init()} -* mysql_thread_init():: @code{mysql_thread_init()} -* mysql_thread_end():: @code{mysql_thread_end()} +* my_init():: @code{my_init()} +* mysql_thread_init():: @code{mysql_thread_init()} +* mysql_thread_end():: @code{mysql_thread_end()} @end menu @node my_init(), mysql_thread_init(), C Thread functions, C Thread functions @@ -42084,8 +42124,8 @@ possible to choose between using the embedded MySQL server and a stand-alone server without modifying any code. @menu -* mysql_server_init():: -* mysql_server_end():: +* mysql_server_init():: +* mysql_server_end():: @end menu @node mysql_server_init(), mysql_server_end(), C Embedded Server functions, C Embedded Server functions @@ -42338,7 +42378,7 @@ For clients that use MySQL header files, you may need to specify a files. -@node Threaded clients, libmysqld , Building clients, C +@node Threaded clients, libmysqld, Building clients, C @subsection How to Make a Threaded Client @cindex clients, threaded @@ -42812,7 +42852,7 @@ clean: rm -f $(targets) $(objects) *.core @end example -@node libmysqld licensing, , libmysqld example, libmysqld +@node libmysqld licensing, , libmysqld example, libmysqld @subsubsection Licensing the Embedded Server The MySQL source code is covered by the GNU GPL license diff --git a/acinclude.m4 b/acinclude.m4 index 8a7413b9b08..260e9b127b9 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -726,7 +726,7 @@ AC_MSG_CHECKING(for OpenSSL) openssl_includes="-I/usr/local/ssl/include" AC_DEFINE(HAVE_OPENSSL) else - AC_MSG_RESULT("disabled because --with-vio wasn't used") + AC_MSG_RESULT(disabled because --with-vio wasn not used) fi else AC_MSG_RESULT(no) @@ -748,15 +748,19 @@ dnl Call MYSQL_CHECK_ORBIT even if mysqlfs == no, so that @orbit_*@ dnl get substituted. MYSQL_CHECK_ORBIT + AC_MSG_CHECKING(if we should build MySQLFS) fs_dirs="" if test "$mysqlfs" = "yes" then if test -n "$orbit_exec_prefix" then fs_dirs=fs + AC_MSG_RESULT([yes]) else - AC_MSG_RESULT("disabled because ORBIT, the CORBA ORB, wasn't found"]) + AC_MSG_RESULT(disabled because ORBIT, the CORBA ORB, was not found) fi + else + AC_MSG_RESULT([no]) fi AC_SUBST([fs_dirs]) ]) diff --git a/include/m_ctype.h b/include/m_ctype.h index b41323e10b9..86a67541d73 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -57,6 +57,8 @@ extern CHARSET_INFO *default_charset_info; extern CHARSET_INFO *find_compiled_charset(uint cs_number); extern CHARSET_INFO *find_compiled_charset_by_name(const char *name); extern CHARSET_INFO compiled_charsets[]; +extern uint compiled_charset_number(const char *name); +extern const char *compiled_charset_name(uint charset_number); #define MY_CHARSET_UNDEFINED 0 #define MY_CHARSET_CURRENT (default_charset_info->number) diff --git a/mysys/charset.c b/mysys/charset.c index f778afb4144..1bbf7e58c77 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -44,13 +44,6 @@ struct simpleconfig_buf_st { char *p; }; -/* Defined in strings/ctype.c */ - -CHARSET_INFO *find_compiled_charset(uint cs_number); -uint compiled_charset_number(const char *name); -const char *compiled_charset_name(uint charset_number); - - static uint num_from_csname(CS_ID **cs, const char *name) { CS_ID **c; @@ -264,22 +257,22 @@ static my_bool read_charset_file(uint cs_number, CHARSET_INFO *set, uint get_charset_number(const char *charset_name) { - my_bool error; - error = init_available_charsets(MYF(0)); /* If it isn't initialized */ - if (error) - return compiled_charset_number(charset_name); - else - return num_from_csname(available_charsets, charset_name); + uint number=compiled_charset_number(charset_name); + if (number) + return number; + if (init_available_charsets(MYF(0))) /* If it isn't initialized */ + return 0; + return num_from_csname(available_charsets, charset_name); } const char *get_charset_name(uint charset_number) { - my_bool error; - error = init_available_charsets(MYF(0)); /* If it isn't initialized */ - if (error) - return compiled_charset_name(charset_number); - else - return name_from_csnum(available_charsets, charset_number); + char *name=compiled_charset_name(charset_number); + if (*name != '?') + return name; + if (init_available_charsets(MYF(0))) /* If it isn't initialized */ + return "?"; + return name_from_csnum(available_charsets, charset_number); } @@ -293,8 +286,8 @@ static CHARSET_INFO *find_charset(CHARSET_INFO **table, uint cs_number, return NULL; } -static CHARSET_INFO *find_charset_by_name(CHARSET_INFO **table, const char *name, - size_t tablesz) +static CHARSET_INFO *find_charset_by_name(CHARSET_INFO **table, + const char *name, size_t tablesz) { uint i; for (i = 0; i < tablesz; ++i) diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 6530e5dd4cf..2358dde7b6d 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -474,7 +474,7 @@ int main(int argc,char **argv) MY_INIT(argv[0]); - start_value=1060872L; best_t1=7930739L; best_t2=4311642L; best_type=3; /* mode=5333 add=6 type: 0 */ + start_value=1109118L; best_t1=6657025L; best_t2=6114496L; best_type=1; /* mode=4903 add=3 type: 0 */ if (get_options(argc,(char **) argv)) exit(1);