From a6c634b328dc46e6bca14382d47a0c06e4c7a51a Mon Sep 17 00:00:00 2001 From: "igor@rurik.mysql.com" <> Date: Tue, 13 May 2003 12:06:34 -0700 Subject: [PATCH 01/12] logging_ok: Logging to logging@openlogging.org accepted mf_keycache.c: Fixed a deadlock when reading from an index file fails. --- BitKeeper/etc/logging_ok | 1 + mysys/mf_keycache.c | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index b6f9647ea49..0a5caaa8858 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -31,6 +31,7 @@ hf@bisonxp.(none) hf@deer.mysql.r18.ru hf@genie.(none) igor@hundin.mysql.fi +igor@rurik.mysql.com jani@dsl-jkl1657.dial.inet.fi jani@dsl-kpogw4gb5.dial.inet.fi jani@hynda.(none) diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 45cbcdb3ab7..264037e9a70 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -826,7 +826,7 @@ restart: (uint) hash_link->file,(ulong) hash_link->diskpos)); } } - KEYCACHE_DBUG_ASSERT(n <= my_hash_links_used); + KEYCACHE_DBUG_ASSERT(cnt <= my_hash_links_used); #endif } if (! hash_link) @@ -1063,6 +1063,9 @@ restart: KEYCACHE_DBUG_ASSERT(page_status != -1); *page_st=page_status; + KEYCACHE_DBUG_PRINT("find_key_block", + ("file %u, filepos %lu, page_status %lu", + (uint) file,(ulong) filepos,(uint) page_status)); #if !defined(DBUG_OFF) && defined(EXTRA_DEBUG) DBUG_EXECUTE("check_keycache2",test_key_cache("end of find_key_block",0);); @@ -1181,7 +1184,7 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length, keycache_pthread_mutex_lock(&THR_LOCK_keycache); my_cache_r_requests++; block=find_key_block(file,filepos,0,&page_st); - if (page_st != PAGE_READ) + if (block->status != BLOCK_ERROR && page_st != PAGE_READ) { /* The requested page is to be read into the block buffer */ read_block(block,key_cache_block_size,read_length+offset, @@ -1303,7 +1306,7 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length, keycache_pthread_mutex_lock(&THR_LOCK_keycache); my_cache_w_requests++; block=find_key_block(file, filepos, 1, &page_st); - if (page_st != PAGE_READ && + if (block->status != BLOCK_ERROR && page_st != PAGE_READ && (offset || read_length < key_cache_block_size)) read_block(block, offset + read_length >= key_cache_block_size? From f547f2769f6419384d2def370d579e1d672dec5e Mon Sep 17 00:00:00 2001 From: "igor@rurik.mysql.com" <> Date: Thu, 12 Jun 2003 04:29:02 -0700 Subject: [PATCH 02/12] Many files: New feature: preload indexes into key cache. mi_preload.c: new file Many files: Added preload statement. --- include/my_base.h | 4 +- include/my_sys.h | 2 + include/myisam.h | 1 + myisam/Makefile.am | 1 + myisam/mi_extra.c | 3 ++ myisam/mi_preload.c | 118 ++++++++++++++++++++++++++++++++++++++++++++ myisam/myisamdef.h | 1 + mysys/mf_keycache.c | 80 ++++++++++++++++++++++++++++++ sql/ha_myisam.cc | 66 +++++++++++++++++++++++++ sql/ha_myisam.h | 1 + sql/handler.cc | 5 ++ sql/handler.h | 1 + sql/lex.h | 2 + sql/mysql_priv.h | 5 ++ sql/mysqld.cc | 6 +++ sql/set_var.cc | 4 ++ sql/sql_base.cc | 6 +-- sql/sql_class.h | 1 + sql/sql_lex.h | 2 +- sql/sql_parse.cc | 10 ++++ sql/sql_table.cc | 23 +++++++++ sql/sql_yacc.yy | 61 +++++++++++++++++++++-- sql/table.h | 1 + 23 files changed, 395 insertions(+), 9 deletions(-) create mode 100644 myisam/mi_preload.c diff --git a/include/my_base.h b/include/my_base.h index b806436fe0e..167c062deb5 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -123,7 +123,8 @@ enum ha_extra_function { HA_EXTRA_NO_IGNORE_DUP_KEY, HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE, /* Cursor will not be used for update */ HA_EXTRA_PREPARE_FOR_DELETE, - HA_EXTRA_PREPARE_FOR_UPDATE /* Remove read cache if problems */ + HA_EXTRA_PREPARE_FOR_UPDATE, /* Remove read cache if problems */ + HA_EXTRA_PRELOAD_BUFFER_SIZE /* Set buffer size for preloading */ }; /* The following is parameter to ha_panic() */ @@ -255,6 +256,7 @@ enum ha_base_keytype { #define HA_ERR_CANNOT_ADD_FOREIGN 150 /* Cannot add a foreign key constr. */ #define HA_ERR_NO_REFERENCED_ROW 151 /* Cannot add a child row */ #define HA_ERR_ROW_IS_REFERENCED 152 /* Cannot delete a parent row */ +#define HA_ERR_NON_UNIQUE_BLOCK_SIZE 153 /* Non unique key block size */ /* Other constants */ diff --git a/include/my_sys.h b/include/my_sys.h index 86ca6ec6a1f..75a7627dc07 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -644,6 +644,8 @@ extern int init_key_cache(ulong use_mem); extern int resize_key_cache(ulong use_mem); extern byte *key_cache_read(File file,my_off_t filepos,byte* buff,uint length, uint block_length,int return_buffer); +extern int key_cache_insert(File file, my_off_t filepos, + byte *buff, uint length); extern int key_cache_write(File file,my_off_t filepos,byte* buff,uint length, uint block_length,int force_write); extern int flush_key_blocks(int file, enum flush_type type); diff --git a/include/myisam.h b/include/myisam.h index 33aa6aa3f31..e85d3057672 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -410,6 +410,7 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, ulonglong key_map, int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows); void mi_flush_bulk_insert(MI_INFO *info, uint inx); void mi_end_bulk_insert(MI_INFO *info); +int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves); #ifdef __cplusplus } diff --git a/myisam/Makefile.am b/myisam/Makefile.am index f8225868d96..d4cd953ac66 100644 --- a/myisam/Makefile.am +++ b/myisam/Makefile.am @@ -47,6 +47,7 @@ libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \ mi_range.c mi_dbug.c mi_checksum.c mi_log.c \ mi_changed.c mi_static.c mi_delete_all.c \ mi_delete_table.c mi_rename.c mi_check.c \ + mi_preload.c \ ft_parser.c ft_stopwords.c ft_static.c \ ft_update.c ft_boolean_search.c ft_nlq_search.c sort.c \ rt_index.c rt_key.c rt_mbr.c rt_split.c sp_key.c diff --git a/myisam/mi_extra.c b/myisam/mi_extra.c index 75057dd4e6a..4b71f3a867b 100644 --- a/myisam/mi_extra.c +++ b/myisam/mi_extra.c @@ -367,6 +367,9 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) if (!share->state.header.uniques) info->opt_flag|= OPT_NO_ROWS; break; + case HA_EXTRA_PRELOAD_BUFFER_SIZE: + info->preload_buff_size= *((ulong *) extra_arg); + break; case HA_EXTRA_KEY_CACHE: case HA_EXTRA_NO_KEY_CACHE: default: diff --git a/myisam/mi_preload.c b/myisam/mi_preload.c new file mode 100644 index 00000000000..be45be66ecf --- /dev/null +++ b/myisam/mi_preload.c @@ -0,0 +1,118 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + Preload indexes into key cache +*/ + +#include "myisamdef.h" + + +/* + Preload pages of the index file for a table into the key cache + + SYNOPSIS + mi_preload() + info open table + map map of indexes to preload into key cache + ignore_leaves only non-leaves pages are to be preloaded + + RETURN VALUE + 0 if a success. error code - otherwise. + + NOTES. + At present pages for all indexes are preloaded. + In future only pages for indexes specified in the key_map parameter + of the table will be preloaded. +*/ + +int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves) +{ + uint i; + uint length; + uint block_length= 0; + uchar *buff= NULL; + MYISAM_SHARE* share= info->s; + uint keys= share->state.header.keys; + MI_KEYDEF *keyinfo= share->keyinfo; + my_off_t key_file_length= share->state.state.key_file_length; + my_off_t pos= share->base.keystart; + + if (!keys || !key_map || key_file_length == pos) + return 0; + + block_length= keyinfo[0].block_length; + + if (!key_map) + return 0; + + /* Check whether all indexes use the same block size */ + for (i= 1 ; i < keys ; i++) + { + if (keyinfo[i].block_length != block_length) + return (my_errno= HA_ERR_NON_UNIQUE_BLOCK_SIZE); + } + + length= info->preload_buff_size/block_length * block_length; + set_if_bigger(length, block_length); + + if (!(buff= (uchar *) my_malloc(length, MYF(MY_WME)))) + return (my_errno= HA_ERR_OUT_OF_MEM); + + if (flush_key_blocks(share->kfile, FLUSH_RELEASE)) + goto err; + + do + { + /* Read the next block of index file into the preload buffer */ + set_if_smaller(length, key_file_length-pos); + if (my_pread(share->kfile, (byte*) buff, length, pos, MYF(MY_FAE))) + goto err; + + if (ignore_leaves) + { + uchar *end= buff+length; + do + { + if (mi_test_if_nod(buff)) + { + if (key_cache_insert(share->kfile, pos, (byte*) buff, block_length)) + goto err; + } + pos+= block_length; + } + while ((buff+= block_length) != end); + buff= end-length; + } + else + { + if (key_cache_insert(share->kfile, pos, (byte*) buff, length)) + goto err; + pos+= length; + } + + } + while (pos != key_file_length); + + my_free(buff, MYF(0)); + + return 0; + +err: + my_free(buff, MYF(MY_ALLOW_ZERO_PTR)); + return (my_errno= errno); +} + diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index 50320f1ecbd..9321a3918e2 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -262,6 +262,7 @@ struct st_myisam_info { int save_lastinx; LIST open_list; IO_CACHE rec_cache; /* When cacheing records */ + uint preload_buff_size; /* When preloading indexes */ myf lock_wait; /* is 0 or MY_DONT_WAIT */ my_bool was_locked; /* Was locked in panic */ my_bool quick_mode; diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 264037e9a70..3276044fc2f 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -1258,6 +1258,86 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length, } +/* + Insert a block of file data from a buffer into key cache + + SYNOPSIS + key_cache_insert() + file file descriptor + filepos file offset of the data from the buffer + buff buffer with data to insert into key cache + length length of the data in the buffer + + RETURN VALUE + 0 if a success, 1 -otherwise. +*/ + +int key_cache_insert(File file, my_off_t filepos, byte *buff, uint length) +{ + DBUG_ENTER("key_cache_insert"); + DBUG_PRINT("enter", ("file %u, filepos %lu, length %u", + (uint) file,(ulong) filepos, length)); + + if (my_disk_blocks > 0) + { + /* Key cache is used */ + reg1 BLOCK_LINK *block; + uint offset= (uint) (filepos & (key_cache_block_size-1)); + uint read_length; + int page_st; + + /* Read data into key cache from buff in key_cache_block_size increments */ + filepos-= offset; + do + { + read_length= length > key_cache_block_size ? + key_cache_block_size : length; + KEYCACHE_DBUG_ASSERT(read_length > 0); + keycache_pthread_mutex_lock(&THR_LOCK_keycache); + my_cache_r_requests++; + block=find_key_block(file, filepos, 0, &page_st); + if (block->status != BLOCK_ERROR && page_st != PAGE_READ) + { + /* The requested page is to be read into the block buffer */ +#if !defined(SERIALIZED_READ_FROM_CACHE) + keycache_pthread_mutex_unlock(&THR_LOCK_keycache); +#endif + + /* Copy data from buff */ + if (!(read_length & 511)) + bmove512(block->buffer+offset, buff, read_length); + else + memcpy(block->buffer+offset, buff, (size_t) read_length); + +#if !defined(SERIALIZED_READ_FROM_CACHE) + keycache_pthread_mutex_lock(&THR_LOCK_keycache); +#endif + block->status= BLOCK_READ; + block->length= read_length+offset; + } + + remove_reader(block); + /* + Link the block into the LRU chain + if it's the last submitted request for the block + */ + unreg_request(block,1); + + keycache_pthread_mutex_unlock(&THR_LOCK_keycache); + + if (block->status & BLOCK_ERROR) + DBUG_RETURN(1); + + buff+=read_length; + filepos+=read_length; + offset=0; + + } while ((length-= read_length)); + } + DBUG_RETURN(0); +} + + /* Write a buffer into disk; filepos must be a multiple of 'block_length', but it doesn't diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 213f5baf388..d9b9f3130de 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -674,6 +674,72 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) } +/* + Preload pages of the index file for a table into the key cache. +*/ + +int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt) +{ + int error; + const char *errmsg; + ulonglong map= ~(ulonglong) 0; + TABLE_LIST *table_list= table->pos_in_table_list; + my_bool ignore_leaves= table_list->ignore_leaves; + + DBUG_ENTER("ha_myisam::preload_keys"); + + /* Check validity of the index references */ + if (table_list->use_index) + { + key_map kmap= get_key_map_from_key_list(table, table_list->use_index); + if (kmap == ~(key_map) 0) + { + errmsg= thd->net.last_error; + error= HA_ADMIN_FAILED; + goto err; + } + if (kmap) + map= kmap; + } + + mi_extra(file, HA_EXTRA_PRELOAD_BUFFER_SIZE, + (void *) &thd->variables.preload_buff_size); + + if ((error= mi_preload(file, map, ignore_leaves))) + { + switch (error) { + case HA_ERR_NON_UNIQUE_BLOCK_SIZE: + errmsg= "Indexes use different block sizes"; + break; + case HA_ERR_OUT_OF_MEM: + errmsg= "Failed to allocate buffer"; + break; + default: + char buf[ERRMSGSIZE+20]; + my_snprintf(buf, ERRMSGSIZE, + "Failed to read from index file (errno: %d)", my_errno); + errmsg= buf; + } + error= HA_ADMIN_FAILED; + goto err; + } + + DBUG_RETURN(HA_ADMIN_OK); + + err: + { + MI_CHECK param; + myisamchk_init(¶m); + param.thd= thd; + param.op_name= (char*)"preload_keys"; + param.db_name= table->table_cache_key; + param.table_name= table->table_name; + param.testflag= 0; + mi_check_print_error(¶m, errmsg); + DBUG_RETURN(error); + } +} + /* Deactive all not unique index that can be recreated fast diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h index 154429ecc0d..8486e25556b 100644 --- a/sql/ha_myisam.h +++ b/sql/ha_myisam.h @@ -127,6 +127,7 @@ class ha_myisam: public handler int optimize(THD* thd, HA_CHECK_OPT* check_opt); int restore(THD* thd, HA_CHECK_OPT* check_opt); int backup(THD* thd, HA_CHECK_OPT* check_opt); + int preload_keys(THD* thd, HA_CHECK_OPT* check_opt); #ifdef HAVE_REPLICATION int dump(THD* thd, int fd); int net_read_dump(NET* net); diff --git a/sql/handler.cc b/sql/handler.cc index f2b7dbdf531..e84c9bf3569 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -588,6 +588,11 @@ int handler::analyze(THD* thd, HA_CHECK_OPT* check_opt) return HA_ADMIN_NOT_IMPLEMENTED; } +int handler::preload_keys(THD* thd, HA_CHECK_OPT* check_opt) +{ + return HA_ADMIN_NOT_IMPLEMENTED; +} + /* Read first row (only) from a table This is never called for InnoDB or BDB tables, as these table types diff --git a/sql/handler.h b/sql/handler.h index 8c23a3625e0..a2408ab0fe0 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -304,6 +304,7 @@ public: virtual int optimize(THD* thd,HA_CHECK_OPT* check_opt); virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt); virtual int backup(THD* thd, HA_CHECK_OPT* check_opt); + virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt); /* restore assumes .frm file must exist, and that generate_table() has been called; It will just copy the data file and run repair. diff --git a/sql/lex.h b/sql/lex.h index f85431aadf7..0cbc048e00c 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -221,6 +221,7 @@ static SYMBOL symbols[] = { { "KILL", SYM(KILL_SYM),0,0}, { "LAST", SYM(LAST_SYM),0,0}, { "LEADING", SYM(LEADING),0,0}, + { "LEAVES", SYM(LEAVES),0,0}, { "LEFT", SYM(LEFT),0,0}, { "LEVEL", SYM(LEVEL_SYM),0,0}, { "LIKE", SYM(LIKE),0,0}, @@ -299,6 +300,7 @@ static SYMBOL symbols[] = { { "POLYGON", SYM(POLYGON),0,0}, { "PURGE", SYM(PURGE),0,0}, { "PRECISION", SYM(PRECISION),0,0}, + { "PRELOAD", SYM(PRELOAD),0,0}, { "PREV", SYM(PREV_SYM),0,0}, { "PRIMARY", SYM(PRIMARY_SYM),0,0}, { "PROCEDURE", SYM(PROCEDURE),0,0}, diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index ea6e544a1fd..e0c3f5aeaec 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -246,6 +246,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout); /* Options to add_table_to_list() */ #define TL_OPTION_UPDATING 1 #define TL_OPTION_FORCE_INDEX 2 +#define TL_OPTION_IGNORE_LEAVES 4 /* Some portable defines */ @@ -393,6 +394,8 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* table_list, HA_CHECK_OPT* check_opt); int mysql_optimize_table(THD* thd, TABLE_LIST* table_list, HA_CHECK_OPT* check_opt); +int mysql_preload_keys(THD* thd, TABLE_LIST* table_list); + bool check_simple_select(); SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length); @@ -584,6 +587,8 @@ enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND, extern const Item **not_found_item; Item ** find_item_in_list(Item *item, List &items, uint *counter, find_item_error_report_type report_error); +key_map get_key_map_from_key_list(TABLE *table, + List *index_list); bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, const char *table_name, List_iterator *it); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index f73bd6721f0..7f3c69cb7c9 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3464,6 +3464,7 @@ enum options OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT, OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT, OPT_OPEN_FILES_LIMIT, + OPT_PRELOAD_BUFFER_SIZE, OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_MIN_RES_UNIT, OPT_QUERY_CACHE_SIZE, OPT_QUERY_CACHE_TYPE, OPT_RECORD_BUFFER, OPT_RECORD_RND_BUFFER, OPT_RELAY_LOG_SPACE_LIMIT, OPT_RELAY_LOG_PURGE, @@ -4244,6 +4245,11 @@ Disable with --skip-isam", "If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of files.", (gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 65535, 0, 1, 0}, + {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE, + "The size of the buffer that is allocated when preloading indexes", + (gptr*) &global_system_variables.preload_buff_size, + (gptr*) &max_system_variables.preload_buff_size, 0, GET_ULONG, + REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0}, #ifdef HAVE_QUERY_CACHE {"query_cache_limit", OPT_QUERY_CACHE_LIMIT, "Don't cache results that are bigger than this.", diff --git a/sql/set_var.cc b/sql/set_var.cc index e4adbb0a318..ddaef4c4e14 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -199,6 +199,8 @@ sys_var_thd_ulong sys_net_retry_count("net_retry_count", &SV::net_retry_count, fix_net_retry_count); sys_var_thd_bool sys_new_mode("new", &SV::new_mode); +sys_var_thd_ulong sys_preload_buff_size("preload_buffer_size", + &SV::preload_buff_size); sys_var_thd_ulong sys_read_buff_size("read_buffer_size", &SV::read_buff_size); sys_var_thd_ulong sys_read_rnd_buff_size("read_rnd_buffer_size", @@ -402,6 +404,7 @@ sys_var *sys_variables[]= &sys_net_wait_timeout, &sys_net_write_timeout, &sys_new_mode, + &sys_preload_buff_size, &sys_pseudo_thread_id, &sys_query_cache_size, #ifdef HAVE_QUERY_CACHE @@ -573,6 +576,7 @@ struct show_var_st init_vars[]= { {"log_error", (char*) log_error_file, SHOW_CHAR}, {"port", (char*) &mysql_port, SHOW_INT}, {"protocol_version", (char*) &protocol_version, SHOW_INT}, + {sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS}, {sys_pseudo_thread_id.name, (char*) &sys_pseudo_thread_id, SHOW_SYS}, {sys_read_buff_size.name, (char*) &sys_read_buff_size, SHOW_SYS}, {sys_read_rnd_buff_size.name,(char*) &sys_read_rnd_buff_size, SHOW_SYS}, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index fc95f5deb40..c7db77e1d84 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -35,8 +35,6 @@ static int open_unireg_entry(THD *thd,TABLE *entry,const char *db, const char *name, const char *alias); static void free_cache_entry(TABLE *entry); static void mysql_rm_tmp_tables(void); -static key_map get_key_map_from_key_list(TABLE *table, - List *index_list); extern "C" byte *table_cache_key(const byte *record,uint *length, @@ -2058,8 +2056,8 @@ bool setup_tables(TABLE_LIST *tables) } -static key_map get_key_map_from_key_list(TABLE *table, - List *index_list) +key_map get_key_map_from_key_list(TABLE *table, + List *index_list) { key_map map=0; List_iterator_fast it(*index_list); diff --git a/sql/sql_class.h b/sql/sql_class.h index 925afde2202..996331b071f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -365,6 +365,7 @@ struct system_variables ulong net_retry_count; ulong net_wait_timeout; ulong net_write_timeout; + ulong preload_buff_size; ulong query_cache_type; ulong read_buff_size; ulong read_rnd_buff_size; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index f31b3305e07..04f784e62dc 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -59,7 +59,7 @@ enum enum_sql_command { SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB, SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT, SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION, - SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK, + SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK, SQLCOM_PRELOAD_KEYS, SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE, SQLCOM_ROLLBACK, SQLCOM_COMMIT, SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP, SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1d2449839d8..2596d349a1c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1819,6 +1819,15 @@ mysql_execute_command(THD *thd) res = mysql_restore_table(thd, tables); break; } + case SQLCOM_PRELOAD_KEYS: + { + if (check_db_used(thd, tables) || + check_access(thd, INDEX_ACL, tables->db, &tables->grant.privilege)) + goto error; + res = mysql_preload_keys(thd, tables); + break; + } + #ifndef EMBEDDED_LIBRARY case SQLCOM_CHANGE_MASTER: @@ -3937,6 +3946,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ptr->lock_type= lock_type; ptr->updating= test(table_options & TL_OPTION_UPDATING); ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX); + ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES); ptr->derived= table->sel; if (use_index) ptr->use_index=(List *) thd->memdup((gptr) use_index, diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3cac88d05b2..a73f55077c9 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1331,6 +1331,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, goto err; continue; } + table->table->pos_in_table_list= table; if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify) { char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE]; @@ -1486,6 +1487,28 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) } +/* + Preload specified indexes for a table into key cache + + SYNOPSIS + mysql_preload_keys() + thd Thread object + tables Table list (one table only) + + RETURN VALUES + 0 ok + -1 error +*/ + +int mysql_preload_keys(THD* thd, TABLE_LIST* tables) +{ + DBUG_ENTER("mysql_preload_keys"); + DBUG_RETURN(mysql_admin_table(thd, tables, 0, + "preload_keys", TL_READ, 0, 0, 0, + &handler::preload_keys)); +} + + /* Create a table identical to the specified table diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e3b2c738949..6c120574644 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -256,6 +256,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token KEY_SYM %token LEADING %token LEAST_SYM +%token LEAVES %token LEVEL_SYM %token LEX_HOSTNAME %token LIKE @@ -309,6 +310,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token DUMPFILE %token PACK_KEYS_SYM %token PARTIAL +%token PRELOAD %token PRIMARY_SYM %token PRIVILEGES %token PROCESS @@ -584,7 +586,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); type int_type real_type order_dir opt_field_spec lock_option udf_type if_exists opt_local opt_table_options table_options table_option opt_if_not_exists opt_no_write_to_binlog opt_var_type opt_var_ident_type - delete_option opt_temporary all_or_any opt_distinct + delete_option opt_temporary all_or_any opt_distinct opt_ignore_leafs %type ULONG_NUM raid_types merge_insert_types @@ -613,7 +615,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); key_alg opt_btree_or_rtree %type - key_usage_list + key_usage_list %type key_part @@ -661,10 +663,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %type query verb_clause create change select do drop insert replace insert2 insert_values update delete truncate rename - show describe load alter optimize flush + show describe load alter optimize preload flush reset purge begin commit rollback slave master_def master_defs repair restore backup analyze check start field_list field_list_item field_spec kill column_def key_def + preload_list preload_keys select_item_list select_item values_list no_braces opt_limit_clause delete_limit_clause fields opt_values values procedure_list procedure_list2 procedure_item @@ -733,6 +736,7 @@ verb_clause: | lock | kill | optimize + | preload | purge | rename | repair @@ -1824,6 +1828,55 @@ table_to_table: YYABORT; }; +preload: + PRELOAD + { + LEX *lex=Lex; + lex->sql_command=SQLCOM_PRELOAD_KEYS; + } + preload_list + {} + ; + +preload_list: + preload_keys + | preload_list ',' preload_keys; + +preload_keys: + table_ident preload_keys_spec opt_ignore_leafs + { + LEX *lex=Lex; + SELECT_LEX *sel= &lex->select_lex; + if (!sel->add_table_to_list(lex->thd, $1, NULL, $3, + TL_READ, + sel->get_use_index(), + (List *)0)) + YYABORT; + } + ; + +preload_keys_spec: + keys_or_index { Select->select_lex()->interval_list.empty(); } + preload_key_list_or_empty + { + LEX *lex=Lex; + SELECT_LEX *sel= &lex->select_lex; + sel->use_index= sel->interval_list; + sel->use_index_ptr= &sel->use_index; + } + ; + +preload_key_list_or_empty: + /* empty */ + | '(' key_usage_list2 ')' {} + ; + +opt_ignore_leafs: + /* empty */ + { $$= 0; } + | IGNORE_SYM LEAVES { $$= TL_OPTION_IGNORE_LEAVES; } + ; + /* Select : retrieve data from table */ @@ -4251,6 +4304,7 @@ keyword: | INSERT_METHOD {} | RELAY_THREAD {} | LAST_SYM {} + | LEAVES {} | LEVEL_SYM {} | LINESTRING {} | LOCAL_SYM {} @@ -4294,6 +4348,7 @@ keyword: | PASSWORD {} | POINT_SYM {} | POLYGON {} + | PRELOAD {} | PREV_SYM {} | PROCESS {} | PROCESSLIST_SYM {} diff --git a/sql/table.h b/sql/table.h index 2aefe23cb2f..3132e72fb2f 100644 --- a/sql/table.h +++ b/sql/table.h @@ -181,6 +181,7 @@ typedef struct st_table_list bool straight; /* optimize with prev table */ bool updating; /* for replicate-do/ignore table */ bool force_index; /* Prefer index over table scan */ + bool ignore_leaves; /* Preload only non-leaf nodes */ } TABLE_LIST; typedef struct st_changed_table_list From 1e5dec8cf838510d6409501ca337ca087e3f0a0a Mon Sep 17 00:00:00 2001 From: "igor@rurik.mysql.com" <> Date: Thu, 12 Jun 2003 05:26:50 -0700 Subject: [PATCH 03/12] preload.result, preload.test: new file --- mysql-test/r/preload.result | 214 ++++++++++++++++++++++++++++++++++++ mysql-test/t/preload.test | 101 +++++++++++++++++ 2 files changed, 315 insertions(+) create mode 100644 mysql-test/r/preload.result create mode 100755 mysql-test/t/preload.test diff --git a/mysql-test/r/preload.result b/mysql-test/r/preload.result new file mode 100644 index 00000000000..0afd95b6fb8 --- /dev/null +++ b/mysql-test/r/preload.result @@ -0,0 +1,214 @@ +drop table if exists t1, t2; +create table t1 ( +a int not null auto_increment, +b char(16) not null, +primary key (a), +key (b) +); +create table t2( +a int not null auto_increment, +b char(16) not null, +primary key (a), +key (b) +); +insert into t1(b) values +('test0'), +('test1'), +('test2'), +('test3'), +('test4'), +('test5'), +('test6'), +('test7'); +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; +select count(*) from t1; +count(*) +33448 +select count(*) from t2; +count(*) +20672 +flush tables; +flush status; +show status like "key_%"; +Variable_name Value +Key_blocks_used 918 +Key_read_requests 0 +Key_reads 0 +Key_write_requests 0 +Key_writes 0 +select count(*) from t1 where b = 'test1'; +count(*) +4181 +show status like "key_%"; +Variable_name Value +Key_blocks_used 918 +Key_read_requests 217 +Key_reads 45 +Key_write_requests 0 +Key_writes 0 +select count(*) from t1 where b = 'test1'; +count(*) +4181 +show status like "key_%"; +Variable_name Value +Key_blocks_used 918 +Key_read_requests 434 +Key_reads 45 +Key_write_requests 0 +Key_writes 0 +flush tables; +flush status; +select @@preload_buffer_size; +@@preload_buffer_size +32768 +preload t1 keys; +Table Op Msg_type Msg_text +test.t1 preload_keys status OK +show status like "preload_%"; +Variable_name Value +show status like "key_%"; +Variable_name Value +Key_blocks_used 918 +Key_read_requests 0 +Key_reads 0 +Key_write_requests 0 +Key_writes 0 +select count(*) from t1 where b = 'test1'; +count(*) +4181 +show status like "key_%"; +Variable_name Value +Key_blocks_used 918 +Key_read_requests 217 +Key_reads 45 +Key_write_requests 0 +Key_writes 0 +flush tables; +flush status; +show status like "key_%"; +Variable_name Value +Key_blocks_used 918 +Key_read_requests 0 +Key_reads 0 +Key_write_requests 0 +Key_writes 0 +set session preload_buffer_size=256*1024; +select @@preload_buffer_size; +@@preload_buffer_size +262144 +preload t1 keys ignore leaves; +Table Op Msg_type Msg_text +test.t1 preload_keys status OK +show status like "key_%"; +Variable_name Value +Key_blocks_used 918 +Key_read_requests 0 +Key_reads 0 +Key_write_requests 0 +Key_writes 0 +select count(*) from t1 where b = 'test1'; +count(*) +4181 +show status like "key_%"; +Variable_name Value +Key_blocks_used 918 +Key_read_requests 217 +Key_reads 45 +Key_write_requests 0 +Key_writes 0 +flush tables; +flush status; +show status like "key_%"; +Variable_name Value +Key_blocks_used 918 +Key_read_requests 0 +Key_reads 0 +Key_write_requests 0 +Key_writes 0 +set session preload_buffer_size=1*1024; +select @@preload_buffer_size; +@@preload_buffer_size +1024 +preload t1 keys, t2 keys (primary,b) ignore leaves; +Table Op Msg_type Msg_text +test.t1 preload_keys status OK +test.t2 preload_keys status OK +show status like "key_%"; +Variable_name Value +Key_blocks_used 918 +Key_read_requests 0 +Key_reads 0 +Key_write_requests 0 +Key_writes 0 +select count(*) from t1 where b = 'test1'; +count(*) +4181 +select count(*) from t2 where b = 'test1'; +count(*) +2584 +show status like "key_%"; +Variable_name Value +Key_blocks_used 918 +Key_read_requests 351 +Key_reads 73 +Key_write_requests 0 +Key_writes 0 +flush tables; +flush status; +show status like "key_%"; +Variable_name Value +Key_blocks_used 918 +Key_read_requests 0 +Key_reads 0 +Key_write_requests 0 +Key_writes 0 +preload t3 keys, t2 keys (primary,b) ; +Table Op Msg_type Msg_text +test.t3 preload_keys error Table 'test.t3' doesn't exist +test.t2 preload_keys status OK +show status like "key_%"; +Variable_name Value +Key_blocks_used 918 +Key_read_requests 0 +Key_reads 0 +Key_write_requests 0 +Key_writes 0 +flush tables; +flush status; +show status like "key_%"; +Variable_name Value +Key_blocks_used 918 +Key_read_requests 0 +Key_reads 0 +Key_write_requests 0 +Key_writes 0 +preload t3 keys (b), t2 keys (c) ; +Table Op Msg_type Msg_text +test.t3 preload_keys error Table 'test.t3' doesn't exist +test.t2 preload_keys error Key column 'c' doesn't exist in table +test.t2 preload_keys status Operation failed +show status like "key_%"; +Variable_name Value +Key_blocks_used 918 +Key_read_requests 0 +Key_reads 0 +Key_write_requests 0 +Key_writes 0 +drop table t1, t2; diff --git a/mysql-test/t/preload.test b/mysql-test/t/preload.test new file mode 100755 index 00000000000..1fd0d0a5b17 --- /dev/null +++ b/mysql-test/t/preload.test @@ -0,0 +1,101 @@ +# +# Testing of PRELOAD +# + +--disable_warnings +drop table if exists t1, t2; +--enable_warnings + + +create table t1 ( + a int not null auto_increment, + b char(16) not null, + primary key (a), + key (b) +); + +create table t2( + a int not null auto_increment, + b char(16) not null, + primary key (a), + key (b) +); + +insert into t1(b) values + ('test0'), + ('test1'), + ('test2'), + ('test3'), + ('test4'), + ('test5'), + ('test6'), + ('test7'); + +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; +insert into t2(b) select b from t1; +insert into t1(b) select b from t2; + +select count(*) from t1; +select count(*) from t2; + +flush tables; flush status; +show status like "key_%"; + +select count(*) from t1 where b = 'test1'; +show status like "key_%"; +select count(*) from t1 where b = 'test1'; +show status like "key_%"; + +flush tables; flush status; +select @@preload_buffer_size; +preload t1 keys; +show status like "preload_%"; +show status like "key_%"; +select count(*) from t1 where b = 'test1'; +show status like "key_%"; + +flush tables; flush status; +show status like "key_%"; +set session preload_buffer_size=256*1024; +select @@preload_buffer_size; +preload t1 keys ignore leaves; +show status like "key_%"; +select count(*) from t1 where b = 'test1'; +show status like "key_%"; + +flush tables; flush status; +show status like "key_%"; +set session preload_buffer_size=1*1024; +select @@preload_buffer_size; +preload t1 keys, t2 keys (primary,b) ignore leaves; +show status like "key_%"; +select count(*) from t1 where b = 'test1'; +select count(*) from t2 where b = 'test1'; +show status like "key_%"; + +flush tables; flush status; +show status like "key_%"; +preload t3 keys, t2 keys (primary,b) ; +show status like "key_%"; + +flush tables; flush status; +show status like "key_%"; +preload t3 keys (b), t2 keys (c) ; +show status like "key_%"; + +drop table t1, t2; From 3b7911d36769ba3a822ef2740c24ce8e97f67ec6 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Mon, 16 Jun 2003 10:32:49 +0200 Subject: [PATCH 04/12] - changed "password" to "Password" as suggested by Paul DuBois to be consistent with the other column names in the table. --- scripts/mysql_fix_privilege_tables.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mysql_fix_privilege_tables.sql b/scripts/mysql_fix_privilege_tables.sql index 3466e3cf799..43dc6d89481 100644 --- a/scripts/mysql_fix_privilege_tables.sql +++ b/scripts/mysql_fix_privilege_tables.sql @@ -4,7 +4,7 @@ ALTER TABLE host type=MyISAM; ALTER TABLE func type=MyISAM; ALTER TABLE columns_priv type=MyISAM; ALTER TABLE tables_priv type=MyISAM; -ALTER TABLE user change password password char(45) not null; +ALTER TABLE user change Password Password char(45) not null; ALTER TABLE user add File_priv enum('N','Y') NOT NULL; CREATE TABLE IF NOT EXISTS func ( name char(64) DEFAULT '' NOT NULL, From 242ee84fb9e64a7c1257d6c5467eb5815c84229f Mon Sep 17 00:00:00 2001 From: "serg@sergbook.mylan" <> Date: Wed, 18 Jun 2003 14:12:50 +0200 Subject: [PATCH 05/12] triggers magic enforce REAL_EMAIL --- BitKeeper/etc/logging_ok | 1 + BitKeeper/triggers/post-incoming | 3 --- BitKeeper/triggers/post-outgoing | 3 --- BitKeeper/triggers/pre-commit | 12 ++++++++++++ 4 files changed, 13 insertions(+), 6 deletions(-) delete mode 100755 BitKeeper/triggers/post-incoming delete mode 100755 BitKeeper/triggers/post-outgoing create mode 100755 BitKeeper/triggers/pre-commit diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 806eac52759..0b6f4a222a0 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -97,6 +97,7 @@ sasha@mysql.sashanet.com serg@build.mysql2.com serg@serg.mylan serg@serg.mysql.com +serg@sergbook.mylan serg@sergbook.mysql.com sinisa@rhols221.adsl.netsonic.fi tfr@beta.frontier86.ee diff --git a/BitKeeper/triggers/post-incoming b/BitKeeper/triggers/post-incoming deleted file mode 100755 index f1ea2255de9..00000000000 --- a/BitKeeper/triggers/post-incoming +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh - -echo "Test: post-incoming works" diff --git a/BitKeeper/triggers/post-outgoing b/BitKeeper/triggers/post-outgoing deleted file mode 100755 index 3fc2cdbad67..00000000000 --- a/BitKeeper/triggers/post-outgoing +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh - -echo "Test: post-outgoing works" diff --git a/BitKeeper/triggers/pre-commit b/BitKeeper/triggers/pre-commit new file mode 100755 index 00000000000..2293dc55e2a --- /dev/null +++ b/BitKeeper/triggers/pre-commit @@ -0,0 +1,12 @@ +#!/bin/sh + +if [ "$REAL_EMAIL" = "" ] +then + echo "Error: you must set REAL_EMAIL in your profile" + echo "e.g.: export REAL_EMAIL='Joe Dow '" + echo "" + echo "Commit FAILED!" + echo "Set REAL_EMAIL and retry." + exit 1 +fi + From eeb987ddd7119975083af26c803d693c214880f7 Mon Sep 17 00:00:00 2001 From: "paul@teton.kitebird.com" <> Date: Wed, 18 Jun 2003 12:10:40 -0500 Subject: [PATCH 06/12] INSTALL-WIN-SOURCE: More edits to INSTALL-WIN-SOURCE. --- INSTALL-WIN-SOURCE | 116 ++++++++++++++++++++++++--------------------- 1 file changed, 63 insertions(+), 53 deletions(-) diff --git a/INSTALL-WIN-SOURCE b/INSTALL-WIN-SOURCE index ee3e35a91c8..bce093633f5 100755 --- a/INSTALL-WIN-SOURCE +++ b/INSTALL-WIN-SOURCE @@ -10,7 +10,7 @@ This is a simple 'HOWTO' document describing how to build MySQL binaries for versions 4.1 and above on Windows. Instructions are provided for building binaries from a standard source distribution or from the BitKeeper -tree that contains the latest developer source. +tree that contains the latest development source. --------------------------------------------------------- NOTE @@ -51,29 +51,15 @@ system: - ~45 MB disk space - 64 MB RAM -You'll also need a MySQL source distribution. You can -get the source for released versions of MySQL from: - -http://www.mysql.com/downloads/ - -Alternatively, you can package a source distribution -yourself from the latest BitKeeper developer source -tree. If you plan to do this, you must create the -package on a Unix system and then transfer it to your -Windows system. (The reason for this is that the initial -configuration scripts and some of the build steps work -only on Unix.) The BitKeeper approach thus requires: - - - A system running Unix, or a Unix-like system such as Linux - - BitKeeper 3.0 installed on that system (you can obtain - BitKeeper from http://www.bitkeeper.com) +You'll also need a MySQL source distribution, which you +can obtain as described in section 2. ------------------------------------------------------- 2. OBTAINING A WINDOWS SOURCE DISTRIBUTION ------------------------------------------------------- -There are two ways you can get a Windows source distribution for -MySQL version 4.1 and above: +There are two ways you can get a Windows source distribution +for MySQL version 4.1 and above: I. Obtain a MySQL AB-distributed source distribution for the particular version of MySQL in which you are interested. @@ -82,41 +68,54 @@ MySQL version 4.1 and above: http://www.mysql.com/downloads/ - II. Create a source package yourself from the latest development - 'BitKeeper' source tree. + II. Alternatively, you can package a source distribution + yourself from the latest BitKeeper developer source + tree. If you plan to do this, you must create the + package on a Unix system and then transfer it to your + Windows system. (The reason for this is that some of the + configuration and build steps require tools that work only + on Unix.) The BitKeeper approach thus requires: + + - A system running Unix, or a Unix-like system such as Linux + - BitKeeper 3.0 installed on that system (you can obtain + BitKeeper from http://www.bitkeeper.com) If you are using the first option, you can skip the next -section and go directly to 'BUILDING FROM VC++ WORKSPACE'. +section and go directly to "BUILDING 'mysql server & clients' +FROM VC++ WORKSPACE" ------------------------------------------------------- 3. CREATING A SOURCE PACKAGE FROM THE 'BitKeeper' TREE ------------------------------------------------------- -To build the latest Windows source package, Please follow the -following instructions from any of your '*UNIX*' operating -systems (preferably Linux): +To build the latest Windows source package from the current +BitKeeper source tree, use the following instructions. Please +note that this procedure must be performed on a system +running a Unix or Unix-like operating system. (The procedure +is know to work well on Linux, for example. - Clone the BitKeeper source tree for MySQL (version 4.1 or above, as desired). For more information how to clone - the BitKeeper source tree, follow the instructions at: + the source tree, see the instructions at: http://www.mysql.com/doc/en/Installing_source_tree.html -- Build the distribution so that you have a server binary to - work with. One way to do this is to run the following - command in the top-level directory of your source tree: +- Configure and build the distribution so that you have a + server binary to work with. One way to do this is to run + the following command in the top-level directory of your + source tree: ./BUILD/compile-pentium-max -- After making sure that build process completed successfully, +- After making sure that the build process completed successfully, run the following utility script from top-level directory of your source tree: ./scripts/make_win_src_distribution - This script creates the Windows source package. You can - supply different options to the script based on your needs. - It accepts: the following options: + This script creates a Windows source package, to be used on + your Windows system. You can supply different options to the + script based on your needs. It accepts the following options: --debug Debug, without creating the package --tmp Specify the temporary location @@ -128,15 +127,14 @@ systems (preferably Linux): By default, make_win_src_distribution creates a zipped archive with the name mysql-$version-win-src.zip, where - $version is the version of the MySQL source tree you - cloned. + $version represents the version of your MySQL source tree. - Copy or upload to your Windows machine the Windows source - package that you have just created, and compile it using + package that you have just created. To compile it, use the instructions in the next section. --------------------------------------------------------- -4. BUILDING 'mysql server & clients' FROM VC++ WORKSPACE +4. BUILDING 'mysql server & clients' FROM VC++ WORKSPACE --------------------------------------------------------- NOTE: MySQL 4.1 and above VC++ workspace files are compatible @@ -148,20 +146,20 @@ Unpack the Windows source zipped archive to a folder and open mysql.dsw from your top-level directory. If you want to build both release and debug versions, then -select 'build' -> 'buildall' option. To build only 'release' -or 'debug' versions, then select all appropriate workspaces -from the 'build' -> 'batch build' option. +select 'build' -> 'buildall' option. To build only release +or debug versions, select all appropriate workspaces from +the 'build' -> 'batch build' option. -The simplest solution to build basic clients and core +The simplest solution to building the basic clients and core server is to set your current active workspace as 'mysqld' release or debug version, and just hit 'build' or 'F7', which -creates necessary client binaries in the 'client_release' or -'client_debug' directories. The libraries are placed in the +creates the necessary client binaries in the 'client_release' +or 'client_debug' directories. The libraries are placed in the 'lib_release' and 'lib_debug' directories for release and debug versions, respectively. Now you have built the distribution. If you get any compiler -errors, please cross check and send the compiler output to +errors, please cross check and email the compiler output to win32@lists.mysql.com for further assistance. --------------------------------------------------------- @@ -173,16 +171,28 @@ TODO from MySQL PIEFU team. 6. STARTING THE MYSQL SERVER FOR THE FIRST TIME --------------------------------------------------------- -First ensure to set or copy my.ini or my.cnf file to your -'data' directory that exists in the top-level directory or -point to existing 'data' directory. +The server built using the preceding instructions will +expect that the MySQL base directory and data directory +are C:\mysql and C:\mysql\data by default. If you want to +test your server using the source root directory and its +data directory as the base directory and data directory, +you will need to tell the server their pathnames. You can +either do this on the command line with the --basedir +and --data-dir options, or place appropriate options in +an option file (C:\my.cnf or the my.ini file in your +Windows directory). If you have an existing data directory +elsewhere that you want to use, you can specify its pathname +instead. -Now, start your server from the 'client_release' or -'client_debug' directory (depending on which server you -want to use), by following the instructions from: +Start your server from the 'client_release' or 'client_debug' +directory (depending on which server you want to use). The +general instructions are given here: http://www.mysql.com/doc/en/Windows_installation.html +You'll have to adapt the instructions appropriately if you +want to use a different base directory and/or data directory. + That's all!!! See, it's as simple to build MySQL on Windows as on any other platform!!! @@ -200,12 +210,12 @@ exists in your 'client_release' or 'client_debug' directory. --------------------------------------------------------- - For production use, MySQL AB does not advise using a MySQL - server built by yourself from source. Instead, stick to - binaries shipped by MySQL AB. + server built by yourself from source. It is preferable to + stick to using binaries shipped by MySQL AB. - If you find something not working as expected, or you have suggestions about ways to improve the current build process - on Windows, please email to 'win32@lists.mysql.com'. + on Windows, please email to win32@lists.mysql.com. Thanks MySQL Team From a7f584da794e6073c4268f4a4b18c4244a0a1aa0 Mon Sep 17 00:00:00 2001 From: "lenz@kallisto.local" <> Date: Wed, 18 Jun 2003 23:13:29 +0200 Subject: [PATCH 07/12] - added sql-common subdirectory and sql_common.h to source distribution --- Makefile.am | 2 +- configure.in | 8 +++++--- include/Makefile.am | 2 +- sql-common/Makefile.am | 21 +++++++++++++++++++++ 4 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 sql-common/Makefile.am diff --git a/Makefile.am b/Makefile.am index 1fcf498a84b..ffebf891795 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,7 +22,7 @@ AUTOMAKE_OPTIONS = foreign EXTRA_DIST = INSTALL-SOURCE README \ COPYING COPYING.LIB SUBDIRS = . include @docs_dirs@ \ - @readline_topdir@ \ + @readline_topdir@ sql-common \ @thread_dirs@ pstack @sql_client_dirs@ \ @sql_server_dirs@ scripts man tests \ BUILD @netware_dir@ os2 @libmysqld_dirs@ \ diff --git a/configure.in b/configure.in index bddeeb6c989..63b33e391b2 100644 --- a/configure.in +++ b/configure.in @@ -2176,8 +2176,8 @@ AC_ARG_WITH(libedit, [ with_libedit=undefined ] ) -compile_readline= no -compile_libedit= no +compile_readline="no" +compile_libedit="no" if [test "$with_libedit" = "yes"] && [test "$with_readline" = "yes"] then @@ -2820,6 +2820,7 @@ AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile dnl libmysql_r/Makefile libmysqld/Makefile libmysqld/examples/Makefile dnl libmysql/Makefile client/Makefile dnl pstack/Makefile pstack/aout/Makefile sql/Makefile sql/share/Makefile dnl + sql-common/Makefile dnl merge/Makefile dbug/Makefile scripts/Makefile dnl include/Makefile sql-bench/Makefile tools/Makefile dnl tests/Makefile Docs/Makefile support-files/Makefile dnl @@ -2840,6 +2841,7 @@ echo "Remember to check the platform specific part of the reference manual for" echo "hints about installing MySQL on your platform. Also have a look at the" echo "files in the Docs directory." echo -# The following text is checked in ./Do-compile to se that the configure ends. +# The following text is checked in ./Do-compile to verify that configure +# ended sucessfully - don't remove it. echo "Thank you for choosing MySQL!" echo diff --git a/include/Makefile.am b/include/Makefile.am index 3a197c310aa..81966233a32 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -21,7 +21,7 @@ pkginclude_HEADERS = my_dbug.h m_string.h my_sys.h my_list.h my_xml.h \ my_semaphore.h my_pthread.h my_no_pthread.h raid.h \ errmsg.h my_global.h my_net.h my_alloc.h \ my_getopt.h sslopt-longopts.h my_dir.h typelib.h \ - sslopt-vars.h sslopt-case.h $(BUILT_SOURCES) + sslopt-vars.h sslopt-case.h sql_common.h $(BUILT_SOURCES) noinst_HEADERS = config-win.h config-os2.h config-netware.h \ nisam.h heap.h merge.h my_bitmap.h\ myisam.h myisampack.h myisammrg.h ft_global.h\ diff --git a/sql-common/Makefile.am b/sql-common/Makefile.am new file mode 100644 index 00000000000..1f397c0ea87 --- /dev/null +++ b/sql-common/Makefile.am @@ -0,0 +1,21 @@ +# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to create Makefile.in +EXTRA_DIST = client.c pack.c + +# Don't update the files from bitkeeper +%::SCCS/s.% From 69af692a5cbbfa32a70736a1ac78dfbfdff77f7c Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Thu, 19 Jun 2003 11:36:44 +0500 Subject: [PATCH 08/12] These functions now return a result of proper collation: BIN OCT CONV HEX CHAR FORMAT REPLACE --- mysql-test/r/func_str.result | 41 ++++++++++++++++++++++++++++++++++-- mysql-test/t/func_str.test | 17 +++++++++++++-- sql/item.cc | 2 +- sql/item_strfunc.cc | 15 +++++++++++++ sql/item_strfunc.h | 19 ++++++++++++++--- 5 files changed, 86 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index ffb7f2cd911..302d9d7374b 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -249,6 +249,24 @@ INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf'); SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password"); 1 DROP TABLE t1; +select collation(bin(130)), coercibility(bin(130)); +collation(bin(130)) coercibility(bin(130)) +latin1_swedish_ci 3 +select collation(oct(130)), coercibility(oct(130)); +collation(oct(130)) coercibility(oct(130)) +latin1_swedish_ci 3 +select collation(conv(130,16,10)), coercibility(conv(130,16,10)); +collation(conv(130,16,10)) coercibility(conv(130,16,10)) +latin1_swedish_ci 3 +select collation(hex(130)), coercibility(hex(130)); +collation(hex(130)) coercibility(hex(130)) +latin1_swedish_ci 3 +select collation(char(130)), coercibility(hex(130)); +collation(char(130)) coercibility(hex(130)) +binary 3 +select collation(format(130,10)), coercibility(format(130,10)); +collation(format(130,10)) coercibility(format(130,10)) +latin1_swedish_ci 3 select collation(lcase(_latin2'a')), coercibility(lcase(_latin2'a')); collation(lcase(_latin2'a')) coercibility(lcase(_latin2'a')) latin2_general_ci 3 @@ -306,8 +324,17 @@ latin2_general_ci 3 select collation(insert(_latin2'abcd',2,3,_latin2'ef')), coercibility(insert(_latin2'abcd',2,3,_latin2'ef')); collation(insert(_latin2'abcd',2,3,_latin2'ef')) coercibility(insert(_latin2'abcd',2,3,_latin2'ef')) latin2_general_ci 3 +select collation(replace(_latin2'abcd',_latin2'b',_latin2'B')), coercibility(replace(_latin2'abcd',_latin2'b',_latin2'B')); +collation(replace(_latin2'abcd',_latin2'b',_latin2'B')) coercibility(replace(_latin2'abcd',_latin2'b',_latin2'B')) +latin2_general_ci 3 create table t1 select +bin(130), +oct(130), +conv(130,16,10), +hex(130), +char(130), +format(130,10), left(_latin2'a',1), right(_latin2'a',1), lcase(_latin2'a'), @@ -326,11 +353,20 @@ reverse(_latin2'ab'), quote(_latin2'ab'), soundex(_latin2'ab'), substring(_latin2'ab',1), -insert(_latin2'abcd',2,3,_latin2'ef') +insert(_latin2'abcd',2,3,_latin2'ef'), +replace(_latin2'abcd',_latin2'b',_latin2'B') ; +Warnings: +Warning 1263 Data truncated for column 'format(130,10)' at row 1 show create table t1; Table Create Table t1 CREATE TABLE `t1` ( + `bin(130)` char(64) NOT NULL default '', + `oct(130)` char(64) NOT NULL default '', + `conv(130,16,10)` char(64) NOT NULL default '', + `hex(130)` char(6) NOT NULL default '', + `char(130)` char(1) NOT NULL default '', + `format(130,10)` char(4) NOT NULL default '', `left(_latin2'a',1)` char(1) character set latin2 NOT NULL default '', `right(_latin2'a',1)` char(1) character set latin2 NOT NULL default '', `lcase(_latin2'a')` char(1) character set latin2 NOT NULL default '', @@ -349,6 +385,7 @@ t1 CREATE TABLE `t1` ( `quote(_latin2'ab')` char(6) character set latin2 NOT NULL default '', `soundex(_latin2'ab')` char(4) character set latin2 NOT NULL default '', `substring(_latin2'ab',1)` char(2) character set latin2 NOT NULL default '', - `insert(_latin2'abcd',2,3,_latin2'ef')` char(6) character set latin2 NOT NULL default '' + `insert(_latin2'abcd',2,3,_latin2'ef')` char(6) character set latin2 NOT NULL default '', + `replace(_latin2'abcd',_latin2'b',_latin2'B')` char(4) character set latin2 NOT NULL default '' ) TYPE=MyISAM CHARSET=latin1 drop table t1; diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 93e35efa455..1d33d196bdd 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -136,6 +136,12 @@ DROP TABLE t1; # # Test collation and coercibility # +select collation(bin(130)), coercibility(bin(130)); +select collation(oct(130)), coercibility(oct(130)); +select collation(conv(130,16,10)), coercibility(conv(130,16,10)); +select collation(hex(130)), coercibility(hex(130)); +select collation(char(130)), coercibility(hex(130)); +select collation(format(130,10)), coercibility(format(130,10)); select collation(lcase(_latin2'a')), coercibility(lcase(_latin2'a')); select collation(ucase(_latin2'a')), coercibility(ucase(_latin2'a')); select collation(left(_latin2'a',1)), coercibility(left(_latin2'a',1)); @@ -155,9 +161,16 @@ select collation(quote(_latin2'ab')), coercibility(quote(_latin2'ab')); select collation(soundex(_latin2'ab')), coercibility(soundex(_latin2'ab')); select collation(substring(_latin2'ab',1)), coercibility(substring(_latin2'ab',1)); select collation(insert(_latin2'abcd',2,3,_latin2'ef')), coercibility(insert(_latin2'abcd',2,3,_latin2'ef')); +select collation(replace(_latin2'abcd',_latin2'b',_latin2'B')), coercibility(replace(_latin2'abcd',_latin2'b',_latin2'B')); create table t1 select + bin(130), + oct(130), + conv(130,16,10), + hex(130), + char(130), + format(130,10), left(_latin2'a',1), right(_latin2'a',1), lcase(_latin2'a'), @@ -176,8 +189,8 @@ select quote(_latin2'ab'), soundex(_latin2'ab'), substring(_latin2'ab',1), - insert(_latin2'abcd',2,3,_latin2'ef') + insert(_latin2'abcd',2,3,_latin2'ef'), + replace(_latin2'abcd',_latin2'b',_latin2'B') ; - show create table t1; drop table t1; diff --git a/sql/item.cc b/sql/item.cc index cdd78572a0a..57efd3e7bf3 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -39,7 +39,7 @@ Item::Item(): { marker= 0; maybe_null=null_value=with_sum_func=unsigned_flag=0; - coercibility=COER_IMPLICIT; + coercibility=COER_COERCIBLE; name= 0; decimals= 0; max_length= 0; THD *thd= current_thd; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index d660f7c472c..9ab20281a97 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -813,6 +813,7 @@ null: void Item_func_replace::fix_length_and_dec() { + uint i; max_length=args[0]->max_length; int diff=(int) (args[2]->max_length - args[1]->max_length); if (diff > 0 && args[1]->max_length) @@ -825,6 +826,20 @@ void Item_func_replace::fix_length_and_dec() max_length=MAX_BLOB_WIDTH; maybe_null=1; } + set_charset(args[0]->charset(), args[0]->coercibility); + + for (i=1; i<3; i++) + { + if (set_charset(charset(), coercibility, + args[i]->charset(), args[i]->coercibility)) + { + my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), + charset()->name,coercion_name(coercibility), + args[i]->charset()->name,coercion_name(args[i]->coercibility), + func_name()); + break; + } + } } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 26c69668b0a..6bb1c510013 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -433,6 +433,7 @@ public: String *val_str(String *); void fix_length_and_dec() { + set_charset(default_charset()); max_length=args[0]->max_length+(args[0]->max_length-args[0]->decimals)/3; } const char *func_name() const { return "format"; } @@ -444,7 +445,11 @@ class Item_func_char :public Item_str_func public: Item_func_char(List &list) :Item_str_func(list) {} String *val_str(String *); - void fix_length_and_dec() { maybe_null=0; max_length=arg_count; } + void fix_length_and_dec() + { + set_charset(default_charset()); + maybe_null=0; max_length=arg_count; + } const char *func_name() const { return "char"; } }; @@ -490,7 +495,11 @@ public: Item_func_conv(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {} const char *func_name() const { return "conv"; } String *val_str(String *); - void fix_length_and_dec() { decimals=0; max_length=64; } + void fix_length_and_dec() + { + set_charset(default_charset()); + decimals=0; max_length=64; + } }; @@ -501,7 +510,11 @@ public: Item_func_hex(Item *a) :Item_str_func(a) {} const char *func_name() const { return "hex"; } String *val_str(String *); - void fix_length_and_dec() { decimals=0; max_length=args[0]->max_length*2; } + void fix_length_and_dec() + { + set_charset(default_charset()); + decimals=0; max_length=args[0]->max_length*2; + } }; From ebb88ec6ead1c84438bf632e259958d03b48adf2 Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Thu, 19 Jun 2003 13:12:55 +0500 Subject: [PATCH 09/12] LPAD, RPAD, MAKE_SET and EXPORT_SET now works correctly with collations --- mysql-test/r/func_str.result | 20 +++++++++++++++ mysql-test/t/func_str.test | 8 ++++++ sql/item_strfunc.cc | 47 +++++++++++++++++++++++++++++++++++- 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 302d9d7374b..6ee452764c2 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -285,9 +285,21 @@ latin2_general_ci 3 select collation(concat(_latin2'a',_latin2'b')), coercibility(concat(_latin2'a',_latin2'b')); collation(concat(_latin2'a',_latin2'b')) coercibility(concat(_latin2'a',_latin2'b')) latin2_general_ci 3 +select collation(lpad(_latin2'a',4,_latin2'b')), coercibility(lpad(_latin2'a',4,_latin2'b')); +collation(lpad(_latin2'a',4,_latin2'b')) coercibility(lpad(_latin2'a',4,_latin2'b')) +binary 3 +select collation(rpad(_latin2'a',4,_latin2'b')), coercibility(rpad(_latin2'a',4,_latin2'b')); +collation(rpad(_latin2'a',4,_latin2'b')) coercibility(rpad(_latin2'a',4,_latin2'b')) +latin2_general_ci 3 select collation(concat_ws(_latin2'a',_latin2'b')), coercibility(concat_ws(_latin2'a',_latin2'b')); collation(concat_ws(_latin2'a',_latin2'b')) coercibility(concat_ws(_latin2'a',_latin2'b')) latin2_general_ci 3 +select collation(make_set(255,_latin2'a',_latin2'b',_latin2'c')), coercibility(make_set(255,_latin2'a',_latin2'b',_latin2'c')); +collation(make_set(255,_latin2'a',_latin2'b',_latin2'c')) coercibility(make_set(255,_latin2'a',_latin2'b',_latin2'c')) +latin2_general_ci 3 +select collation(export_set(255,_latin2'y',_latin2'n',_latin2' ')), coercibility(export_set(255,_latin2'y',_latin2'n',_latin2' ')); +collation(export_set(255,_latin2'y',_latin2'n',_latin2' ')) coercibility(export_set(255,_latin2'y',_latin2'n',_latin2' ')) +binary 3 select collation(trim(_latin2' a ')), coercibility(trim(_latin2' a ')); collation(trim(_latin2' a ')) coercibility(trim(_latin2' a ')) latin2_general_ci 3 @@ -341,7 +353,11 @@ lcase(_latin2'a'), ucase(_latin2'a'), substring(_latin2'a',1,1), concat(_latin2'a',_latin2'b'), +lpad(_latin2'a',4,_latin2'b'), +rpad(_latin2'a',4,_latin2'b'), concat_ws(_latin2'a',_latin2'b'), +make_set(255,_latin2'a',_latin2'b',_latin2'c'), +export_set(255,_latin2'y',_latin2'n',_latin2' '), trim(_latin2' a '), ltrim(_latin2' a '), rtrim(_latin2' a '), @@ -373,7 +389,11 @@ t1 CREATE TABLE `t1` ( `ucase(_latin2'a')` char(1) character set latin2 NOT NULL default '', `substring(_latin2'a',1,1)` char(1) character set latin2 NOT NULL default '', `concat(_latin2'a',_latin2'b')` char(2) character set latin2 NOT NULL default '', + `lpad(_latin2'a',4,_latin2'b')` char(4) character set latin2 NOT NULL default '', + `rpad(_latin2'a',4,_latin2'b')` char(4) character set latin2 NOT NULL default '', `concat_ws(_latin2'a',_latin2'b')` char(1) character set latin2 NOT NULL default '', + `make_set(255,_latin2'a',_latin2'b',_latin2'c')` char(5) character set latin2 NOT NULL default '', + `export_set(255,_latin2'y',_latin2'n',_latin2' ')` char(127) character set latin2 NOT NULL default '', `trim(_latin2' a ')` char(3) character set latin2 NOT NULL default '', `ltrim(_latin2' a ')` char(3) character set latin2 NOT NULL default '', `rtrim(_latin2' a ')` char(3) character set latin2 NOT NULL default '', diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 1d33d196bdd..83d49743a4a 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -148,7 +148,11 @@ select collation(left(_latin2'a',1)), coercibility(left(_latin2'a',1)); select collation(right(_latin2'a',1)), coercibility(right(_latin2'a',1)); select collation(substring(_latin2'a',1,1)), coercibility(substring(_latin2'a',1,1)); select collation(concat(_latin2'a',_latin2'b')), coercibility(concat(_latin2'a',_latin2'b')); +select collation(lpad(_latin2'a',4,_latin2'b')), coercibility(lpad(_latin2'a',4,_latin2'b')); +select collation(rpad(_latin2'a',4,_latin2'b')), coercibility(rpad(_latin2'a',4,_latin2'b')); select collation(concat_ws(_latin2'a',_latin2'b')), coercibility(concat_ws(_latin2'a',_latin2'b')); +select collation(make_set(255,_latin2'a',_latin2'b',_latin2'c')), coercibility(make_set(255,_latin2'a',_latin2'b',_latin2'c')); +select collation(export_set(255,_latin2'y',_latin2'n',_latin2' ')), coercibility(export_set(255,_latin2'y',_latin2'n',_latin2' ')); select collation(trim(_latin2' a ')), coercibility(trim(_latin2' a ')); select collation(ltrim(_latin2' a ')), coercibility(ltrim(_latin2' a ')); select collation(rtrim(_latin2' a ')), coercibility(rtrim(_latin2' a ')); @@ -177,7 +181,11 @@ select ucase(_latin2'a'), substring(_latin2'a',1,1), concat(_latin2'a',_latin2'b'), + lpad(_latin2'a',4,_latin2'b'), + rpad(_latin2'a',4,_latin2'b'), concat_ws(_latin2'a',_latin2'b'), + make_set(255,_latin2'a',_latin2'b',_latin2'c'), + export_set(255,_latin2'y',_latin2'n',_latin2' '), trim(_latin2' a '), ltrim(_latin2' a '), rtrim(_latin2' a '), diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 9ab20281a97..4955c699315 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1780,8 +1780,20 @@ void Item_func_make_set::split_sum_func(Item **ref_pointer_array, void Item_func_make_set::fix_length_and_dec() { max_length=arg_count-1; - for (uint i=1 ; i < arg_count ; i++) + set_charset(args[0]->charset(), args[0]->coercibility); + for (uint i=0 ; i < arg_count ; i++) + { max_length+=args[i]->max_length; + if (set_charset(charset(), coercibility, + args[i]->charset(), args[i]->coercibility)) + { + my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), + charset()->name,coercion_name(coercibility), + args[i]->charset()->name,coercion_name(args[i]->coercibility), + func_name()); + break; + } + } used_tables_cache|=item->used_tables(); const_item_cache&=item->const_item(); with_sum_func= with_sum_func || item->with_sum_func; @@ -1964,6 +1976,15 @@ err: void Item_func_rpad::fix_length_and_dec() { + if (set_charset(args[0]->charset(), args[0]->coercibility, + args[2]->charset(), args[2]->coercibility)) + { + my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), + args[0]->charset()->name,coercion_name(args[0]->coercibility), + args[2]->charset()->name,coercion_name(args[2]->coercibility), + func_name()); + } + if (args[1]->const_item()) { uint32 length= (uint32) args[1]->val_int(); @@ -2024,6 +2045,15 @@ String *Item_func_rpad::val_str(String *str) void Item_func_lpad::fix_length_and_dec() { + if (set_charset(args[0]->charset(), args[0]->coercibility, + args[2]->charset(), args[2]->coercibility)) + { + my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), + args[0]->charset()->name,coercion_name(args[0]->coercibility), + args[2]->charset()->name,coercion_name(args[2]->coercibility), + func_name()); + } + if (args[1]->const_item()) { uint32 length= (uint32) args[1]->val_int(); @@ -2433,9 +2463,24 @@ String* Item_func_export_set::val_str(String* str) void Item_func_export_set::fix_length_and_dec() { + uint i; uint length=max(args[1]->max_length,args[2]->max_length); uint sep_length=(arg_count > 3 ? args[3]->max_length : 1); max_length=length*64+sep_length*63; + + set_charset(args[1]->charset(), args[1]->coercibility); + for (i=2 ; i < 4 && i < arg_count ; i++) + { + if (set_charset(charset(), coercibility, + args[i]->charset(), args[i]->coercibility)) + { + my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), + charset()->name,coercion_name(coercibility), + args[i]->charset()->name,coercion_name(args[i]->coercibility), + func_name()); + break; + } + } } String* Item_func_inet_ntoa::val_str(String* str) From 853c3dd77fa986ea743fe71a4743a8ed6d22885b Mon Sep 17 00:00:00 2001 From: "lenz@kallisto.local" <> Date: Thu, 19 Jun 2003 10:46:45 +0200 Subject: [PATCH 10/12] - added libmysql/client_settings.h to distribution --- libmysql/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am index 128f1c03967..0125bd2b98d 100644 --- a/libmysql/Makefile.am +++ b/libmysql/Makefile.am @@ -28,6 +28,7 @@ libmysqlclient_la_SOURCES = $(target_sources) libmysqlclient_la_LIBADD = $(target_libadd) libmysqlclient_la_LDFLAGS = $(target_ldflags) EXTRA_DIST = Makefile.shared +noinst_HEADERS = client_settings.h # This is called from the toplevel makefile link_sources: From 3ed12d5a7473ee1711c471b74aaccfa9d544b33d Mon Sep 17 00:00:00 2001 From: "igor@rurik.mysql.com" <> Date: Thu, 19 Jun 2003 02:34:33 -0700 Subject: [PATCH 11/12] preload.result, preload.test: Removed non-generic info (key used blocks) preload.result, preload.test, lex.h, sql_yacc.yy: Syntax change for preload statement --- mysql-test/r/preload.result | 87 +++++++++---------------------------- mysql-test/t/preload.test | 41 +++++++++-------- sql/lex.h | 1 - sql/sql_yacc.yy | 10 ++--- 4 files changed, 44 insertions(+), 95 deletions(-) diff --git a/mysql-test/r/preload.result b/mysql-test/r/preload.result index 0afd95b6fb8..4d9293c7929 100644 --- a/mysql-test/r/preload.result +++ b/mysql-test/r/preload.result @@ -46,169 +46,122 @@ count(*) 20672 flush tables; flush status; -show status like "key_%"; +show status like "key_read%"; Variable_name Value -Key_blocks_used 918 Key_read_requests 0 Key_reads 0 -Key_write_requests 0 -Key_writes 0 select count(*) from t1 where b = 'test1'; count(*) 4181 -show status like "key_%"; +show status like "key_read%"; Variable_name Value -Key_blocks_used 918 Key_read_requests 217 Key_reads 45 -Key_write_requests 0 -Key_writes 0 select count(*) from t1 where b = 'test1'; count(*) 4181 -show status like "key_%"; +show status like "key_read%"; Variable_name Value -Key_blocks_used 918 Key_read_requests 434 Key_reads 45 -Key_write_requests 0 -Key_writes 0 flush tables; flush status; select @@preload_buffer_size; @@preload_buffer_size 32768 -preload t1 keys; +load index into cache t1 keys; Table Op Msg_type Msg_text test.t1 preload_keys status OK -show status like "preload_%"; +show status like "key_read%"; Variable_name Value -show status like "key_%"; -Variable_name Value -Key_blocks_used 918 Key_read_requests 0 Key_reads 0 -Key_write_requests 0 -Key_writes 0 select count(*) from t1 where b = 'test1'; count(*) 4181 -show status like "key_%"; +show status like "key_read%"; Variable_name Value -Key_blocks_used 918 Key_read_requests 217 Key_reads 45 -Key_write_requests 0 -Key_writes 0 flush tables; flush status; -show status like "key_%"; +show status like "key_read%"; Variable_name Value -Key_blocks_used 918 Key_read_requests 0 Key_reads 0 -Key_write_requests 0 -Key_writes 0 set session preload_buffer_size=256*1024; select @@preload_buffer_size; @@preload_buffer_size 262144 -preload t1 keys ignore leaves; +load index into cache t1 keys ignore leaves; Table Op Msg_type Msg_text test.t1 preload_keys status OK -show status like "key_%"; +show status like "key_read%"; Variable_name Value -Key_blocks_used 918 Key_read_requests 0 Key_reads 0 -Key_write_requests 0 -Key_writes 0 select count(*) from t1 where b = 'test1'; count(*) 4181 -show status like "key_%"; +show status like "key_read%"; Variable_name Value -Key_blocks_used 918 Key_read_requests 217 Key_reads 45 -Key_write_requests 0 -Key_writes 0 flush tables; flush status; -show status like "key_%"; +show status like "key_read%"; Variable_name Value -Key_blocks_used 918 Key_read_requests 0 Key_reads 0 -Key_write_requests 0 -Key_writes 0 set session preload_buffer_size=1*1024; select @@preload_buffer_size; @@preload_buffer_size 1024 -preload t1 keys, t2 keys (primary,b) ignore leaves; +load index into cache t1 keys, t2 keys (primary,b) ignore leaves; Table Op Msg_type Msg_text test.t1 preload_keys status OK test.t2 preload_keys status OK -show status like "key_%"; +show status like "key_read%"; Variable_name Value -Key_blocks_used 918 Key_read_requests 0 Key_reads 0 -Key_write_requests 0 -Key_writes 0 select count(*) from t1 where b = 'test1'; count(*) 4181 select count(*) from t2 where b = 'test1'; count(*) 2584 -show status like "key_%"; +show status like "key_read%"; Variable_name Value -Key_blocks_used 918 Key_read_requests 351 Key_reads 73 -Key_write_requests 0 -Key_writes 0 flush tables; flush status; -show status like "key_%"; +show status like "key_read%"; Variable_name Value -Key_blocks_used 918 Key_read_requests 0 Key_reads 0 -Key_write_requests 0 -Key_writes 0 -preload t3 keys, t2 keys (primary,b) ; +load index into cache t3 keys, t2 keys (primary,b) ; Table Op Msg_type Msg_text test.t3 preload_keys error Table 'test.t3' doesn't exist test.t2 preload_keys status OK -show status like "key_%"; +show status like "key_read%"; Variable_name Value -Key_blocks_used 918 Key_read_requests 0 Key_reads 0 -Key_write_requests 0 -Key_writes 0 flush tables; flush status; -show status like "key_%"; +show status like "key_read%"; Variable_name Value -Key_blocks_used 918 Key_read_requests 0 Key_reads 0 -Key_write_requests 0 -Key_writes 0 -preload t3 keys (b), t2 keys (c) ; +load index into cache t3 keys (b), t2 keys (c) ; Table Op Msg_type Msg_text test.t3 preload_keys error Table 'test.t3' doesn't exist test.t2 preload_keys error Key column 'c' doesn't exist in table test.t2 preload_keys status Operation failed -show status like "key_%"; +show status like "key_read%"; Variable_name Value -Key_blocks_used 918 Key_read_requests 0 Key_reads 0 -Key_write_requests 0 -Key_writes 0 drop table t1, t2; diff --git a/mysql-test/t/preload.test b/mysql-test/t/preload.test index 1fd0d0a5b17..7357b42c599 100755 --- a/mysql-test/t/preload.test +++ b/mysql-test/t/preload.test @@ -54,48 +54,47 @@ select count(*) from t1; select count(*) from t2; flush tables; flush status; -show status like "key_%"; +show status like "key_read%"; select count(*) from t1 where b = 'test1'; -show status like "key_%"; +show status like "key_read%"; select count(*) from t1 where b = 'test1'; -show status like "key_%"; +show status like "key_read%"; flush tables; flush status; select @@preload_buffer_size; -preload t1 keys; -show status like "preload_%"; -show status like "key_%"; +load index into cache t1 keys; +show status like "key_read%"; select count(*) from t1 where b = 'test1'; -show status like "key_%"; +show status like "key_read%"; flush tables; flush status; -show status like "key_%"; +show status like "key_read%"; set session preload_buffer_size=256*1024; select @@preload_buffer_size; -preload t1 keys ignore leaves; -show status like "key_%"; +load index into cache t1 keys ignore leaves; +show status like "key_read%"; select count(*) from t1 where b = 'test1'; -show status like "key_%"; +show status like "key_read%"; flush tables; flush status; -show status like "key_%"; +show status like "key_read%"; set session preload_buffer_size=1*1024; select @@preload_buffer_size; -preload t1 keys, t2 keys (primary,b) ignore leaves; -show status like "key_%"; +load index into cache t1 keys, t2 keys (primary,b) ignore leaves; +show status like "key_read%"; select count(*) from t1 where b = 'test1'; select count(*) from t2 where b = 'test1'; -show status like "key_%"; +show status like "key_read%"; flush tables; flush status; -show status like "key_%"; -preload t3 keys, t2 keys (primary,b) ; -show status like "key_%"; +show status like "key_read%"; +load index into cache t3 keys, t2 keys (primary,b) ; +show status like "key_read%"; flush tables; flush status; -show status like "key_%"; -preload t3 keys (b), t2 keys (c) ; -show status like "key_%"; +show status like "key_read%"; +load index into cache t3 keys (b), t2 keys (c) ; +show status like "key_read%"; drop table t1, t2; diff --git a/sql/lex.h b/sql/lex.h index 0c3e58c4a50..f7c4418cb8d 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -300,7 +300,6 @@ static SYMBOL symbols[] = { { "POLYGON", SYM(POLYGON),0,0}, { "PURGE", SYM(PURGE),0,0}, { "PRECISION", SYM(PRECISION),0,0}, - { "PRELOAD", SYM(PRELOAD),0,0}, { "PREV", SYM(PREV_SYM),0,0}, { "PRIMARY", SYM(PRIMARY_SYM),0,0}, { "PROCEDURE", SYM(PROCEDURE),0,0}, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0b18b7ffdc5..323fa3da6b6 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -310,7 +310,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token DUMPFILE %token PACK_KEYS_SYM %token PARTIAL -%token PRELOAD %token PRIMARY_SYM %token PRIVILEGES %token PROCESS @@ -581,7 +580,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); type int_type real_type order_dir opt_field_spec lock_option udf_type if_exists opt_local opt_table_options table_options table_option opt_if_not_exists opt_no_write_to_binlog opt_var_type opt_var_ident_type - delete_option opt_temporary all_or_any opt_distinct opt_ignore_leafs + delete_option opt_temporary all_or_any opt_distinct opt_ignore_leaves %type ULONG_NUM raid_types merge_insert_types @@ -1838,7 +1837,7 @@ table_to_table: }; preload: - PRELOAD + LOAD INDEX INTO CACHE_SYM { LEX *lex=Lex; lex->sql_command=SQLCOM_PRELOAD_KEYS; @@ -1852,7 +1851,7 @@ preload_list: | preload_list ',' preload_keys; preload_keys: - table_ident preload_keys_spec opt_ignore_leafs + table_ident preload_keys_spec opt_ignore_leaves { LEX *lex=Lex; SELECT_LEX *sel= &lex->select_lex; @@ -1880,7 +1879,7 @@ preload_key_list_or_empty: | '(' key_usage_list2 ')' {} ; -opt_ignore_leafs: +opt_ignore_leaves: /* empty */ { $$= 0; } | IGNORE_SYM LEAVES { $$= TL_OPTION_IGNORE_LEAVES; } @@ -4374,7 +4373,6 @@ keyword: | PASSWORD {} | POINT_SYM {} | POLYGON {} - | PRELOAD {} | PREV_SYM {} | PROCESS {} | PROCESSLIST_SYM {} From 1908cc62b609a3a455f2fbef479ccebd8d6bb885 Mon Sep 17 00:00:00 2001 From: "lenz@kallisto.local" <> Date: Thu, 19 Jun 2003 12:18:04 +0200 Subject: [PATCH 12/12] - revert wrong include of zlib.h as zlib is not part of the source distribution - better use -I../zlib where appropriate (usually we use the zlib installed in the system) --- sql/item_strfunc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 9ab20281a97..fddb761fc53 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2572,7 +2572,7 @@ null: } #ifdef HAVE_COMPRESS -#include "../zlib/zlib.h" +#include "zlib.h" String *Item_func_compress::val_str(String *str) {