From e8a3a141c50aaa0f697aaa89c349764bbbbfbd13 Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Sat, 22 Dec 2001 21:08:25 +0200 Subject: [PATCH 01/15] data0type.ic, rem0cmp.c: Allow foreign keys refer between fixed and var length strings --- innobase/include/data0type.ic | 11 +++++++---- innobase/rem/rem0cmp.c | 10 +++++++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/innobase/include/data0type.ic b/innobase/include/data0type.ic index 4a62902eb1b..d82d976d076 100644 --- a/innobase/include/data0type.ic +++ b/innobase/include/data0type.ic @@ -107,14 +107,17 @@ dtype_get_pad_char( ULINT_UNDEFINED if no padding specified */ dtype_t* type) /* in: type */ { - if (type->mtype == DATA_CHAR) { - /* space is the padding character for all char strings */ + if (type->mtype == DATA_CHAR + || type->mtype == DATA_VARCHAR + || type->mtype == DATA_BINARY + || type->mtype == DATA_FIXBINARY) { + + /* Space is the padding character for all char and binary + strings */ return((ulint)' '); } - ut_ad((type->mtype == DATA_BINARY) || (type->mtype == DATA_VARCHAR)); - /* No padding specified */ return(ULINT_UNDEFINED); diff --git a/innobase/rem/rem0cmp.c b/innobase/rem/rem0cmp.c index f3d9d579aa0..363bb013ac9 100644 --- a/innobase/rem/rem0cmp.c +++ b/innobase/rem/rem0cmp.c @@ -100,7 +100,15 @@ cmp_types_are_equal( dtype_t* type1, /* in: type 1 */ dtype_t* type2) /* in: type 2 */ { - if (type1->mtype != type2->mtype) { + if ((type1->mtype == DATA_VARCHAR && type2->mtype == DATA_CHAR) + || (type1->mtype == DATA_CHAR && type2->mtype == DATA_VARCHAR) + || (type1->mtype == DATA_FIXBINARY && type2->mtype == DATA_BINARY) + || (type1->mtype == DATA_BINARY && type2->mtype == DATA_FIXBINARY)) { + + return(TRUE); + } + + if (type1->mtype != type2->mtype) { return(FALSE); } From 954920c874a82fdba6c6a7ad28041635c622b21b Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Sun, 23 Dec 2001 13:06:48 +0200 Subject: [PATCH 02/15] ha_innobase.cc: Increase table comment print size to 500 bytes to be able to print more foreign key constraint infos ha_innobase.h: Change max key len back to 500 bytes because MySQL interpreter cannot handle more --- sql/ha_innobase.cc | 4 ++-- sql/ha_innobase.h | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc index dc030dde39a..62c721de13f 100644 --- a/sql/ha_innobase.cc +++ b/sql/ha_innobase.cc @@ -3220,7 +3220,7 @@ ha_innobase::update_table_comment( { row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; uint length = strlen(comment); - char* str = my_malloc(length + 200, MYF(0)); + char* str = my_malloc(length + 550, MYF(0)); char* pos; if (!str) { @@ -3239,7 +3239,7 @@ ha_innobase::update_table_comment( /* We assume 150 bytes of space to print info */ - dict_print_info_on_foreign_keys(pos, 150, prebuilt->table); + dict_print_info_on_foreign_keys(pos, 500, prebuilt->table); return(str); } diff --git a/sql/ha_innobase.h b/sql/ha_innobase.h index 84698a9114b..3f4bd5144eb 100644 --- a/sql/ha_innobase.h +++ b/sql/ha_innobase.h @@ -100,8 +100,11 @@ class ha_innobase: public handler a secondary key record must also contain the primary key value: max key length is therefore set to slightly - less than 1 / 4 of page size which is 16 kB */ - uint max_key_length() const { return 3500; } + less than 1 / 4 of page size which is 16 kB; + but currently MySQL does not work with keys + whose size is > MAX_KEY_LENGTH */ + uint max_key_length() const { return((MAX_KEY_LENGTH <= 3500) ? + MAX_KEY_LENGTH : 3500);} bool fast_key_read() { return 1;} key_map keys_to_use_for_scanning() { return ~(key_map) 0; } bool has_transactions() { return 1;} From 7f44419d423a16aca7628ade8dcad2e99771e03f Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Mon, 24 Dec 2001 22:27:11 +0200 Subject: [PATCH 03/15] log0recv.c: Print progress info of the applying log records to the database phase in recovery srv0srv.c: Do buffer pool flush and checkpoints more often to make recovery faster --- innobase/log/log0recv.c | 18 +++++++++++++++++- innobase/srv/srv0srv.c | 14 +++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index f83a49d01a6..5cd5850d1a1 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -1019,7 +1019,8 @@ loop: if (recv_addr->state == RECV_NOT_PROCESSED) { if (!has_printed) { fprintf(stderr, -"InnoDB: Starting an apply batch of log records to the database...\n"); +"InnoDB: Starting an apply batch of log records to the database...\n" +"InnoDB: Progress in percents:"); has_printed = TRUE; } @@ -1046,6 +1047,16 @@ loop: recv_addr = HASH_GET_NEXT(addr_hash, recv_addr); } + + if (has_printed + && (i * 100) / hash_get_n_cells(recv_sys->addr_hash) + != ((i + 1) * 100) + / hash_get_n_cells(recv_sys->addr_hash)) { + + fprintf(stderr, "%lu ", + (i * 100) / hash_get_n_cells(recv_sys->addr_hash)); + + } } /* Wait until all the pages have been processed */ @@ -1059,6 +1070,11 @@ loop: mutex_enter(&(recv_sys->mutex)); } + if (has_printed) { + + fprintf(stderr, "\n"); + } + if (!allow_ibuf) { /* Flush all the file pages to disk and invalidate them in the buffer pool */ diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 37bf59b6b9a..d77db335366 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -2417,7 +2417,19 @@ loop: background_loop: /* In this loop we run background operations when the server - is quiet */ + is quiet and we also come here about once in 10 seconds */ + + srv_main_thread_op_info = "flushing buffer pool pages"; + + /* Flush a few oldest pages to make the checkpoint younger */ + + n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST, 10, ut_dulint_max); + + srv_main_thread_op_info = "making checkpoint"; + + /* Make a new checkpoint about once in 10 seconds */ + + log_checkpoint(TRUE, FALSE); srv_main_thread_op_info = "reserving kernel mutex"; From 3fef3c7e5bdc5012fb0f611abf3932f3879bea56 Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Tue, 25 Dec 2001 23:44:41 +0200 Subject: [PATCH 04/15] mysqld.cc: Changed default of file_io_threads to 4 and lock_wait_timeout to 50 seconds Added a missing break: if not specified, innodb_fast_shutdown got the same value as ..flush_log_at_trx commit --- sql/mysqld.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c34f18da1ec..ac1bb3f04be 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2830,9 +2830,9 @@ CHANGEABLE_VAR changeable_vars[] = { (long*) &innobase_additional_mem_pool_size, 1*1024*1024L, 512*1024L, ~0L, 0, 1024}, {"innodb_file_io_threads", - (long*) &innobase_file_io_threads, 9, 4, 64, 0, 1}, + (long*) &innobase_file_io_threads, 4, 4, 64, 0, 1}, {"innodb_lock_wait_timeout", - (long*) &innobase_lock_wait_timeout, 1024 * 1024 * 1024, 1, + (long*) &innobase_lock_wait_timeout, 50, 1, 1024 * 1024 * 1024, 0, 1}, {"innodb_thread_concurrency", (long*) &innobase_thread_concurrency, 8, 1, 1000, 0, 1}, @@ -3935,6 +3935,7 @@ static void get_options(int argc,char **argv) break; case OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT: innobase_flush_log_at_trx_commit= optarg ? test(atoi(optarg)) : 1; + break; case OPT_INNODB_FAST_SHUTDOWN: innobase_fast_shutdown= optarg ? test(atoi(optarg)) : 1; break; From 116ced2f2967a06c520726cfac069afeb2dba14a Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Thu, 27 Dec 2001 00:56:40 +0200 Subject: [PATCH 05/15] os0file.c: Make os_file_flush to ignore the error we get from a raw device in fsync --- innobase/os/os0file.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 9fecf2c04fd..363ed587c4e 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -582,6 +582,13 @@ os_file_flush( return(TRUE); } + /* Since Linux returns EINVAL if the 'file' is actually a raw device, + we choose to ignore that error */ + + if (errno == EINVAL) { + return(TRUE); + } + fprintf(stderr, "InnoDB: Error: the OS said file flush did not succeed\n"); From 2bd8bf31bdc4a0822780bc5a982044dcac4838b3 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Thu, 27 Dec 2001 02:04:27 +0200 Subject: [PATCH 06/15] Bugfix for WHERE key=@a OR key=@b --- Docs/manual.texi | 5 +++++ mysql-test/r/variables.result | 11 ++++++++++ mysql-test/t/variables.test | 13 ++++++++++++ sql/item_func.cc | 38 +++++++++++++++++++++++++++++++++++ sql/item_func.h | 4 ++++ sql/sql_select.cc | 2 +- 6 files changed, 72 insertions(+), 1 deletion(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index f3f3cdec961..101aa22a883 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -46888,6 +46888,11 @@ not yet 100% confident in this code. @appendixsubsec Changes in release 3.23.47 @itemize @bullet @item +Fixed in when using the following construct: +@code{SELECT ... WHERE key=@@var_name OR $key=@@var_name2} +@item +Restrict InnoDB keys to 500 bytes. +@item InnoDB now supports @code{NULL} in keys. @item Fixed shutdown problem on HPUX. (Introduced in 3.23.46) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index f852378e6a1..ab60d5042b0 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -12,3 +12,14 @@ NULL NULL NULL NULL 5 5 1 4 @t5 1.23456 +@min_cid:=min(c_id) @max_cid:=max(c_id) +1 4 +c_id c_name c_country +1 Bozo USA +4 Mr. Floppy GB +c_id c_name c_country +1 Bozo USA +4 Mr. Floppy GB +c_id c_name c_country +1 Bozo USA +4 Mr. Floppy GB diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index d5ff64d199b..0499263467c 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -1,6 +1,7 @@ # # test variables # +drop table if exists t1; set @`test`=1,@TEST=3,@select=2,@t5=1.23456; select @test,@`select`,@TEST,@not_used; set @test_int=10,@test_double=1e-10,@test_string="abcdeghi",@test_string2="abcdefghij",@select=NULL; @@ -14,3 +15,15 @@ select @test_int,@test_double,@test_string,@test_string2; select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3; select @t5; +# +# Test problem with WHERE and variables +# + +CREATE TABLE t1 (c_id INT(4) NOT NULL, c_name CHAR(20), c_country CHAR(3), PRIMARY KEY(c_id)); +INSERT INTO t1 VALUES (1,'Bozo','USA'),(2,'Ronald','USA'),(3,'Kinko','IRE'),(4,'Mr. Floppy','GB'); +SELECT @min_cid:=min(c_id), @max_cid:=max(c_id) from t1; +SELECT * FROM t1 WHERE c_id=@min_cid OR c_id=@max_cid; +SELECT * FROM t1 WHERE c_id=@min_cid OR c_id=@max_cid OR c_id=666; +ALTER TABLE t1 DROP PRIMARY KEY; +select * from t1 where c_id=@min_cid OR c_id=@max_cid; +drop table t1; diff --git a/sql/item_func.cc b/sql/item_func.cc index 94464bdc594..e7e8964b07a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1772,6 +1772,16 @@ Item_func_set_user_var::val_str(String *str) } +void Item_func_set_user_var::print(String *str) +{ + str->append('('); + str->append(name.str,name.length); + str->append(":=",2); + args[0]->print(str); + str->append(')'); +} + + user_var_entry *Item_func_get_user_var::get_entry() { if (!entry || ! entry->value) @@ -1864,6 +1874,34 @@ enum Item_result Item_func_get_user_var::result_type() const return entry->type; } + +void Item_func_get_user_var::print(String *str) +{ + str->append('@'); + str->append(name.str,name.length); + str->append(')'); +} + +bool Item_func_get_user_var::eq(const Item *item) const +{ + /* Assume we don't have rtti */ + if (this == item) + return 1; // Same item is same. + /* Check if other type is also a get_user_var() object */ +#ifdef FIX_THIS + if (item->eq == &Item_func_get_user_var::eq) + return 0; +#else + if (item->type() != FUNC_ITEM || + ((Item_func*) item)->func_name() != func_name()) + return 0; +#endif + Item_func_get_user_var *other=(Item_func_get_user_var*) item; + return (name.length == other->name.length && + !memcmp(name.str, other->name.str, name.length)); +} + + longlong Item_func_inet_aton::val_int() { uint byte_result = 0; diff --git a/sql/item_func.h b/sql/item_func.h index ac4c230f312..4a8f808de57 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -817,6 +817,7 @@ public: enum Item_result result_type () const { return cached_result_type; } bool fix_fields(THD *thd,struct st_table_list *tables); void fix_length_and_dec(); + void print(String *str); const char *func_name() const { return "set_user_var"; } }; @@ -835,13 +836,16 @@ public: longlong val_int(); String *val_str(String* str); void fix_length_and_dec(); + void print(String *str); enum Item_result result_type() const; const char *func_name() const { return "get_user_var"; } bool const_item() const { return const_var_flag; } table_map used_tables() const { return const_var_flag ? 0 : RAND_TABLE_BIT; } + bool eq(const Item *item) const; }; + class Item_func_inet_aton : public Item_int_func { public: diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 330df610b46..9ff64780bdd 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -35,7 +35,7 @@ const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref", "MAYBE_REF","ALL","range","index","fulltext" }; static bool make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, - DYNAMIC_ARRAY *keyuse); + DYNAMIC_ARRAY *keyuse); static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse, JOIN_TAB *join_tab, uint tables,COND *conds,table_map table_map); From ac8155cce1e015494773bf9e4da469233dddb7f2 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Thu, 27 Dec 2001 13:31:10 +0200 Subject: [PATCH 07/15] Portability fixes --- include/global.h | 5 +++++ sql/mysqld.cc | 1 + 2 files changed, 6 insertions(+) diff --git a/include/global.h b/include/global.h index c7d6952f1c6..857c66d3640 100644 --- a/include/global.h +++ b/include/global.h @@ -211,6 +211,11 @@ #ifdef DONT_USE_FINITE /* HPUX 11.x has is_finite() */ #undef HAVE_FINITE #endif +#if defined(HPUX) && defined(_LARGEFILE64_SOURCE) && defined(THREAD) +/* Fix bug in setrlimit */ +#undef setrlimit +#define setrlimit cma_setrlimit64 +#endif /* We can not live without these */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ac1bb3f04be..be20c5fa964 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -377,6 +377,7 @@ static void get_options(int argc,char **argv); static char *get_relative_path(const char *path); static void fix_paths(void); static pthread_handler_decl(handle_connections_sockets,arg); +static pthread_handler_decl(kill_server_thread,arg); static int bootstrap(FILE *file); static bool read_init_file(char *file_name); #ifdef __NT__ From 43f2238c725ddc37100a24f4ae911656c7628929 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Thu, 27 Dec 2001 15:16:08 +0200 Subject: [PATCH 08/15] Portability fix for SCO --- extra/resolveip.c | 49 ++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/extra/resolveip.c b/extra/resolveip.c index 4856bead200..2d21d5c672c 100644 --- a/extra/resolveip.c +++ b/extra/resolveip.c @@ -1,30 +1,28 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, +/* Copyright (C) 2000 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA */ + 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 */ /* Resolves IP's to hostname and hostnames to IP's */ #define RESOLVE_VERSION "2.0" - -#include + +#include #include +#include #include -#ifndef SCO #include -#endif #include #include #ifndef HAVE_BROKEN_NETINET_INCLUDES @@ -34,10 +32,16 @@ #include #include +#ifdef SCO +#undef h_errno +#define h_errno errno +#endif + #if !defined(_AIX) && !defined(HAVE_UNIXWARE7_THREADS) && !defined(HAVE_UNIXWARE7_POSIX) && !defined(h_errno) extern int h_errno; #endif + static int silent=0; static struct option long_options[] = @@ -54,7 +58,7 @@ static void print_version(void) { printf("%s Ver %s, for %s (%s)\n",my_progname,RESOLVE_VERSION, SYSTEM_TYPE,MACHINE_TYPE); -} +} static void usage(void) @@ -140,7 +144,7 @@ int main(int argc, char **argv) puts("Old-Bcast"); continue; } - + hpaddr = gethostbyaddr((char*) &(taddr), sizeof(struct in_addr),AF_INET); if (hpaddr) { @@ -202,6 +206,3 @@ int main(int argc, char **argv) } exit(error); } - - - From 8c8d5c06aacdbb67fea59e329fc1cd5a7e5c05fb Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Thu, 27 Dec 2001 18:43:49 +0200 Subject: [PATCH 09/15] btr0sea.c: Eliminate a gcc compiler bug in inlining --- innobase/btr/btr0sea.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c index 31ef8ce573b..ca8589813ca 100644 --- a/innobase/btr/btr0sea.c +++ b/innobase/btr/btr0sea.c @@ -452,7 +452,7 @@ btr_search_info_update_slow( Checks if a guessed position for a tree cursor is right. Note that if mode is PAGE_CUR_LE, which is used in inserts, and the function returns TRUE, then cursor->up_match and cursor->low_match both have sensible values. */ -UNIV_INLINE +static ibool btr_search_check_guess( /*===================*/ From e4a3e38101aebf5bc64a25877196b7e4abb9b7aa Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Thu, 27 Dec 2001 20:17:49 +0200 Subject: [PATCH 10/15] manual.texi: Make InnoDB startup option samples easier to understand, recommend not setting log files too big, because recovery slow --- Docs/manual.texi | 80 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 21 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index f3f3cdec961..16dc3e9a87f 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -36313,23 +36313,37 @@ the configuration file @file{my.cnf}. @xref{Option files}. The only required parameter to use InnoDB is @code{innodb_data_file_path}, but you should set others if you want to get a better performance. -Suppose you have a Windows NT machine with 128 MB RAM and a single 10 GB +Suppose you have a Windows NT computer with 128 MB RAM and a single 10 GB hard disk. Below is an example of possible configuration parameters in @file{my.cnf} for InnoDB: @example -innodb_data_file_path = ibdata1:2000M;ibdata2:2000M +[mysqld] +# You can write your other MySQL server options here +# ... +# innodb_data_home_dir = c:\ibdata -set-variable = innodb_mirrored_log_groups=1 +# Data files must be able to +# hold your data and indexes +innodb_data_file_path = ibdata1:2000M;ibdata2:2000M +# Set buffer pool size to 50 - 80 % +# of your computer's memory +set-variable = innodb_buffer_pool_size=70M +set-variable = innodb_additional_mem_pool_size=10M innodb_log_group_home_dir = c:\iblogs -set-variable = innodb_log_files_in_group=3 -set-variable = innodb_log_file_size=30M -set-variable = innodb_log_buffer_size=8M -innodb_flush_log_at_trx_commit=1 +# .._log_arch_dir must be the same +# as .._log_group_home_dir innodb_log_arch_dir = c:\iblogs innodb_log_archive=0 -set-variable = innodb_buffer_pool_size=80M -set-variable = innodb_additional_mem_pool_size=10M +set-variable = innodb_log_files_in_group=3 +# Set the log file size to about +# 15 % of the buffer pool size +set-variable = innodb_log_file_size=10M +set-variable = innodb_log_buffer_size=8M +# Set ..flush_log_at_trx_commit to +# 0 if you can afford losing +# a few last transactions +innodb_flush_log_at_trx_commit=1 set-variable = innodb_file_io_threads=4 set-variable = innodb_lock_wait_timeout=50 @end example @@ -36340,27 +36354,44 @@ to be >= 10 MB. InnoDB does not create directories: you have to create them yourself. -Suppose you have a Linux machine with 512 MB RAM and +Suppose you have a Linux computer with 512 MB RAM and three 20 GB hard disks (at directory paths @file{/}, @file{/dr2} and @file{/dr3}). Below is an example of possible configuration parameters in @file{my.cnf} for InnoDB: @example -innodb_data_file_path = ibdata/ibdata1:2000M;dr2/ibdata/ibdata2:2000M +[mysqld] +# You can write your other MySQL server options here +# ... +# innodb_data_home_dir = / -set-variable = innodb_mirrored_log_groups=1 -innodb_log_group_home_dir = /dr3 -set-variable = innodb_log_files_in_group=3 -set-variable = innodb_log_file_size=50M -set-variable = innodb_log_buffer_size=8M -innodb_flush_log_at_trx_commit=1 +# Data files must be able to +# hold your data and indexes +innodb_data_file_path = ibdata/ibdata1:2000M;dr2/ibdata/ibdata2:2000M +# Set buffer pool size to 50 - 80 % +# of your computer's memory +set-variable = innodb_buffer_pool_size=350M +set-variable = innodb_additional_mem_pool_size=20M +innodb_log_group_home_dir = /dr3/iblogs +# .._log_arch_dir must be the same +# as .._log_group_home_dir innodb_log_arch_dir = /dr3/iblogs innodb_log_archive=0 -set-variable = innodb_buffer_pool_size=400M -set-variable = innodb_additional_mem_pool_size=20M +set-variable = innodb_log_files_in_group=3 +# Set the log file size to about +# 15 % of the buffer pool size +set-variable = innodb_log_file_size=50M +set-variable = innodb_log_buffer_size=8M +# Set ..flush_log_at_trx_commit to +# 0 if you can afford losing +# a few last transactions +innodb_flush_log_at_trx_commit=1 set-variable = innodb_file_io_threads=4 set-variable = innodb_lock_wait_timeout=50 +#innodb_flush_method=fdatasync +#innodb_fast_shutdown=1 +#set-variable = innodb_thread_concurrency=5 @end example Note that we have placed the two data files on different disks. @@ -36374,6 +36405,10 @@ improve the performance of the database if all data is not placed on the same physical disk. Putting log files on a different disk from data is very often beneficial for performance. +The combined size of the log files MUST be < 4G in a 32-bit computer, +and to make recovery reasonably fast you should keep the combined size +smaller than the buffer pool size. + The meanings of the configuration parameters are the following: @multitable @columnfractions .30 .70 @@ -36397,7 +36432,9 @@ Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here. @item @code{innodb_log_file_size} @tab Size of each log file in a log group in megabytes. Sensible values range -from 1M to the size of the buffer pool specified below. The bigger the +from 1M to 1/nth of the size of the buffer pool specified below, where +n is the number of log files in the log group. +The bigger the value, the less checkpoint flush activity is needed in the buffer pool, saving disk i/o. But bigger log files also mean that recovery will be slower in case of a crash. File size restriction as for a data file. @@ -37100,7 +37137,8 @@ to zero. InnoDB tries to flush the log anyway once in a second, though the flush is not guaranteed. @strong{4.} -Make your log files big, even as big as the buffer pool. When InnoDB +Make your log files big, the combined size +even as big as the buffer pool. When InnoDB has written the log files full, it has to write the modified contents of the buffer pool to disk in a checkpoint. Small log files will cause many unnecessary disk writes. The drawback in big log files is that recovery From d4a8e8d61ebaff11b5ffb02571763e98d91f3e67 Mon Sep 17 00:00:00 2001 From: "miguel@light.local" <> Date: Sun, 30 Dec 2001 00:22:01 -0200 Subject: [PATCH 11/15] Minors changes for the Windows 3.23.47 release --- mysys/my_bitmap.c | 1 + sql/sql_do.cc | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c index 6bab35eabb1..a18fcba0b60 100644 --- a/mysys/my_bitmap.c +++ b/mysys/my_bitmap.c @@ -27,6 +27,7 @@ #include #include #include +#include inline void bitmap_lock(MY_BITMAP* map) { diff --git a/sql/sql_do.cc b/sql/sql_do.cc index 8e197b47fd5..57a6f88ed63 100644 --- a/sql/sql_do.cc +++ b/sql/sql_do.cc @@ -22,7 +22,6 @@ int mysql_do(THD *thd, List &values) { - int error; List_iterator li(values); Item *value; DBUG_ENTER("mysql_do"); From 410847fac6c1413d744895055168358cbd963474 Mon Sep 17 00:00:00 2001 From: "heikki@donna.mysql.fi" <> Date: Mon, 31 Dec 2001 14:41:58 +0200 Subject: [PATCH 12/15] row0mysql.c: Remove erroneous warning of a duplicate key when the key in a UNIQUE secondary index contains a NULL --- innobase/row/row0mysql.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 58bddcfd24a..9622a7cee32 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1678,6 +1678,8 @@ row_scan_and_check_index( rec_t* rec; ibool is_ok = TRUE; int cmp; + ibool contains_null; + ulint i; char err_buf[1000]; *n_rows = 0; @@ -1723,6 +1725,21 @@ loop: cmp = cmp_dtuple_rec_with_match(prev_entry, rec, &matched_fields, &matched_bytes); + contains_null = FALSE; + + /* In a unique secondary index we allow equal key values if + they contain SQL NULLs */ + + for (i = 0; + i < dict_index_get_n_ordering_defined_by_user(index); + i++) { + if (UNIV_SQL_NULL == dfield_get_len( + dtuple_get_nth_field(prev_entry, i))) { + + contains_null = TRUE; + } + } + if (cmp > 0) { fprintf(stderr, "Error: index records in a wrong order in index %s\n", @@ -1736,6 +1753,7 @@ loop: is_ok = FALSE; } else if ((index->type & DICT_UNIQUE) + && !contains_null && matched_fields >= dict_index_get_n_ordering_defined_by_user(index)) { From cb8bb9a84c17ed91b9b26719a6984606d55a35c0 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Wed, 2 Jan 2002 13:50:31 +0200 Subject: [PATCH 13/15] Backport of mysqldump from 4.0 --- Docs/manual.texi | 4 +- client/client_priv.h | 3 +- client/mysqldump.c | 367 +++++++++++++++++++++++++++++-------------- include/global.h | 4 +- 4 files changed, 254 insertions(+), 124 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 101aa22a883..479eeb7dc69 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -46897,11 +46897,9 @@ InnoDB now supports @code{NULL} in keys. @item Fixed shutdown problem on HPUX. (Introduced in 3.23.46) @item -Added 'DO expression' command. -@item Fixed core-dump bug in replication when using SELECT RELEASE_LOCK(); @item -Added new statement DO expression,[expression]. +Added new command: @code{DO expression,[expression]} @item Added @code{slave-skip-errors} option @item diff --git a/client/client_priv.h b/client/client_priv.h index 377d42763a2..261367f7176 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -29,4 +29,5 @@ enum options { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, OPT_PAGER, OPT_NOPAGER, OPT_TEE, OPT_NOTEE, OPT_LOW_PRIORITY, OPT_AUTO_REPAIR, OPT_COMPRESS, OPT_DROP, OPT_LOCKS, OPT_KEYWORDS, OPT_DELAYED, OPT_OPTIMIZE, - OPT_FTB, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_TABLES}; + OPT_FTB, OPT_LTB, OPT_ENC, OPT_O_ENC, OPT_ESC, OPT_TABLES, + OPT_MASTER_DATA, OPT_AUTOCOMMIT}; diff --git a/client/mysqldump.c b/client/mysqldump.c index 12e08669864..ed5749c88a6 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,28 +18,26 @@ ** ** The author's original notes follow :- ** -** ****************************************************** -** * * -** * AUTHOR: Igor Romanenko (igor@frog.kiev.ua) * -** * DATE: December 3, 1994 * -** * WARRANTY: None, expressed, impressed, implied * -** * or other * -** * STATUS: Public domain * -** * Adapted and optimized for MySQL by * -** * Michael Widenius, Sinisa Milivojevic, Jani Tolonen * -** * -w --where added 9/10/98 by Jim Faucette * -** * slave code by David Saez Padros * -** * * -** ****************************************************** +** AUTHOR: Igor Romanenko (igor@frog.kiev.ua) +** DATE: December 3, 1994 +** WARRANTY: None, expressed, impressed, implied +** or other +** STATUS: Public domain +** Adapted and optimized for MySQL by +** Michael Widenius, Sinisa Milivojevic, Jani Tolonen +** -w --where added 9/10/98 by Jim Faucette +** slave code by David Saez Padros +** master/autocommit code by Brian Aker +** SSL by +** Andrei Errapart +** Tõnu Samuel +** XML by Gary Huntress 10/10/01, cleaned up +** and adapted to mysqldump 05/11/01 by Jani Tolonen */ -/* SSL by -** Andrei Errapart -** Tõnu Samuel -**/ -#define DUMP_VERSION "8.16" +#define DUMP_VERSION "8.20" -#include +#include #include #include #include @@ -74,7 +72,8 @@ static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick=0, extended_insert = 0, lock_tables=0,ignore_errors=0,flush_logs=0,replace=0, ignore=0,opt_drop=0,opt_keywords=0,opt_lock=0,opt_compress=0, opt_delayed=0,create_options=0,opt_quoted=0,opt_databases=0, - opt_alldbs=0,opt_create_db=0,opt_first_slave=0; + opt_alldbs=0,opt_create_db=0,opt_first_slave=0, + opt_autocommit=0,opt_master_data,opt_disable_keys=0,opt_xml=0; static MYSQL mysql_connection,*sock=0; static char insert_pat[12 * 1024],*opt_password=0,*current_user=0, *current_host=0,*path=0,*fields_terminated=0, @@ -91,52 +90,56 @@ FILE *md_result_file; static struct option long_options[] = { {"all-databases", no_argument, 0, 'A'}, - {"all", no_argument, 0, 'a'}, - {"add-drop-table", no_argument, 0, OPT_DROP}, - {"add-locks", no_argument, 0, OPT_LOCKS}, - {"allow-keywords", no_argument, 0, OPT_KEYWORDS}, + {"all", no_argument, 0, 'a'}, + {"add-drop-table", no_argument, 0, OPT_DROP}, + {"add-locks", no_argument, 0, OPT_LOCKS}, + {"allow-keywords", no_argument, 0, OPT_KEYWORDS}, {"character-sets-dir",required_argument,0, OPT_CHARSETS_DIR}, - {"complete-insert", no_argument, 0, 'c'}, - {"compress", no_argument, 0, 'C'}, + {"complete-insert", no_argument, 0, 'c'}, + {"compress", no_argument, 0, 'C'}, {"databases", no_argument, 0, 'B'}, - {"debug", optional_argument, 0, '#'}, + {"debug", optional_argument, 0, '#'}, {"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET}, - {"delayed-insert", no_argument, 0, OPT_DELAYED}, - {"extended-insert", no_argument, 0, 'e'}, + {"delayed-insert", no_argument, 0, OPT_DELAYED}, + {"disable-keys", no_argument, 0, 'K'}, + {"extended-insert", no_argument, 0, 'e'}, {"fields-terminated-by", required_argument, 0, (int) OPT_FTB}, {"fields-enclosed-by", required_argument, 0, (int) OPT_ENC}, {"fields-optionally-enclosed-by", required_argument, 0, (int) OPT_O_ENC}, {"fields-escaped-by", required_argument, 0, (int) OPT_ESC}, {"first-slave", no_argument, 0, 'x'}, {"flush-logs", no_argument, 0, 'F'}, - {"force", no_argument, 0, 'f'}, - {"help", no_argument, 0, '?'}, - {"host", required_argument, 0, 'h'}, + {"force", no_argument, 0, 'f'}, + {"help", no_argument, 0, '?'}, + {"host", required_argument, 0, 'h'}, {"lines-terminated-by", required_argument, 0, (int) OPT_LTB}, - {"lock-tables", no_argument, 0, 'l'}, + {"lock-tables", no_argument, 0, 'l'}, + {"master-data", no_argument, 0, OPT_MASTER_DATA}, + {"no-autocommit", no_argument, 0, OPT_AUTOCOMMIT}, {"no-create-db", no_argument, 0, 'n'}, - {"no-create-info", no_argument, 0, 't'}, - {"no-data", no_argument, 0, 'd'}, - {"opt", no_argument, 0, OPT_OPTIMIZE}, - {"password", optional_argument, 0, 'p'}, + {"no-create-info", no_argument, 0, 't'}, + {"no-data", no_argument, 0, 'd'}, + {"opt", no_argument, 0, OPT_OPTIMIZE}, + {"password", optional_argument, 0, 'p'}, #ifdef __WIN__ - {"pipe", no_argument, 0, 'W'}, + {"pipe", no_argument, 0, 'W'}, #endif - {"port", required_argument, 0, 'P'}, - {"quick", no_argument, 0, 'q'}, + {"port", required_argument, 0, 'P'}, + {"quick", no_argument, 0, 'q'}, {"quote-names", no_argument, 0, 'Q'}, {"result-file", required_argument, 0, 'r'}, {"set-variable", required_argument, 0, 'O'}, - {"socket", required_argument, 0, 'S'}, + {"socket", required_argument, 0, 'S'}, #include "sslopt-longopts.h" - {"tab", required_argument, 0, 'T'}, + {"tab", required_argument, 0, 'T'}, {"tables", no_argument, 0, OPT_TABLES}, #ifndef DONT_ALLOW_USER_CHANGE - {"user", required_argument, 0, 'u'}, + {"user", required_argument, 0, 'u'}, #endif - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {"where", required_argument, 0, 'w'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"where", required_argument, 0, 'w'}, + {"xml", no_argument, 0, 'X'}, {0, 0, 0, 0} }; @@ -151,7 +154,7 @@ CHANGEABLE_VAR md_changeable_vars[] = { }; static void safe_exit(int error); -static void write_heder(FILE *sql_file, char *db_name); +static void write_header(FILE *sql_file, char *db_name); static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row, const char *prefix,const char *name, int string_value); @@ -161,6 +164,7 @@ static int init_dumping(char *); static int dump_databases(char **); static int dump_all_databases(); static char *quote_name(char *name, char *buff); +static void print_quoted_xml(FILE *output, char *fname, char *str, uint len); static void print_version(void) { @@ -202,11 +206,18 @@ static void usage(void) --add-locks Add locks around insert statements.\n\ --allow-keywords Allow creation of column names that are keywords.\n\ --delayed-insert Insert rows with INSERT DELAYED.\n\ + --master-data This will cause the master position and filename to \n\ + be appended to your output. This will automagically \n\ + enable --first-slave.\n\ -F, --flush-logs Flush logs file in server before starting dump.\n\ -f, --force Continue even if we get an sql-error.\n\ -h, --host=... Connect to host.\n"); puts("\ -l, --lock-tables Lock all tables for read.\n\ + --no-autocommit Wrap tables with autocommit/commit statements.\n\ + -K, --disable-keys '/*!40000 ALTER TABLE tb_name DISABLE KEYS */;\n\ + and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */;\n\ + will be put in the output.\n\ -n, --no-create-db 'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;'\n\ will not be put in the output. The above line will\n\ be added otherwise, if --databases or\n\ @@ -215,12 +226,12 @@ puts("\ -d, --no-data No row information.\n\ -O, --set-variable var=option\n\ give a variable a value. --help lists variables\n\ - --opt Same as --add-drop-table --add-locks --all\n\ - --extended-insert --quick --lock-tables\n\ + --opt Same as --add-drop-table --add-locks --all --quick\n\ + --extended-insert --lock-tables --disable-keys\n\ -p, --password[=...] Password to use when connecting to server.\n\ If password is not given it's solicited on the tty.\n"); #ifdef __WIN__ - puts("-W, --pipe Use named pipes to connect to server"); + puts("-W, --pipe Use named pipes to connect to server"); #endif printf("\ -P, --port=... Port number to use for connection.\n\ @@ -246,6 +257,8 @@ puts("\ -v, --verbose Print info about the various stages.\n\ -V, --version Output version information and exit.\n\ -w, --where= dump only selected records; QUOTES mandatory!\n\ + -X, --xml dump a database as well formed XML\n\ + -x, --first-slave Locks all tables across all databases.\n\ EXAMPLES: \"--where=user=\'jimf\'\" \"-wuserid>1\" \"-wuserid<1\"\n\ Use -T (--tab=...) with --fields-...\n\ --fields-terminated-by=...\n\ @@ -269,17 +282,22 @@ puts("\ } /* usage */ -static void write_heder(FILE *sql_file, char *db_name) +static void write_header(FILE *sql_file, char *db_name) { - fprintf(sql_file, "# MySQL dump %s\n#\n", DUMP_VERSION); - fprintf(sql_file, "# Host: %s Database: %s\n", - current_host ? current_host : "localhost", db_name ? db_name : ""); - fputs("#--------------------------------------------------------\n", - sql_file); - fprintf(sql_file, "# Server version\t%s\n", - mysql_get_server_info(&mysql_connection)); + if (opt_xml) + fprintf(sql_file,"\n"); + else + { + fprintf(sql_file, "-- MySQL dump %s\n--\n", DUMP_VERSION); + fprintf(sql_file, "-- Host: %s Database: %s\n", + current_host ? current_host : "localhost", db_name ? db_name : ""); + fputs("---------------------------------------------------------\n", + sql_file); + fprintf(sql_file, "-- Server version\t%s\n", + mysql_get_server_info(&mysql_connection)); + } return; -} /* write_heder */ +} /* write_header */ static int get_options(int *argc,char ***argv) @@ -291,10 +309,17 @@ static int get_options(int *argc,char ***argv) load_defaults("my",load_default_groups,argc,argv); set_all_changeable_vars(md_changeable_vars); while ((c=getopt_long(*argc,*argv, - "#::p::h:u:O:P:r:S:T:EBaAcCdefFlnqtvVw:?Ix", + "#::p::h:u:O:P:r:S:T:EBaAcCdefFKlnqtvVw:?IxX", long_options, &option_index)) != EOF) { switch(c) { + case OPT_MASTER_DATA: + opt_master_data=1; + opt_first_slave=1; + break; + case OPT_AUTOCOMMIT: + opt_autocommit=1; + break; case 'a': create_options=1; break; @@ -320,6 +345,9 @@ static int get_options(int *argc,char ***argv) my_free(current_host,MYF(MY_ALLOW_ZERO_PTR)); current_host=my_strdup(optarg,MYF(MY_WME)); break; + case 'K': + opt_disable_keys=1; + break; case 'n': opt_create_db = 1; break; @@ -366,6 +394,7 @@ static int get_options(int *argc,char ***argv) break; case 'T': path= optarg; + opt_disable_keys=0; break; case 'B': opt_databases = 1; @@ -387,6 +416,10 @@ static int get_options(int *argc,char ***argv) case 'w': where=optarg; break; + case 'X': + opt_xml = 1; + opt_disable_keys=0; + break; case 'x': opt_first_slave=1; break; @@ -422,7 +455,8 @@ static int get_options(int *argc,char ***argv) opt_lock=1; break; case (int) OPT_OPTIMIZE: - extended_insert=opt_drop=opt_lock=lock_tables=quick=create_options=1; + extended_insert=opt_drop=opt_lock=lock_tables=quick=create_options= + opt_disable_keys=1; break; case (int) OPT_DELAYED: opt_delayed=1; @@ -512,7 +546,7 @@ static int dbConnect(char *host, char *user,char *passwd) DBUG_ENTER("dbConnect"); if (verbose) { - fprintf(stderr, "# Connecting to %s...\n", host ? host : "localhost"); + fprintf(stderr, "-- Connecting to %s...\n", host ? host : "localhost"); } mysql_init(&mysql_connection); if (opt_compress) @@ -520,7 +554,7 @@ static int dbConnect(char *host, char *user,char *passwd) #ifdef HAVE_OPENSSL if (opt_use_ssl) mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, - opt_ssl_capath); + opt_ssl_capath, opt_ssl_cipher); #endif if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd, NULL,opt_mysql_port,opt_mysql_unix_port, @@ -539,7 +573,7 @@ static int dbConnect(char *host, char *user,char *passwd) static void dbDisconnect(char *host) { if (verbose) - fprintf(stderr, "# Disconnecting from %s...\n", host ? host : "localhost"); + fprintf(stderr, "-- Disconnecting from %s...\n", host ? host : "localhost"); mysql_close(sock); } /* dbDisconnect */ @@ -553,7 +587,7 @@ static void unescape(FILE *file,char *pos,uint length) ignore_errors=0; /* Fatal error */ safe_exit(EX_MYSQLERR); /* Force exit */ } - mysql_real_escape_string(&mysql_connection,tmp, pos, length); + mysql_real_escape_string(&mysql_connection, tmp, pos, length); fputc('\'', file); fputs(tmp, file); fputc('\'', file); @@ -596,16 +630,16 @@ static uint getTableStructure(char *table, char* db) MYSQL_ROW row; my_bool init=0; uint numFields; - char *strpos, *table_name; + char *strpos, *table_name; const char *delayed; - char name_buff[NAME_LEN+3],table_buff[NAME_LEN+3]; + char name_buff[NAME_LEN+3],table_buff[NAME_LEN+3]; FILE *sql_file = md_result_file; DBUG_ENTER("getTableStructure"); delayed= opt_delayed ? " DELAYED " : ""; if (verbose) - fprintf(stderr, "# Retrieving table structure for table %s...\n", table); + fprintf(stderr, "-- Retrieving table structure for table %s...\n", table); sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", opt_quoted); table_name=quote_name(table,table_buff); @@ -621,7 +655,7 @@ static uint getTableStructure(char *table, char* db) if (mysql_query(sock, buff)) { fprintf(stderr, "%s: Can't get CREATE TABLE for table '%s' (%s)\n", - my_progname, table, mysql_error(sock)); + my_progname, table, mysql_error(sock)); safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } @@ -629,31 +663,36 @@ static uint getTableStructure(char *table, char* db) if (path) { char filename[FN_REFLEN], tmp_path[FN_REFLEN]; - strmov(tmp_path,path); + strmov(tmp_path,path); convert_dirname(tmp_path); sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4), - O_WRONLY, MYF(MY_WME)); + O_WRONLY, MYF(MY_WME)); if (!sql_file) /* If file couldn't be opened */ { safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } - write_heder(sql_file, db); + write_header(sql_file, db); } - fprintf(sql_file, "\n#\n# Table structure for table '%s'\n#\n\n", table); + if (!opt_xml) + fprintf(sql_file, "\n--\n-- Table structure for table '%s'\n--\n\n", + table); if (opt_drop) fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",table_name); tableRes=mysql_store_result(sock); row=mysql_fetch_row(tableRes); - fprintf(sql_file, "%s;\n", row[1]); + if (!opt_xml) + fprintf(sql_file, "%s;\n", row[1]); mysql_free_result(tableRes); } sprintf(insert_pat,"show fields from %s",table_name); if (mysql_query(sock,insert_pat) || !(tableRes=mysql_store_result(sock))) { fprintf(stderr, "%s: Can't get info about table: '%s'\nerror: %s\n", - my_progname, table, mysql_error(sock)); + my_progname, table, mysql_error(sock)); + if (path) + my_fclose(sql_file, MYF(MY_WME)); safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } @@ -702,18 +741,20 @@ static uint getTableStructure(char *table, char* db) if (path) { char filename[FN_REFLEN], tmp_path[FN_REFLEN]; - strmov(tmp_path,path); + strmov(tmp_path,path); convert_dirname(tmp_path); sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4), O_WRONLY, MYF(MY_WME)); if (!sql_file) /* If file couldn't be opened */ { - safe_exit(EX_MYSQLERR); - DBUG_RETURN(0); + safe_exit(EX_MYSQLERR); + DBUG_RETURN(0); } - write_heder(sql_file, db); + write_header(sql_file, db); } - fprintf(sql_file, "\n#\n# Table structure for table '%s'\n#\n\n", table); + if (!opt_xml) + fprintf(sql_file, "\n--\n-- Table structure for table '%s'\n--\n\n", + table); if (opt_drop) fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",table_name); fprintf(sql_file, "CREATE TABLE %s (\n", table_name); @@ -752,7 +793,7 @@ static uint getTableStructure(char *table, char* db) if (row[SHOW_DEFAULT]) { fputs(" DEFAULT ", sql_file); - unescape(sql_file,row[SHOW_DEFAULT],lengths[SHOW_DEFAULT]); + unescape(sql_file, row[SHOW_DEFAULT], lengths[SHOW_DEFAULT]); } if (!row[SHOW_NULL][0]) fputs(" NOT NULL", sql_file); @@ -772,7 +813,7 @@ static uint getTableStructure(char *table, char* db) { fprintf(stderr, "%s: Can't get keys for table '%s' (%s)\n", my_progname, table, mysql_error(sock)); - if (sql_file != stdout) + if (path) my_fclose(sql_file, MYF(MY_WME)); safe_exit(EX_MYSQLERR); DBUG_RETURN(0); @@ -834,7 +875,7 @@ static uint getTableStructure(char *table, char* db) { /* If old MySQL version */ if (verbose) fprintf(stderr, - "# Warning: Couldn't get status information for table '%s' (%s)\n", + "-- Warning: Couldn't get status information for table '%s' (%s)\n", table,mysql_error(sock)); } } @@ -858,12 +899,16 @@ static uint getTableStructure(char *table, char* db) fputs(";\n", sql_file); } } + if (opt_disable_keys) + fprintf(sql_file,"\n/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",table_name); if (cFlag) { strpos=strmov(strpos,") VALUES "); if (!extended_insert) strpos=strmov(strpos,"("); } + if (sql_file != md_result_file) + my_fclose(sql_file, MYF(MY_WME)); DBUG_RETURN(numFields); } /* getTableStructure */ @@ -931,11 +976,11 @@ static void dumpTable(uint numFields, char *table) ulong rownr, row_break, total_length, init_length; if (verbose) - fprintf(stderr, "# Sending SELECT query...\n"); + fprintf(stderr, "-- Sending SELECT query...\n"); if (path) { char filename[FN_REFLEN], tmp_path[FN_REFLEN]; - strmov(tmp_path, path); + strmov(tmp_path,path); convert_dirname(tmp_path); my_load_path(tmp_path, tmp_path, NULL); fn_format(filename, table, tmp_path, ".txt", 4); @@ -958,7 +1003,7 @@ static void dumpTable(uint numFields, char *table) end= add_load_option(end, lines_terminated, " LINES TERMINATED BY"); *end= '\0'; - sprintf(buff," FROM %s",table); + sprintf(buff," FROM %s",quote_name(table,table_buff)); end= strmov(end,buff); if (where) end= strxmov(end, " WHERE ",where,NullS); @@ -970,15 +1015,18 @@ static void dumpTable(uint numFields, char *table) } else { - fprintf(md_result_file,"\n#\n# Dumping data for table '%s'\n", table); + if (!opt_xml) + fprintf(md_result_file,"\n--\n-- Dumping data for table '%s'\n--\n", + table); sprintf(query, "SELECT * FROM %s", quote_name(table,table_buff)); if (where) { - fprintf(md_result_file,"# WHERE: %s\n",where); + if (!opt_xml) + fprintf(md_result_file,"-- WHERE: %s\n",where); strxmov(strend(query), " WHERE ",where,NullS); } - fputs("#\n\n", md_result_file); - + if (!opt_xml) + fputs("\n\n", md_result_file); if (mysql_query(sock, query)) { DBerror(sock, "when retrieving data from server"); @@ -994,7 +1042,7 @@ static void dumpTable(uint numFields, char *table) return; } if (verbose) - fprintf(stderr, "# Retrieving rows...\n"); + fprintf(stderr, "-- Retrieving rows...\n"); if (mysql_num_fields(res) != numFields) { fprintf(stderr,"%s: Error in field count for table: '%s' ! Aborting.\n", @@ -1011,13 +1059,18 @@ static void dumpTable(uint numFields, char *table) row_break=0; rownr=0; init_length=(uint) strlen(insert_pat)+4; + if (opt_xml) + fprintf(md_result_file, "\t<%s>\n", table); + + if (opt_autocommit) + fprintf(md_result_file, "set autocommit=0;\n"); while ((row=mysql_fetch_row(res))) { uint i; ulong *lengths=mysql_fetch_lengths(res); rownr++; - if (!extended_insert) + if (!extended_insert && !opt_xml) fputs(insert_pat,md_result_file); mysql_field_seek(res,0); @@ -1076,22 +1129,36 @@ static void dumpTable(uint numFields, char *table) } else { - if (i) - fputc(',',md_result_file); + if (i && !opt_xml) + fputc(',', md_result_file); if (row[i]) { if (!IS_NUM_FIELD(field)) - unescape(md_result_file, row[i], lengths[i]); + { + if (opt_xml) + print_quoted_xml(md_result_file, field->name, row[i], + lengths[i]); + else + unescape(md_result_file, row[i], lengths[i]); + } else { /* change any strings ("inf","nan",..) into NULL */ char *ptr = row[i]; - fputs((!isalpha(*ptr)) ? ptr : "NULL", md_result_file); + if (opt_xml) + fprintf(md_result_file, "\t\t<%s>%s\n", + field->name,!isalpha(*ptr) ?ptr: "NULL",field->name); + else + fputs((!isalpha(*ptr)) ? ptr : "NULL", md_result_file); } } else { - fputs("NULL",md_result_file); + if (opt_xml) + fprintf(md_result_file, "\t\t<%s>%s\n", + field->name, "NULL", field->name); + else + fputs("NULL", md_result_file); } } } @@ -1109,18 +1176,26 @@ static void dumpTable(uint numFields, char *table) } else { - if (row_break) + if (row_break && !opt_xml) fputs(";\n", md_result_file); row_break=1; /* This is first row */ - fputs(insert_pat,md_result_file); - fputs(extended_row.str,md_result_file); + + if (!opt_xml) + { + fputs(insert_pat,md_result_file); + fputs(extended_row.str,md_result_file); + } total_length = row_length+init_length; } } - else + else if (!opt_xml) fputs(");\n", md_result_file); } - if (extended_insert && row_break) + + //XML - close table tag and supress regular output + if (opt_xml) + fprintf(md_result_file, "\t\n", table); + else if (extended_insert && row_break) fputs(";\n", md_result_file); /* If not empty table */ fflush(md_result_file); if (mysql_errno(sock)) @@ -1135,13 +1210,39 @@ static void dumpTable(uint numFields, char *table) safe_exit(EX_CONSCHECK); return; } + if (opt_disable_keys) + fprintf(md_result_file,"\n/*!40000 ALTER TABLE %s ENABLE KEYS */;\n", + quote_name(table,table_buff)); if (opt_lock) fputs("UNLOCK TABLES;\n", md_result_file); + if (opt_autocommit) + fprintf(md_result_file, "commit;\n"); mysql_free_result(res); } } /* dumpTable */ +static void print_quoted_xml(FILE *output, char *fname, char *str, uint len) +{ + const char *end; + + fprintf(output, "\t\t<%s>", fname); + for (end = str + len; str != end; str++) + { + if (*str == '<') + fputs("<", output); + else if (*str == '>') + fputs(">", output); + else if (*str == '&') + fputs("&", output); + else if (*str == '\"') + fputs(""", output); + else + fputc(*str, output); + } + fprintf(output, "<%s>\n", fname); +} + static char *getTableName(int reset) { static MYSQL_RES *res = NULL; @@ -1194,8 +1295,13 @@ static int dump_databases(char **db_names) int result=0; for ( ; *db_names ; db_names++) { + //XML edit - add database element + if (opt_xml) + fprintf(md_result_file, "<%s>\n", *db_names); if (dump_all_tables_in_db(*db_names)) result=1; + if (opt_xml) + fprintf(md_result_file, "\n", *db_names); } return result; } /* dump_databases */ @@ -1212,7 +1318,7 @@ static int init_dumping(char *database) { if (opt_databases || opt_alldbs) { - fprintf(md_result_file,"\n#\n# Current Database: %s\n#\n", database); + fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", database); if (!opt_create_db) fprintf(md_result_file,"\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;\n", database); @@ -1240,7 +1346,7 @@ static int dump_all_tables_in_db(char *database) init_dynamic_string(&query, "LOCK TABLES ", 256, 1024); for (numrows=0 ; (table = getTableName(1)) ; numrows++) { - dynstr_append(&query, quote_name(table,table_buff)); + dynstr_append(&query, quote_name(table, table_buff)); dynstr_append(&query, " READ /*!32311 LOCAL */,"); } if (numrows && mysql_real_query(sock, query.str, query.length-1)) @@ -1282,7 +1388,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) init_dynamic_string(&query, "LOCK TABLES ", 256, 1024); for (i=0 ; i < tables ; i++) { - dynstr_append(&query, quote_name(table_names[i],table_buff)); + dynstr_append(&query, quote_name(table_names[i], table_buff)); dynstr_append(&query, " READ /*!32311 LOCAL */,"); } if (mysql_real_query(sock, query.str, query.length-1)) @@ -1338,6 +1444,9 @@ static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row, int main(int argc, char **argv) { + MYSQL_ROW row; + MYSQL_RES *master; + MY_INIT(argv[0]); /* ** Check out the args @@ -1350,19 +1459,19 @@ int main(int argc, char **argv) if (dbConnect(current_host, current_user, opt_password)) exit(EX_MYSQLERR); if (!path) - write_heder(md_result_file, *argv); + write_header(md_result_file, *argv); - if (opt_first_slave) - { - lock_tables=0; /* No other locks needed */ - if (mysql_query(sock, "FLUSH TABLES WITH READ LOCK")) - { - my_printf_error(0, "Error: Couldn't execute 'FLUSH TABLES WITH READ LOCK': %s", - MYF(0), mysql_error(sock)); - my_end(0); - return(first_error); - } - } + if (opt_first_slave) + { + lock_tables=0; /* No other locks needed */ + if (mysql_query(sock, "FLUSH TABLES WITH READ LOCK")) + { + my_printf_error(0, "Error: Couldn't execute 'FLUSH TABLES WITH READ LOCK': %s", + MYF(0), mysql_error(sock)); + my_end(0); + return(first_error); + } + } if (opt_alldbs) dump_all_databases(); /* Only one database and selected table(s) */ @@ -1374,6 +1483,28 @@ int main(int argc, char **argv) if (opt_first_slave) { + if (opt_master_data) + { + if (mysql_query(sock, "SHOW MASTER STATUS") || + !(master = mysql_store_result(sock))) + { + my_printf_error(0, "Error: Couldn't execute 'SHOW MASTER STATUS': %s", + MYF(0), mysql_error(sock)); + } + else + { + row = mysql_fetch_row(master); + if(row[0] && row[1]) { + fprintf(md_result_file, + "\n--\n-- Position to start replication from\n--\n\n"); + fprintf(md_result_file, + "CHANGE MASTER TO MASTER_LOG_FILE='%s' ;\n", row[0]); + fprintf(md_result_file, "CHANGE MASTER TO MASTER_LOG_POS=%s ;\n", + row[1]); + } + mysql_free_result(master); + } + } if (mysql_query(sock, "FLUSH MASTER")) { my_printf_error(0, "Error: Couldn't execute 'FLUSH MASTER': %s", diff --git a/include/global.h b/include/global.h index 857c66d3640..b8b118cd855 100644 --- a/include/global.h +++ b/include/global.h @@ -616,8 +616,8 @@ typedef unsigned long ulong; /* Short for unsigned long */ #endif #ifndef longlong_defined #if defined(HAVE_LONG_LONG) && SIZEOF_LONG != 8 -typedef unsigned long long ulonglong; /* ulong or unsigned long long */ -typedef long long longlong; +typedef unsigned long long int ulonglong; /* ulong or unsigned long long */ +typedef long long int longlong; #else typedef unsigned long ulonglong; /* ulong or unsigned long long */ typedef long longlong; From 89f8ca058e3c548fa23b7a4aeb5662425d3d83b0 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Wed, 2 Jan 2002 14:12:37 +0200 Subject: [PATCH 14/15] Removed Heikki's changes to the manual that was meant for 4.0 --- Docs/manual.texi | 76 ++++++++++++------------------------------------ configure.in | 2 +- 2 files changed, 20 insertions(+), 58 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index c657a75a992..479eeb7dc69 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -36313,37 +36313,23 @@ the configuration file @file{my.cnf}. @xref{Option files}. The only required parameter to use InnoDB is @code{innodb_data_file_path}, but you should set others if you want to get a better performance. -Suppose you have a Windows NT computer with 128 MB RAM and a single 10 GB +Suppose you have a Windows NT machine with 128 MB RAM and a single 10 GB hard disk. Below is an example of possible configuration parameters in @file{my.cnf} for InnoDB: @example -[mysqld] -# You can write your other MySQL server options here -# ... -# -innodb_data_home_dir = c:\ibdata -# Data files must be able to -# hold your data and indexes innodb_data_file_path = ibdata1:2000M;ibdata2:2000M -# Set buffer pool size to 50 - 80 % -# of your computer's memory -set-variable = innodb_buffer_pool_size=70M -set-variable = innodb_additional_mem_pool_size=10M +innodb_data_home_dir = c:\ibdata +set-variable = innodb_mirrored_log_groups=1 innodb_log_group_home_dir = c:\iblogs -# .._log_arch_dir must be the same -# as .._log_group_home_dir +set-variable = innodb_log_files_in_group=3 +set-variable = innodb_log_file_size=30M +set-variable = innodb_log_buffer_size=8M +innodb_flush_log_at_trx_commit=1 innodb_log_arch_dir = c:\iblogs innodb_log_archive=0 -set-variable = innodb_log_files_in_group=3 -# Set the log file size to about -# 15 % of the buffer pool size -set-variable = innodb_log_file_size=10M -set-variable = innodb_log_buffer_size=8M -# Set ..flush_log_at_trx_commit to -# 0 if you can afford losing -# a few last transactions -innodb_flush_log_at_trx_commit=1 +set-variable = innodb_buffer_pool_size=80M +set-variable = innodb_additional_mem_pool_size=10M set-variable = innodb_file_io_threads=4 set-variable = innodb_lock_wait_timeout=50 @end example @@ -36354,44 +36340,27 @@ to be >= 10 MB. InnoDB does not create directories: you have to create them yourself. -Suppose you have a Linux computer with 512 MB RAM and +Suppose you have a Linux machine with 512 MB RAM and three 20 GB hard disks (at directory paths @file{/}, @file{/dr2} and @file{/dr3}). Below is an example of possible configuration parameters in @file{my.cnf} for InnoDB: @example -[mysqld] -# You can write your other MySQL server options here -# ... -# -innodb_data_home_dir = / -# Data files must be able to -# hold your data and indexes innodb_data_file_path = ibdata/ibdata1:2000M;dr2/ibdata/ibdata2:2000M -# Set buffer pool size to 50 - 80 % -# of your computer's memory -set-variable = innodb_buffer_pool_size=350M -set-variable = innodb_additional_mem_pool_size=20M -innodb_log_group_home_dir = /dr3/iblogs -# .._log_arch_dir must be the same -# as .._log_group_home_dir -innodb_log_arch_dir = /dr3/iblogs -innodb_log_archive=0 +innodb_data_home_dir = / +set-variable = innodb_mirrored_log_groups=1 +innodb_log_group_home_dir = /dr3 set-variable = innodb_log_files_in_group=3 -# Set the log file size to about -# 15 % of the buffer pool size set-variable = innodb_log_file_size=50M set-variable = innodb_log_buffer_size=8M -# Set ..flush_log_at_trx_commit to -# 0 if you can afford losing -# a few last transactions innodb_flush_log_at_trx_commit=1 +innodb_log_arch_dir = /dr3/iblogs +innodb_log_archive=0 +set-variable = innodb_buffer_pool_size=400M +set-variable = innodb_additional_mem_pool_size=20M set-variable = innodb_file_io_threads=4 set-variable = innodb_lock_wait_timeout=50 -#innodb_flush_method=fdatasync -#innodb_fast_shutdown=1 -#set-variable = innodb_thread_concurrency=5 @end example Note that we have placed the two data files on different disks. @@ -36405,10 +36374,6 @@ improve the performance of the database if all data is not placed on the same physical disk. Putting log files on a different disk from data is very often beneficial for performance. -The combined size of the log files MUST be < 4G in a 32-bit computer, -and to make recovery reasonably fast you should keep the combined size -smaller than the buffer pool size. - The meanings of the configuration parameters are the following: @multitable @columnfractions .30 .70 @@ -36432,9 +36397,7 @@ Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here. @item @code{innodb_log_file_size} @tab Size of each log file in a log group in megabytes. Sensible values range -from 1M to 1/nth of the size of the buffer pool specified below, where -n is the number of log files in the log group. -The bigger the +from 1M to the size of the buffer pool specified below. The bigger the value, the less checkpoint flush activity is needed in the buffer pool, saving disk i/o. But bigger log files also mean that recovery will be slower in case of a crash. File size restriction as for a data file. @@ -37137,8 +37100,7 @@ to zero. InnoDB tries to flush the log anyway once in a second, though the flush is not guaranteed. @strong{4.} -Make your log files big, the combined size -even as big as the buffer pool. When InnoDB +Make your log files big, even as big as the buffer pool. When InnoDB has written the log files full, it has to write the modified contents of the buffer pool to disk in a checkpoint. Small log files will cause many unnecessary disk writes. The drawback in big log files is that recovery diff --git a/configure.in b/configure.in index 562790e3b1e..7b0c604d2be 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! -AM_INIT_AUTOMAKE(mysql, 3.23.47) +AM_INIT_AUTOMAKE(mysql, 3.23.48) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 From 4b877e0088e6f32a606ffaa0fb3c94afb0b24388 Mon Sep 17 00:00:00 2001 From: "monty@hundin.mysql.fi" <> Date: Wed, 2 Jan 2002 21:29:41 +0200 Subject: [PATCH 15/15] Added macros for nice TIMESPEC usage. Fixes for building MySQL with gcc 3.0 Added SIGNED / UNSIGNED casts Fixed core dump bug in net_clear() with libmysqld. Back to using semaphores in query cache. Added 'Null' and 'Index_type' to SHOW INDEX. --- BUILD/FINISH.sh | 3 +- BUILD/Makefile.am | 45 ++++++++++++++ BUILD/SETUP.sh | 4 +- Docs/manual.texi | 87 ++++++++++++++++++++++---- Makefile.am | 3 +- client/Makefile.am | 1 + client/mysql.cc | 1 - client/mysqldump.c | 69 ++++++++++++--------- client/readline.cc | 19 ++---- configure.in | 4 +- extra/my_print_defaults.c | 2 +- include/my_global.h | 27 ++++++-- innobase/include/dyn0dyn.h | 5 ++ libmysql/Makefile.shared | 3 +- libmysqld/examples/Makefile.am | 2 +- libmysqld/lib_vio.c | 15 ++--- myisam/ft_dump.c | 6 +- myisam/ftdefs.h | 4 +- mysql-test/r/bdb.result | 30 ++++----- mysql-test/r/bigint.result | 9 +++ mysql-test/r/fulltext.result | 6 +- mysql-test/r/heap.result | 4 +- mysql-test/r/innodb.result | 30 ++++----- mysql-test/r/isam.result | 8 +-- mysql-test/r/key.result | 9 +++ mysql-test/r/myisam.result | 12 ++-- mysql-test/r/query_cache.result | 53 ++++++++++++++++ mysql-test/r/select.result | 8 +-- mysql-test/r/show_check.result | 28 ++++----- mysql-test/r/type_ranges.result | 30 ++++----- mysql-test/t/bigint.test | 4 ++ mysql-test/t/key.test | 8 +++ mysql-test/t/query_cache.test | 28 +++++++++ sql-bench/crash-me.sh | 33 +++++++++- sql/derror.cc | 34 ++++++----- sql/ha_berkeley.h | 1 + sql/ha_heap.h | 1 + sql/ha_innobase.cc | 21 +++---- sql/ha_innobase.h | 1 + sql/ha_isam.h | 1 + sql/ha_myisam.cc | 14 +++-- sql/ha_myisam.h | 3 +- sql/handler.h | 1 + sql/item_func.cc | 18 +----- sql/item_func.h | 21 +++++++ sql/lex.h | 1 + sql/mysqld.cc | 10 +-- sql/net_pkg.cc | 2 + sql/net_serv.cc | 2 +- sql/slave.cc | 62 +++++++++---------- sql/sql_cache.cc | 60 ++++++++++-------- sql/sql_cache.h | 7 ++- sql/sql_insert.cc | 16 +---- sql/sql_manager.cc | 8 +-- sql/sql_parse.cc | 4 +- sql/sql_repl.cc | 25 +++----- sql/sql_show.cc | 14 ++++- sql/sql_table.cc | 105 ++++++++++++++++++++------------ sql/sql_yacc.yy | 8 ++- 59 files changed, 677 insertions(+), 363 deletions(-) create mode 100644 BUILD/Makefile.am diff --git a/BUILD/FINISH.sh b/BUILD/FINISH.sh index 2e2ba1f7358..fbeaf1e3c68 100644 --- a/BUILD/FINISH.sh +++ b/BUILD/FINISH.sh @@ -20,7 +20,8 @@ then (cd gemini && aclocal && autoheader && aclocal && automake && autoconf) fi -CFLAGS=\"$cflags\" CXX=$CXX CXXFLAGS=\"$cxxflags\" $configure" +CFLAGS=\"$cflags\" CXX=\"$CXX\" CXXFLAGS=\"$cxxflags\" CXXLDFLAGS=\"$CXXLDFLAGS\" \ +$configure" if [ -z "$just_configure" ] then diff --git a/BUILD/Makefile.am b/BUILD/Makefile.am new file mode 100644 index 00000000000..ca42a79eec0 --- /dev/null +++ b/BUILD/Makefile.am @@ -0,0 +1,45 @@ +# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; 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 = FINISH.sh \ + SETUP.sh \ + compile-alpha \ + compile-alpha-ccc \ + compile-alpha-cxx \ + compile-alpha-debug \ + compile-ia64-debug-max \ + compile-pentium \ + compile-pentium-debug \ + compile-pentium-debug-max \ + compile-pentium-debug-no-bdb \ + compile-pentium-debug-openssl \ + compile-pentium-gcov \ + compile-pentium-gprof \ + compile-pentium-max \ + compile-pentium-myodbc \ + compile-pentium-mysqlfs-debug \ + compile-pentium-pgcc \ + compile-pentium-symbols \ + compile-solaris-sparc \ + compile-solaris-sparc-debug \ + compile-solaris-sparc-fortre \ + compile-solaris-sparc-purify + +# Don't update the files from bitkeeper +%::SCCS/s.% diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index f878123db59..3fa297fea1a 100644 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -69,7 +69,9 @@ fi if gcc -v 2>&1 | grep 'version 3' > /dev/null 2>&1 then - CXX=c++ + CXX="gcc -DUSE_MYSYS_NEW" + CXXLDFLAGS="-Wl,--defsym -Wl,__cxa_pure_virtual=0" else CXX=gcc + CXXLDFLAGS="" fi diff --git a/Docs/manual.texi b/Docs/manual.texi index f6c7c897fdc..e33eb38e586 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -1754,7 +1754,7 @@ Many embedded MySQL users will benefit from the @emph{dual licensing} scheme of MySQL, where besides the GPL license also commercial licensing is available for those not wishing to be bound by the GPL. The embedded MySQL library uses the same interface as the normal -client library, so it is convenient and easy to use. +client library, so it is convenient and easy to use. @xref{libmysqld}. @node Nutshell Other features, Nutshell Future features, Nutshell Embedded MySQL, MySQL 4.0 In A Nutshell @@ -8050,6 +8050,11 @@ version 4.0; @itemize @bullet @item +@code{SHOW INDEX} has 2 columns more (@code{Null} and @code{Index_type}) +than it had in 3.23. +@item +@code{SIGNED} is a reserved word. +@item To use @code{MATCH ... AGAINST (... IN BOOLEAN MODE)} with your tables, you need to rebuild them with @code{ALTER TABLE table_name TYPE=MyISAM}, @strong{even} if they are of @code{MyISAM} type. @@ -14159,7 +14164,6 @@ MySQL reads default options from the following files on Windows: @item @strong{Filename} @tab @strong{Purpose} @item @code{windows-system-directory\my.ini} @tab Global options @item @code{C:\my.cnf} @tab Global options -@item @code{C:\mysql\data\my.cnf} @tab Server-specific options @end multitable Note that on Windows, you should specify all paths with @code{/} instead of @@ -18903,13 +18907,16 @@ are returned: @item @code{Sub_part} @tab Number of indexed characters if the column is only partly indexed. @code{NULL} if the entire key is indexed. +@item @code{Null} $tab Contains 'YES' if the column may contain @code{NULL}. +@item @code{Index_type} @tab Index method used. @item @code{Comment} @tab Various remarks. For now, it tells - whether index is FULLTEXT or not. +in MySQL < 4.0.2 whether index is @code{FULLTEXT} or not. @end multitable Note that as the @code{Cardinality} is counted based on statistics stored as integers, it's not necessarily accurate for small tables. +The @code{Null} and @code{Index_type} column was added in MySQL 4.0.2. @node SHOW TABLE STATUS, SHOW STATUS, SHOW DATABASE INFO, SHOW @subsubsection @code{SHOW TABLE STATUS} @@ -19746,7 +19753,7 @@ subsystem) @cindex threads, display @cindex processes, display -@code{SHOW PROCESSLIST} shows you which threads are running. You can +@code{SHOW [FULL] PROCESSLIST} shows you which threads are running. You can also get this information using the @code{mysqladmin processlist} command. If you have the @strong{process} privilege, you can see all threads. Otherwise, you can see only your own threads. @xref{KILL, , @@ -21151,7 +21158,7 @@ the following configure options: You can find the MySQL-max binaries at @uref{http://www.mysql.com/downloads/mysql-max-3.23.html}. -The Windows MySQL 3.23 binary distribution includes both the +The Windows MySQL binary distributions includes both the standard @code{mysqld.exe} binary and the @code{mysqld-max.exe} binary. @uref{http://www.mysql.com/downloads/mysql-3.23.html}. @xref{Windows installation}. @@ -30665,6 +30672,7 @@ make string comparison even more flexible. @menu * Arithmetic functions:: Arithmetic Operations * Mathematical functions:: Mathematical Functions +* Numerical casts:: @end menu @@ -30733,7 +30741,7 @@ in a context where its result is converted to an integer! @end table -@node Mathematical functions, , Arithmetic functions, Numeric Functions +@node Mathematical functions, Numerical casts, Arithmetic functions, Numeric Functions @subsubsection Mathematical Functions All mathematical functions return @code{NULL} in case of an error. @@ -31130,6 +31138,35 @@ The above happens because 10.28 is actually stored as something like 10.2799999999999999. @end table +@node Numerical casts, , Mathematical functions, Numeric Functions +@subsubsection Casting numbers to signed / unsigned + +@cindex casts, SIGNED +@cindex casts, UNSIGNED + +To cast a string to a numeric value, you don't have to do anything; Just +use the string value as it would be a number: + +@example +mysql> select 1+'1'; + -> 2 +@end example + +MySQL support arithmetic with both signed and unsigned 64 bit values. +If you are using an numerical operations (like @code{+}) and one of the +operands are @code{unsigned}, then the result will be unsigned. You can +override this by using the @code{SIGNED} and @code{UNSIGNED} cast +operators, which will cast the operation to signed respective unsigned +64 bit integer. + +@example +mysql> select UNSIGNED 1-2; + -> 18446744073709551615 +mysql select SIGNED (UNSIGNED 1-2); + -> -1 +@end example + +@code{SIGNED} and @code{UNSIGNED} where added in MySQL 4.0.2. @node Date and time functions, Other Functions, Numeric Functions, Functions @subsection Date and Time Functions @@ -31608,10 +31645,11 @@ mysql> select NOW() + 0; @item UNIX_TIMESTAMP() @itemx UNIX_TIMESTAMP(date) If called with no argument, returns a Unix timestamp (seconds since -@code{'1970-01-01 00:00:00'} GMT). If @code{UNIX_TIMESTAMP()} is called with -a @code{date} argument, it returns the value of the argument as seconds since -@code{'1970-01-01 00:00:00'} GMT. @code{date} may be a @code{DATE} string, -a @code{DATETIME} string, a @code{TIMESTAMP}, or a number in the format +@code{'1970-01-01 00:00:00'} GMT) as an unsigned integer. If +@code{UNIX_TIMESTAMP()} is called with a @code{date} argument, it +returns the value of the argument as seconds since @code{'1970-01-01 +00:00:00'} GMT. @code{date} may be a @code{DATE} string, a +@code{DATETIME} string, a @code{TIMESTAMP}, or a number in the format @code{YYMMDD} or @code{YYYYMMDD} in local time: @example @@ -31622,11 +31660,14 @@ mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00'); @end example When @code{UNIX_TIMESTAMP} is used on a @code{TIMESTAMP} column, the function -will receive the value directly, with no implicit +will return the internal timestamp value directly, with no implicit ``string-to-unix-timestamp'' conversion. If you give @code{UNIX_TIMESTAMP()} a wrong or out-of-range date, it will return 0. +If you want to subtract @code{UNIX_TIMESTAMP()} columns, +@xref{Numerical casts}. + @findex FROM_UNIXTIME() @item FROM_UNIXTIME(unix_timestamp) Returns a representation of the @code{unix_timestamp} argument as a value in @@ -43140,6 +43181,11 @@ No UDF functions. No stack trace on core dump. @item No internal RAID support. +@item +You can set this up as a server or a master (no replication). +@item +You can't connect to the embedded server from an outside process with +sockets or TCP/IP. @end itemize Some of these limitations can be changed by editing the @file{mysql_embed.h} @@ -43148,6 +43194,8 @@ include file and recompiling MySQL. @node libmysqld options, libmysqld TODO, libmysqld restrictions, libmysqld @subsubsection Using Option Files with the Embedded Server +@cindex defaults, embedded + The following is the recommended way to use option files to make it easy to switch between a client/server application and one where MySQL is embedded. @xref{Option files}. @@ -43881,7 +43929,7 @@ is not the case, you should run the script @menu * UDF calling:: UDF Calling Sequences -* UDF aggr. calling:: UDF Calling Sequences for aggregate functions +* UDF aggr. calling :: * UDF arguments:: Argument Processing * UDF return values:: Return Values and Error Handling * UDF compiling:: Compiling and Installing User-definable Functions @@ -47845,11 +47893,24 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. @cindex changes, version 4.0 @menu +* News-4.0.2:: Changes in release 4.0.2 * News-4.0.1:: Changes in release 4.0.1 * News-4.0.0:: Changes in release 4.0.0 @end menu -@node News-4.0.1, News-4.0.0, News-4.0.x, News-4.0.x +@node News-4.0.2, News-4.0.1, News-4.0.x, News-4.0.x +@appendixsubsec Changes in release 4.0.2 + +@itemize @bullet +@item +Added cast functions @code{SIGNED} and @code{UNSIGNED}. +@item +Changed order of how keys are created in tables. +@item +Added a new columns @code{Null} and @code{Index_type} to @code{SHOW INDEX}. +@end itemize + +@node News-4.0.1, News-4.0.0, News-4.0.2, News-4.0.x @appendixsubsec Changes in release 4.0.1 @itemize @bullet diff --git a/Makefile.am b/Makefile.am index 7257617b8e6..af2f13f8f5b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,7 +23,8 @@ EXTRA_DIST = INSTALL-SOURCE README \ COPYING COPYING.LIB MIRRORS SUBDIRS = include @docs_dirs@ @readline_dir@ \ @thread_dirs@ pstack @sql_client_dirs@ \ - @sql_server_dirs@ @libmysqld_dirs@ scripts tests man \ + @sql_server_dirs@ @libmysqld_dirs@ scripts man \ + tests BUILD \ @bench_dirs@ support-files @fs_dirs@ @tools_dirs@ # Relink after clean diff --git a/client/Makefile.am b/client/Makefile.am index 8763486d3e2..cccb612af98 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -28,6 +28,7 @@ noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \ client_priv.h mysql_SOURCES = mysql.cc readline.cc sql_string.cc completion_hash.cc mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS) +mysqlbinlog_LDADD = $(LDADD) $(CXXLDFLAGS) mysql_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) mysqladmin_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) mysqlcheck_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES) diff --git a/client/mysql.cc b/client/mysql.cc index 2f040a0596f..72c97872455 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -171,7 +171,6 @@ static int sql_connect(char *host,char *database,char *user,char *password, uint silent); static int put_info(const char *str,INFO_TYPE info,uint error=0); static void safe_put_field(const char *pos,ulong length); -static const char *array_value(const char **array, char *key); static void xmlencode_print(const char *src, uint length); static void init_pager(); static void end_pager(); diff --git a/client/mysqldump.c b/client/mysqldump.c index 083f7a02d6f..25768dbe188 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -35,7 +35,7 @@ ** and adapted to mysqldump 05/11/01 by Jani Tolonen */ -#define DUMP_VERSION "8.19" +#define DUMP_VERSION "8.20" #include #include @@ -101,6 +101,7 @@ static struct option long_options[] = {"debug", optional_argument, 0, '#'}, {"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET}, {"delayed-insert", no_argument, 0, OPT_DELAYED}, + {"disable-keys", no_argument, 0, 'K'}, {"extended-insert", no_argument, 0, 'e'}, {"fields-terminated-by", required_argument, 0, (int) OPT_FTB}, {"fields-enclosed-by", required_argument, 0, (int) OPT_ENC}, @@ -118,7 +119,6 @@ static struct option long_options[] = {"no-create-db", no_argument, 0, 'n'}, {"no-create-info", no_argument, 0, 't'}, {"no-data", no_argument, 0, 'd'}, - {"no-disable-keys", no_argument, 0, 'K'}, {"opt", no_argument, 0, OPT_OPTIMIZE}, {"password", optional_argument, 0, 'p'}, #ifdef __WIN__ @@ -154,7 +154,7 @@ CHANGEABLE_VAR md_changeable_vars[] = { }; static void safe_exit(int error); -static void write_heder(FILE *sql_file, char *db_name); +static void write_header(FILE *sql_file, char *db_name); static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row, const char *prefix,const char *name, int string_value); @@ -215,9 +215,9 @@ static void usage(void) puts("\ -l, --lock-tables Lock all tables for read.\n\ --no-autocommit Wrap tables with autocommit/commit statements.\n\ - -K, --no-disable-keys '/*!40000 ALTER TABLE tb_name DISABLE KEYS */;\n\ + -K, --disable-keys '/*!40000 ALTER TABLE tb_name DISABLE KEYS */;\n\ and '/*!40000 ALTER TABLE tb_name ENABLE KEYS */;\n\ - will not be put in the output.\n\ + will be put in the output.\n\ -n, --no-create-db 'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;'\n\ will not be put in the output. The above line will\n\ be added otherwise, if --databases or\n\ @@ -226,8 +226,8 @@ puts("\ -d, --no-data No row information.\n\ -O, --set-variable var=option\n\ give a variable a value. --help lists variables\n\ - --opt Same as --add-drop-table --add-locks --all\n\ - --extended-insert --quick --lock-tables\n\ + --opt Same as --add-drop-table --add-locks --all --quick\n\ + --extended-insert --lock-tables --disable-keys\n\ -p, --password[=...] Password to use when connecting to server.\n\ If password is not given it's solicited on the tty.\n"); #ifdef __WIN__ @@ -282,7 +282,7 @@ puts("\ } /* usage */ -static void write_heder(FILE *sql_file, char *db_name) +static void write_header(FILE *sql_file, char *db_name) { if (opt_xml) fprintf(sql_file,"\n"); @@ -297,7 +297,7 @@ static void write_heder(FILE *sql_file, char *db_name) mysql_get_server_info(&mysql_connection)); } return; -} /* write_heder */ +} /* write_header */ static int get_options(int *argc,char ***argv) @@ -394,6 +394,7 @@ static int get_options(int *argc,char ***argv) break; case 'T': path= optarg; + opt_disable_keys=0; break; case 'B': opt_databases = 1; @@ -415,7 +416,10 @@ static int get_options(int *argc,char ***argv) case 'w': where=optarg; break; - case 'X': opt_xml = 1; opt_disable_keys=1; break; + case 'X': + opt_xml = 1; + opt_disable_keys=0; + break; case 'x': opt_first_slave=1; break; @@ -451,7 +455,8 @@ static int get_options(int *argc,char ***argv) opt_lock=1; break; case (int) OPT_OPTIMIZE: - extended_insert=opt_drop=opt_lock=lock_tables=quick=create_options=1; + extended_insert=opt_drop=opt_lock=lock_tables=quick=create_options= + opt_disable_keys=1; break; case (int) OPT_DELAYED: opt_delayed=1; @@ -666,7 +671,7 @@ static uint getTableStructure(char *table, char* db) safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } - write_heder(sql_file, db); + write_header(sql_file, db); } if (!opt_xml) fprintf(sql_file, "\n--\n-- Table structure for table '%s'\n--\n\n", @@ -685,6 +690,8 @@ static uint getTableStructure(char *table, char* db) { fprintf(stderr, "%s: Can't get info about table: '%s'\nerror: %s\n", my_progname, table, mysql_error(sock)); + if (path) + my_fclose(sql_file, MYF(MY_WME)); safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } @@ -738,10 +745,10 @@ static uint getTableStructure(char *table, char* db) O_WRONLY, MYF(MY_WME)); if (!sql_file) /* If file couldn't be opened */ { - safe_exit(EX_MYSQLERR); - DBUG_RETURN(0); + safe_exit(EX_MYSQLERR); + DBUG_RETURN(0); } - write_heder(sql_file, db); + write_header(sql_file, db); } if (!opt_xml) fprintf(sql_file, "\n--\n-- Table structure for table '%s'\n--\n\n", @@ -804,7 +811,7 @@ static uint getTableStructure(char *table, char* db) { fprintf(stderr, "%s: Can't get keys for table '%s' (%s)\n", my_progname, table, mysql_error(sock)); - if (sql_file != stdout) + if (path) my_fclose(sql_file, MYF(MY_WME)); safe_exit(EX_MYSQLERR); DBUG_RETURN(0); @@ -890,7 +897,7 @@ static uint getTableStructure(char *table, char* db) fputs(";\n", sql_file); } } - if (!opt_disable_keys) + if (opt_disable_keys) fprintf(sql_file,"\n/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",table_name); if (cFlag) { @@ -898,6 +905,8 @@ static uint getTableStructure(char *table, char* db) if (!extended_insert) strpos=strmov(strpos,"("); } + if (sql_file != md_result_file) + my_fclose(sql_file, MYF(MY_WME)); DBUG_RETURN(numFields); } /* getTableStructure */ @@ -1198,7 +1207,7 @@ static void dumpTable(uint numFields, char *table) safe_exit(EX_CONSCHECK); return; } - if (!opt_disable_keys) + if (opt_disable_keys) fprintf(md_result_file,"\n/*!40000 ALTER TABLE %s ENABLE KEYS */;\n", quote_name(table,table_buff)); if (opt_lock) @@ -1447,19 +1456,19 @@ int main(int argc, char **argv) if (dbConnect(current_host, current_user, opt_password)) exit(EX_MYSQLERR); if (!path) - write_heder(md_result_file, *argv); + write_header(md_result_file, *argv); - if (opt_first_slave) - { - lock_tables=0; /* No other locks needed */ - if (mysql_query(sock, "FLUSH TABLES WITH READ LOCK")) - { - my_printf_error(0, "Error: Couldn't execute 'FLUSH TABLES WITH READ LOCK': %s", - MYF(0), mysql_error(sock)); - my_end(0); - return(first_error); - } - } + if (opt_first_slave) + { + lock_tables=0; /* No other locks needed */ + if (mysql_query(sock, "FLUSH TABLES WITH READ LOCK")) + { + my_printf_error(0, "Error: Couldn't execute 'FLUSH TABLES WITH READ LOCK': %s", + MYF(0), mysql_error(sock)); + my_end(0); + return(first_error); + } + } if (opt_alldbs) dump_all_databases(); /* Only one database and selected table(s) */ diff --git a/client/readline.cc b/client/readline.cc index 38da8499eef..f5fbfd8cd0c 100644 --- a/client/readline.cc +++ b/client/readline.cc @@ -119,20 +119,11 @@ static bool init_line_buffer_from_string(LINE_BUFFER *buffer,my_string str) } -static void free_line_buffer(LINE_BUFFER *buffer) -{ - if (buffer->buffer) - { - my_free((gptr) buffer->buffer,MYF(0)); - buffer->buffer=0; - } -} - - -/* Fill the buffer retaining the last n bytes at the beginning of the - newly filled buffer (for backward context). Returns the number of new - bytes read from disk. */ - +/* + Fill the buffer retaining the last n bytes at the beginning of the + newly filled buffer (for backward context). Returns the number of new + bytes read from disk. +*/ static uint fill_buffer(LINE_BUFFER *buffer) { diff --git a/configure.in b/configure.in index 25bdaf18f34..894b0f157e2 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! -AM_INIT_AUTOMAKE(mysql, 4.0.1-alpha) +AM_INIT_AUTOMAKE(mysql, 4.0.2-alpha) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 @@ -2262,7 +2262,7 @@ AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile \ strings/Makefile regex/Makefile heap/Makefile \ bdb/Makefile \ myisam/Makefile myisammrg/Makefile \ - man/Makefile readline/Makefile vio/Makefile \ + man/Makefile BUILD/Makefile readline/Makefile vio/Makefile \ libmysql_r/Makefile libmysqld/Makefile libmysqld/examples/Makefile \ libmysql/Makefile client/Makefile \ pstack/Makefile pstack/aout/Makefile sql/Makefile sql/share/Makefile \ diff --git a/extra/my_print_defaults.c b/extra/my_print_defaults.c index d8edb8cc448..70ccb3797e6 100644 --- a/extra/my_print_defaults.c +++ b/extra/my_print_defaults.c @@ -58,7 +58,7 @@ static void usage(my_bool version) -?, --help Display this help message and exit.\n\ -V, --version Output version information and exit.\n", config_file); - printf("\nExample usage: %s --config-file=my client mysql\n",my_progname); + printf("\nExample usage:\n%s --config-file=my client mysql\n",my_progname); } static int get_options(int *argc,char ***argv) diff --git a/include/my_global.h b/include/my_global.h index 27781b230fd..7277bdcd715 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -216,8 +216,13 @@ #ifdef DONT_USE_FINITE /* HPUX 11.x has is_finite() */ #undef HAVE_FINITE #endif +#if defined(HPUX) && defined(_LARGEFILE64_SOURCE) && defined(THREAD) +/* Fix bug in setrlimit */ +#undef setrlimit +#define setrlimit cma_setrlimit64 +#endif -/* We can not live without these */ +/* We can not live without the following defines */ #define USE_MYFUNC 1 /* Must use syscall indirection */ #define MASTER 1 /* Compile without unireg */ @@ -226,7 +231,7 @@ #define USE_REGEX 1 /* We want the use the regex library */ /* Do not define for ultra sparcs */ #ifndef OS2 -#define USE_BMOVE512 1 /* Use this unless the system bmove is faster */ +#define USE_BMOVE512 1 /* Use this unless system bmove is faster */ #endif /* Paranoid settings. Define I_AM_PARANOID if you are paranoid */ @@ -611,8 +616,8 @@ typedef unsigned long ulong; /* Short for unsigned long */ #endif #ifndef longlong_defined #if defined(HAVE_LONG_LONG) && SIZEOF_LONG != 8 -typedef unsigned long long ulonglong; /* ulong or unsigned long long */ -typedef long long longlong; +typedef unsigned long long int ulonglong; /* ulong or unsigned long long */ +typedef long long int longlong; #else typedef unsigned long ulonglong; /* ulong or unsigned long long */ typedef long longlong; @@ -713,6 +718,20 @@ typedef char bool; /* Ordinary boolean values 0 1 */ #define MY_HOW_OFTEN_TO_ALARM 2 /* How often we want info on screen */ #define MY_HOW_OFTEN_TO_WRITE 1000 /* How often we want info on screen */ +#ifdef HAVE_TIMESPEC_TS_SEC +#define set_timespec(ABSTIME,SEC) { (ABSTIME).ts_sec=time(0) + (time_t) (SEC); (ABSTIME).ts_nsec=0; } +#elif defined(__WIN__) +#define set_timespec(ABSTIME,SEC) { (ABSTIME).tv_sec=time((time_t*)0) + (time_t) (SEC); (ABSTIME).tv_nsec=0; } +#else +#define set_timespec(ABSTIME,SEC) \ +{\ + struct timeval tv;\ + gettimeofday(&tv,0);\ + (ABSTIME).tv_sec=tv.tv_sec+(time_t) (SEC);\ + (ABSTIME).tv_nsec=tv.tv_usec*1000;\ +} +#endif + /* ** Define-funktions for reading and storing in machine independent format ** (low byte first) diff --git a/innobase/include/dyn0dyn.h b/innobase/include/dyn0dyn.h index 07ad8539b38..332622b6d4c 100644 --- a/innobase/include/dyn0dyn.h +++ b/innobase/include/dyn0dyn.h @@ -18,7 +18,12 @@ typedef dyn_block_t dyn_array_t; /* Initial 'payload' size in bytes in a dynamic array block */ +#ifndef _AIX #define DYN_ARRAY_DATA_SIZE 1024 +#else +/* AIX has a quite small stack / thread */ +#define DYN_ARRAY_DATA_SIZE 128 +#endif /************************************************************************* Initializes a dynamic array. */ diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared index 934051bb2bf..0d3aa79b9ce 100644 --- a/libmysql/Makefile.shared +++ b/libmysql/Makefile.shared @@ -34,7 +34,8 @@ LTCHARSET_OBJS= ${CHARSET_OBJS:.o=.lo} target_sources = libmysql.c net.c password.c manager.c \ get_password.c errmsg.c -mystringsobjects = strmov.lo strxmov.lo strnmov.lo strmake.lo strend.lo \ +mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \ + strmake.lo strend.lo \ strnlen.lo strfill.lo is_prefix.lo \ int2str.lo str2int.lo strinstr.lo strcont.lo \ strcend.lo bcmp.lo \ diff --git a/libmysqld/examples/Makefile.am b/libmysqld/examples/Makefile.am index d1cf24caf48..d9f9f05ae97 100644 --- a/libmysqld/examples/Makefile.am +++ b/libmysqld/examples/Makefile.am @@ -11,7 +11,7 @@ DEFS = -DEMBEDDED_LIBRARY INCLUDES = -I$(top_srcdir)/include $(openssl_includes) \ -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/client LIBS = @LIBS@ -LDADD = ../libmysqld.a @innodb_system_libs@ @LIBDL@ +LDADD = ../libmysqld.a @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS) mysqltest_SOURCES = mysqltest.c diff --git a/libmysqld/lib_vio.c b/libmysqld/lib_vio.c index a6723f8322e..9bf492ed5ea 100644 --- a/libmysqld/lib_vio.c +++ b/libmysqld/lib_vio.c @@ -146,27 +146,23 @@ int vio_write(Vio * vio, const gptr buf, int size) int vio_blocking(Vio * vio, my_bool set_blocking_mode) { - int r=0; - return (r); + return (0); } my_bool vio_is_blocking(Vio * vio) { - my_bool r=0; - return(r); + return(0); } int vio_fastsend(Vio * vio) { - int r=0; - return(r); + return(0); } int vio_keepalive(Vio* vio, my_bool set_keep_alive) { - int r=0; - return (r); + return (0); } @@ -181,8 +177,7 @@ vio_should_retry(Vio * vio __attribute__((unused))) int vio_close(Vio * vio) { - int r=0; - return(r); + return(0); } diff --git a/myisam/ft_dump.c b/myisam/ft_dump.c index f8e0fab8357..a693878acd9 100644 --- a/myisam/ft_dump.c +++ b/myisam/ft_dump.c @@ -27,7 +27,7 @@ static int count=0, stats=0, dump=0, verbose=0, lstats=0; static char *query=NULL; static uint lengths[256]; -#define MAX (HA_FT_MAXLEN+10) +#define MAX_LEN (HA_FT_MAXLEN+10) #define HOW_OFTEN_TO_WRITE 10000 int main(int argc,char *argv[]) @@ -37,7 +37,7 @@ int main(int argc,char *argv[]) float weight; double gws, min_gws=0, avg_gws=0; MI_INFO *info; - char buf[MAX], buf2[MAX], buf_maxlen[MAX], buf_min_gws[MAX]; + char buf[MAX_LEN], buf2[MAX_LEN], buf_maxlen[MAX_LEN], buf_min_gws[MAX_LEN]; ulong total=0, maxlen=0, uniq=0, max_doc_cnt=0; struct { MI_INFO *info; } aio0, *aio=&aio0; /* for GWS_IN_USE */ @@ -105,7 +105,7 @@ int main(int argc,char *argv[]) #error #endif - snprintf(buf,MAX,"%.*s",(int) keylen,info->lastkey+1); + snprintf(buf,MAX_LEN,"%.*s",(int) keylen,info->lastkey+1); casedn_str(buf); total++; lengths[keylen]++; diff --git a/myisam/ftdefs.h b/myisam/ftdefs.h index f8b50cb45b9..1a3c0ef60dc 100644 --- a/myisam/ftdefs.h +++ b/myisam/ftdefs.h @@ -135,7 +135,7 @@ FT_WORD * ft_linearize(/*MI_INFO *, uint, byte *, */TREE *); FT_WORD * _mi_ft_parserecord(MI_INFO *, uint, byte *, const byte *); uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, const byte *record); -const struct _ft_vft _ft_vft_nlq; +extern const struct _ft_vft _ft_vft_nlq; FT_INFO *ft_init_nlq_search(MI_INFO *, uint, byte *, uint, my_bool); int ft_nlq_read_next(FT_INFO *, char *); float ft_nlq_find_relevance(FT_INFO *, byte *, uint); @@ -144,7 +144,7 @@ float ft_nlq_get_relevance(FT_INFO *); my_off_t ft_nlq_get_docid(FT_INFO *); void ft_nlq_reinit_search(FT_INFO *); -const struct _ft_vft _ft_vft_boolean; +extern const struct _ft_vft _ft_vft_boolean; FT_INFO *ft_init_boolean_search(MI_INFO *, uint, byte *, uint, my_bool); int ft_boolean_read_next(FT_INFO *, char *); float ft_boolean_find_relevance(FT_INFO *, byte *, uint); diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result index a7ddff5c532..e553105fcc7 100644 --- a/mysql-test/r/bdb.result +++ b/mysql-test/r/bdb.result @@ -167,10 +167,10 @@ optimize table t1; Table Op Msg_type Msg_text test.t1 optimize status OK show keys from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t1 0 PRIMARY 1 id A 39 NULL NULL -t1 1 parent_id 1 parent_id A 9 NULL NULL -t1 1 level 1 level A 3 NULL NULL +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 id A 39 NULL NULL BTREE +t1 1 parent_id 1 parent_id A 9 NULL NULL BTREE +t1 1 level 1 level A 3 NULL NULL BTREE drop table t1; CREATE TABLE t1 ( gesuchnr int(11) DEFAULT '0' NOT NULL, @@ -217,8 +217,8 @@ analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status OK show keys from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t1 1 skr 1 a A 3 NULL NULL +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 skr 1 a A 3 NULL NULL YES BTREE drop table t1; create table t1 (a int,b varchar(20),key(a)) type=bdb; insert into t1 values (1,""), (2,"testing"); @@ -381,13 +381,13 @@ drop table t1; CREATE TABLE t1 (a int not null, b int not null,c int not null, key(a),primary key(a,b), unique(c),key(a),unique(b)); show index from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t1 0 PRIMARY 1 a A NULL NULL NULL -t1 0 PRIMARY 2 b A 0 NULL NULL -t1 0 b 1 b A 0 NULL NULL -t1 0 c 1 c A 0 NULL NULL -t1 1 a 1 a A NULL NULL NULL -t1 1 a_2 1 a A NULL NULL NULL +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 a A NULL NULL NULL BTREE +t1 0 PRIMARY 2 b A 0 NULL NULL BTREE +t1 0 c 1 c A 0 NULL NULL BTREE +t1 0 b 1 b A 0 NULL NULL BTREE +t1 1 a 1 a A NULL NULL NULL BTREE +t1 1 a_2 1 a A NULL NULL NULL BTREE drop table t1; create table t1 (col1 int not null, col2 char(4) not null, primary key(col1)); alter table t1 type=BDB; @@ -784,8 +784,8 @@ optimize table t1; Table Op Msg_type Msg_text test.t1 optimize status OK show keys from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t1 0 PRIMARY 1 a A 2 NULL NULL +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 a A 2 NULL NULL BTREE drop table t1; create table t1 (i int, j int )TYPE=BDB; insert into t1 values (1,2); diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result index 1c4a94ef1ee..1618f3f27a2 100644 --- a/mysql-test/r/bigint.result +++ b/mysql-test/r/bigint.result @@ -55,3 +55,12 @@ select min(big),max(big),max(big)-1 from t1 group by a; min(big) max(big) max(big)-1 -1 9223372036854775807 9223372036854775806 drop table t1; +select UNSIGNED 1-2; +UNSIGNED 1-2 +18446744073709551615 +select SIGNED (UNSIGNED 1-2); +SIGNED (UNSIGNED 1-2) +-1 +select UNSIGNED '-1'; +UNSIGNED '-1' +18446744073709551615 diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index d3038acdc5c..6660a788646 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -101,9 +101,9 @@ match(ttxt.inhalt) against ('foobar'); id 3 show keys from t2; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t2 1 tig 1 ticket A NULL NULL NULL -t2 1 tix 1 inhalt A NULL 1 NULL FULLTEXT +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t2 1 tig 1 ticket A NULL NULL NULL YES BTREE +t2 1 tix 1 inhalt A NULL 1 NULL YES FULLTEXT show create table t2; Table Create Table t2 CREATE TABLE `t2` ( diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result index 3acd0d14118..5495997324a 100644 --- a/mysql-test/r/heap.result +++ b/mysql-test/r/heap.result @@ -3,8 +3,8 @@ create table t1 (a int not null,b int not null, primary key (a)) type=heap comme insert into t1 values(1,1),(2,2),(3,3),(4,4); delete from t1 where a=1 or a=0; show keys from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t1 0 PRIMARY 1 a NULL NULL NULL NULL +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 a NULL NULL NULL NULL HASH select * from t1; a b 2 2 diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 8664cab0b84..1a48b6d6294 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -167,10 +167,10 @@ optimize table t1; Table Op Msg_type Msg_text test.t1 optimize error The handler for the table doesn't support check/repair show keys from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t1 0 PRIMARY 1 id A 87 NULL NULL -t1 1 parent_id 1 parent_id A 21 NULL NULL -t1 1 level 1 level A 4 NULL NULL +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 id A 87 NULL NULL BTREE +t1 1 parent_id 1 parent_id A 21 NULL NULL BTREE +t1 1 level 1 level A 4 NULL NULL BTREE drop table t1; CREATE TABLE t1 ( gesuchnr int(11) DEFAULT '0' NOT NULL, @@ -210,8 +210,8 @@ analyze table t1; Table Op Msg_type Msg_text test.t1 analyze error The handler for the table doesn't support check/repair show keys from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t1 1 skr 1 a A 1 NULL NULL +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 skr 1 a A 1 NULL NULL YES BTREE drop table t1; create table t1 (a int,b varchar(20),key(a)) type=innodb; insert into t1 values (1,""), (2,"testing"); @@ -353,13 +353,13 @@ drop table t1; CREATE TABLE t1 (a int not null, b int not null,c int not null, key(a),primary key(a,b), unique(c),key(a),unique(b)); show index from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t1 0 PRIMARY 1 a A NULL NULL NULL -t1 0 PRIMARY 2 b A 0 NULL NULL -t1 0 b 1 b A 0 NULL NULL -t1 0 c 1 c A 0 NULL NULL -t1 1 a 1 a A NULL NULL NULL -t1 1 a_2 1 a A NULL NULL NULL +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 a A NULL NULL NULL BTREE +t1 0 PRIMARY 2 b A 0 NULL NULL BTREE +t1 0 c 1 c A 0 NULL NULL BTREE +t1 0 b 1 b A 0 NULL NULL BTREE +t1 1 a 1 a A NULL NULL NULL BTREE +t1 1 a_2 1 a A NULL NULL NULL BTREE drop table t1; create table t1 (col1 int not null, col2 char(4) not null, primary key(col1)); alter table t1 type=innodb; @@ -726,8 +726,8 @@ optimize table t1; Table Op Msg_type Msg_text test.t1 optimize error The handler for the table doesn't support check/repair show keys from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t1 0 PRIMARY 1 a A 1 NULL NULL +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 a A 1 NULL NULL BTREE drop table t1; create table t1 (i int, j int ) TYPE=innodb; insert into t1 values (1,2); diff --git a/mysql-test/r/isam.result b/mysql-test/r/isam.result index baeda5537e5..d19352aad42 100644 --- a/mysql-test/r/isam.result +++ b/mysql-test/r/isam.result @@ -72,8 +72,8 @@ a int(11) PRI 0 select,insert,update,references b int(11) MUL 0 select,insert,update,references c int(11) 0 select,insert,update,references show index from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t1 0 PRIMARY 1 a A 4 NULL NULL -t1 1 b 1 b A 1 NULL NULL -t1 1 b 2 c A 4 NULL NULL +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 a A 4 NULL NULL BTREE +t1 1 b 1 b A 1 NULL NULL BTREE +t1 1 b 2 c A 4 NULL NULL BTREE drop table t1,t2; diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result index 0c73fc086c5..6dfe0809e7f 100644 --- a/mysql-test/r/key.result +++ b/mysql-test/r/key.result @@ -138,3 +138,12 @@ a b a 1 a 2 drop table t1; +create table t1 (a int not null unique, b int unique, c int, d int not null primary key, key(c), e int not null unique); +show keys from t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 d A 0 NULL NULL BTREE +t1 0 a 1 a A 0 NULL NULL BTREE +t1 0 e 1 e A 0 NULL NULL BTREE +t1 0 b 1 b A NULL NULL NULL YES BTREE +t1 1 c 1 c A NULL NULL NULL YES BTREE +drop table t1; diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index efcc610cbd4..c5c69c1ba7b 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -37,16 +37,16 @@ optimize table t1; Table Op Msg_type Msg_text test.t1 optimize status OK show index from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t1 0 PRIMARY 1 a A 5 NULL NULL -t1 1 b 1 b A 1 NULL NULL +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 a A 5 NULL NULL BTREE +t1 1 b 1 b A 1 NULL NULL BTREE optimize table t1; Table Op Msg_type Msg_text test.t1 optimize status Table is already up to date show index from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t1 0 PRIMARY 1 a A 5 NULL NULL -t1 1 b 1 b A 1 NULL NULL +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 a A 5 NULL NULL BTREE +t1 1 b 1 b A 1 NULL NULL BTREE drop table t1; create table t1 (a int not null, b int not null, c int not null, primary key (a),key(b)) type=myisam; insert into t1 values (3,3,3),(1,1,1),(2,2,2),(4,4,4); diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index fa130deec19..632f64e25de 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -406,6 +406,59 @@ Variable_name Value Qcache_hits 6 drop database mysqltest; drop table t1; +create table t1 (i int not null); +insert into t1 (i) values (1),(2),(3),(4); +select SQL_CALC_FOUND_ROWS * from t1 limit 2; +i +1 +2 +select FOUND_ROWS(); +FOUND_ROWS() +4 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 6 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +select * from t1 where i=1; +i +1 +select FOUND_ROWS(); +FOUND_ROWS() +1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 6 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +select SQL_CALC_FOUND_ROWS * from t1 limit 2; +i +1 +2 +select FOUND_ROWS(); +FOUND_ROWS() +4 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 7 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +select * from t1 where i=1; +i +1 +select FOUND_ROWS(); +FOUND_ROWS() +1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 8 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +drop table t1; flush query cache; reset query cache; create table t1 (a int not null); diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 702d4a6de03..ee057b268fd 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3225,10 +3225,10 @@ fld6 char(4) select,insert,update,references show full columns from t2 from test like 's%'; Field Type Null Key Default Extra Privileges show keys from t2; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t2 0 PRIMARY 1 auto A 1199 NULL NULL -t2 0 fld1 1 fld1 A 1199 NULL NULL -t2 1 fld3 1 fld3 A NULL NULL NULL +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t2 0 PRIMARY 1 auto A 1199 NULL NULL BTREE +t2 0 fld1 1 fld1 A 1199 NULL NULL BTREE +t2 1 fld3 1 fld3 A NULL NULL NULL BTREE DO 1; DO benchmark(100,1+1),1,1; drop table t4, t3,t2, t1; diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index f66bf22b224..2530e5b09fb 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -21,10 +21,10 @@ check table t1 type=extended; Table Op Msg_type Msg_text test.t1 check status OK show index from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t1 0 PRIMARY 1 a A 5 NULL NULL -t1 1 b 1 b A 1 NULL NULL -t1 1 b 2 c A 5 NULL NULL +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 a A 5 NULL NULL BTREE +t1 1 b 1 b A 1 NULL NULL BTREE +t1 1 b 2 c A 5 NULL NULL BTREE insert into t1 values (5,5,5); Duplicate entry '5' for key 1 optimize table t1; @@ -54,20 +54,20 @@ analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status OK show index from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t1 0 PRIMARY 1 f1 A 1 NULL NULL -t1 0 PRIMARY 2 f2 A 3 NULL NULL -t1 0 PRIMARY 3 f3 A 9 NULL NULL -t1 0 PRIMARY 4 f4 A 18 NULL NULL +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 f1 A 1 NULL NULL BTREE +t1 0 PRIMARY 2 f2 A 3 NULL NULL BTREE +t1 0 PRIMARY 3 f3 A 9 NULL NULL BTREE +t1 0 PRIMARY 4 f4 A 18 NULL NULL BTREE repair table t1; Table Op Msg_type Msg_text test.t1 repair status OK show index from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t1 0 PRIMARY 1 f1 A 1 NULL NULL -t1 0 PRIMARY 2 f2 A 3 NULL NULL -t1 0 PRIMARY 3 f3 A 9 NULL NULL -t1 0 PRIMARY 4 f4 A 18 NULL NULL +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 f1 A 1 NULL NULL BTREE +t1 0 PRIMARY 2 f2 A 3 NULL NULL BTREE +t1 0 PRIMARY 3 f3 A 9 NULL NULL BTREE +t1 0 PRIMARY 4 f4 A 18 NULL NULL BTREE drop table t1; create temporary table t1 (a int not null); show create table t1; diff --git a/mysql-test/r/type_ranges.result b/mysql-test/r/type_ranges.result index 22b4292fa39..fc7cc5255cf 100644 --- a/mysql-test/r/type_ranges.result +++ b/mysql-test/r/type_ranges.result @@ -64,21 +64,21 @@ longblob_col longblob select,insert,update,references options enum('one','two','tree') MUL one select,insert,update,references flags set('one','two','tree') select,insert,update,references show keys from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Comment -t1 0 PRIMARY 1 auto A 0 NULL NULL -t1 1 utiny 1 utiny A NULL NULL NULL -t1 1 tiny 1 tiny A NULL NULL NULL -t1 1 short 1 short A NULL NULL NULL -t1 1 any_name 1 medium A NULL NULL NULL -t1 1 longlong 1 longlong A NULL NULL NULL -t1 1 real_float 1 real_float A NULL NULL NULL -t1 1 ushort 1 ushort A NULL NULL NULL -t1 1 umedium 1 umedium A NULL NULL NULL -t1 1 ulong 1 ulong A NULL NULL NULL -t1 1 ulonglong 1 ulonglong A NULL NULL NULL -t1 1 ulonglong 2 ulong A NULL NULL NULL -t1 1 options 1 options A NULL NULL NULL -t1 1 options 2 flags A NULL NULL NULL +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 auto A 0 NULL NULL BTREE +t1 1 utiny 1 utiny A NULL NULL NULL BTREE +t1 1 tiny 1 tiny A NULL NULL NULL BTREE +t1 1 short 1 short A NULL NULL NULL BTREE +t1 1 any_name 1 medium A NULL NULL NULL BTREE +t1 1 longlong 1 longlong A NULL NULL NULL BTREE +t1 1 real_float 1 real_float A NULL NULL NULL BTREE +t1 1 ushort 1 ushort A NULL NULL NULL BTREE +t1 1 umedium 1 umedium A NULL NULL NULL BTREE +t1 1 ulong 1 ulong A NULL NULL NULL BTREE +t1 1 ulonglong 1 ulonglong A NULL NULL NULL BTREE +t1 1 ulonglong 2 ulong A NULL NULL NULL BTREE +t1 1 options 1 options A NULL NULL NULL BTREE +t1 1 options 2 flags A NULL NULL NULL BTREE CREATE UNIQUE INDEX test on t1 ( auto ) ; CREATE INDEX test2 on t1 ( ulonglong,ulong) ; CREATE INDEX test3 on t1 ( medium ) ; diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test index 52ae9ad35db..27ac346825b 100644 --- a/mysql-test/t/bigint.test +++ b/mysql-test/t/bigint.test @@ -29,3 +29,7 @@ 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; + +select UNSIGNED 1-2; +select SIGNED (UNSIGNED 1-2); +select UNSIGNED '-1'; diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test index a8417fad876..6fc975a1cb3 100644 --- a/mysql-test/t/key.test +++ b/mysql-test/t/key.test @@ -160,3 +160,11 @@ SELECT * FROM t1 WHERE a='a' AND b=2; SELECT * FROM t1 WHERE a='a' AND b in (2); SELECT * FROM t1 WHERE a='a' AND b in (1,2); drop table t1; + +# +# Test of create key order +# + +create table t1 (a int not null unique, b int unique, c int, d int not null primary key, key(c), e int not null unique); +show keys from t1; +drop table t1; diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index 8a577d0be05..280f2202af1 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -287,6 +287,34 @@ show status like "Qcache_hits"; drop database mysqltest; drop table t1; +# +# FOUND_ROWS() +# + +create table t1 (i int not null); +insert into t1 (i) values (1),(2),(3),(4); + +select SQL_CALC_FOUND_ROWS * from t1 limit 2; +select FOUND_ROWS(); +show status like "Qcache_hits"; +show status like "Qcache_queries_in_cache"; + +select * from t1 where i=1; +select FOUND_ROWS(); +show status like "Qcache_hits"; +show status like "Qcache_queries_in_cache"; + +select SQL_CALC_FOUND_ROWS * from t1 limit 2; +select FOUND_ROWS(); +show status like "Qcache_hits"; +show status like "Qcache_queries_in_cache"; + +select * from t1 where i=1; +select FOUND_ROWS(); +show status like "Qcache_hits"; +show status like "Qcache_queries_in_cache"; +drop table t1; + # # Test insert delayed # diff --git a/sql-bench/crash-me.sh b/sql-bench/crash-me.sh index 434599a1ac4..9572143ae53 100644 --- a/sql-bench/crash-me.sh +++ b/sql-bench/crash-me.sh @@ -143,7 +143,15 @@ $longreadlen=16000000; # For retrieval buffer # use sigtrap; # Must be removed with perl5.005_2 on Win98 $SIG{PIPE} = 'IGNORE'; -$SIG{SEGV} = sub {warn('SEGFAULT')}; +$problem_counter=0; +$SIG{SEGV} = sub { + $problem_counter +=1; + if ($problem_counter >= 100) { + die("Too many problems, try to restart"); + } else { + warn('SEGFAULT'); + }; +}; $dbh=safe_connect(); # @@ -252,6 +260,8 @@ report("Functions",'functions',"select 1+1 $end_query"); report("Group functions",'group_functions',"select count(*) from crash_me"); report("Group functions with distinct",'group_distinct_functions', "select count(distinct a) from crash_me"); +report("Group functions with several distinct",'group_many_distinct_functions', + "select count(distinct a), count(distinct b) from crash_me"); report("Group by",'group_by',"select a from crash_me group by a"); report("Group by position",'group_by_position', "select a from crash_me group by 1"); @@ -1438,6 +1448,14 @@ if (!report("case independent table names","table_name_case", safe_query("drop table crash_q $drop_attr"); } +if (!report("case independent field names","field_name_case", + "create table crash_q (q integer)", + "insert into crash_q(Q) values (1)", + "drop table crash_q $drop_attr")) +{ + safe_query("drop table crash_q $drop_attr"); +} + if (!report("drop table if exists","drop_if_exists", "create table crash_q (q integer)", "drop table if exists crash_q $drop_attr")) @@ -2450,6 +2468,7 @@ sub report print "$prompt: "; if (!defined($limits{$limit})) { + save_config_data($limit,"incompleted",$prompt); save_config_data($limit,safe_query(\@queries) ? "yes" : "no",$prompt); } print "$limits{$limit}\n"; @@ -2462,6 +2481,7 @@ sub report_fail print "$prompt: "; if (!defined($limits{$limit})) { + save_config_data($limit,"incompleted",$prompt); save_config_data($limit,safe_query(\@queries) ? "no" : "yes",$prompt); } print "$limits{$limit}\n"; @@ -2478,6 +2498,7 @@ sub report_one print "$prompt: "; if (!defined($limits{$limit})) { + save_config_data($limit,"incompleted",$prompt); $result="no"; foreach $query (@$queries) { @@ -2503,6 +2524,7 @@ sub report_result print "$prompt: "; if (!defined($limits{$limit})) { + save_config_data($limit,"incompleted",$prompt); $error=safe_query_result($query,"1",2); save_config_data($limit,$error ? "not supported" : $last_result,$prompt); } @@ -2515,6 +2537,7 @@ sub report_trans my ($limit,$queries,$check,$clear)=@_; if (!defined($limits{$limit})) { + save_config_data($limit,"incompleted",$prompt); eval {undef($dbh->{AutoCommit})}; if (!$@) { @@ -2556,9 +2579,11 @@ sub check_and_report print "$prompt: " if (!defined($skip_prompt)); if (!defined($limits{$limit})) { + save_config_data($limit,"incompleted",$prompt); $tmp=1-safe_query(\@$pre); $tmp=safe_query_result($query,$answer,$string_type) if (!$tmp); safe_query(\@$post); + delete $limits{$limit}; if ($function == 3) # Report error as 'no'. { $function=0; @@ -2587,8 +2612,10 @@ sub try_and_report my ($tmp,$test,$type); print "$prompt: "; + if (!defined($limits{$limit})) { + save_config_data($limit,"incompleted",$prompt); $type="no"; # Not supported foreach $test (@tests) { @@ -2699,7 +2726,7 @@ sub safe_query_result elsif ($result_type == 5) # Result should have given prefix { $result= -1 if (length($row->[0]) < length($answer) && - substring($row->[0],1,length($answer)) ne $answer); + substr($row->[0],1,length($answer)) ne $answer); } elsif ($result_type == 6) # Exact match but ignore errors { @@ -2760,6 +2787,8 @@ sub find_limit() print "$end (cache)\n"; return $end; } + save_config_data($limit,"incompleted",$prompt); + if (defined($query->{'init'}) && !defined($end=$limits{'restart'}{'tohigh'})) { if (!safe_query($query->{'init'})) diff --git a/sql/derror.cc b/sql/derror.cc index d0519c37dca..7ebe6e4b3c5 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -44,7 +44,7 @@ static void read_texts(const char *file_name,const char ***point, uint error_messages) { register uint i; - uint ant,funktpos,length,textant; + uint count,funktpos,length,textcount; File file; char name[FN_REFLEN]; const char *buff; @@ -64,36 +64,38 @@ static void read_texts(const char *file_name,const char ***point, if (head[0] != (uchar) 254 || head[1] != (uchar) 254 || head[2] != 2 || head[3] != 1) goto err; /* purecov: inspected */ - textant=head[4]; - length=uint2korr(head+6); ant=uint2korr(head+8); + textcount=head[4]; + length=uint2korr(head+6); count=uint2korr(head+8); - if (ant < error_messages) + if (count < error_messages) { - fprintf(stderr,"\n%s: Fatal error: Error message file '%s' had only %d error messages, but it should have at least %d error messages.\n\ -Check that the above file is the right version for this program!\n\n", - my_progname,name,ant,error_messages); + sql_print_error("\ +Error message file '%s' had only %d error messages,\n\ +but it should contain at least %d error messages.\n\ +Check that the above file is the right version for this program!", + name,count,error_messages); VOID(my_close(file,MYF(MY_WME))); unireg_abort(1); } x_free((gptr) *point); /* Free old language */ if (!(*point= (const char**) - my_malloc((uint) (length+ant*sizeof(char*)),MYF(0)))) + my_malloc((uint) (length+count*sizeof(char*)),MYF(0)))) { funktpos=2; /* purecov: inspected */ goto err; /* purecov: inspected */ } - buff= (char*) (*point + ant); + buff= (char*) (*point + count); - if (my_read(file,(byte*) buff,(uint) ant*2,MYF(MY_NABP))) goto err; - for (i=0, pos= (uchar*) buff ; i< ant ; i++) + if (my_read(file,(byte*) buff,(uint) count*2,MYF(MY_NABP))) goto err; + for (i=0, pos= (uchar*) buff ; i< count ; i++) { (*point)[i]=buff+uint2korr(pos); pos+=2; } if (my_read(file,(byte*) buff,(uint) length,MYF(MY_NABP))) goto err; - for (i=1 ; i < textant ; i++) + for (i=1 ; i < textcount ; i++) { point[i]= *point +uint2korr(head+10+i+i); } @@ -103,18 +105,18 @@ Check that the above file is the right version for this program!\n\n", err: switch (funktpos) { case 2: - buff="\n%s: Fatal error: Not enough memory for messagefile '%s'\n\n"; + buff="Not enough memory for messagefile '%s'"; break; case 1: - buff="\n%s: Fatal error: Can't read from messagefile '%s'\n\n"; + buff="Can't read from messagefile '%s'"; break; default: - buff="\n%s: Fatal error: Can't find messagefile '%s'\n\n"; + buff="Can't find messagefile '%s'"; break; } if (file != FERR) VOID(my_close(file,MYF(MY_WME))); - fprintf(stderr,buff,my_progname,name); + sql_print_error(buff,name); unireg_abort(1); } /* read_texts */ diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h index 65116f908ac..fbc858b5996 100644 --- a/sql/ha_berkeley.h +++ b/sql/ha_berkeley.h @@ -98,6 +98,7 @@ class ha_berkeley: public handler } ~ha_berkeley() {} const char *table_type() const { return "BerkeleyDB"; } + const char *index_type(uint key_number) { return "BTREE"; } const char **bas_ext() const; ulong option_flag() const { return int_option_flag; } uint max_record_length() const { return HA_MAX_REC_LENGTH; } diff --git a/sql/ha_heap.h b/sql/ha_heap.h index 9b041411012..fa077cef60a 100644 --- a/sql/ha_heap.h +++ b/sql/ha_heap.h @@ -31,6 +31,7 @@ class ha_heap: public handler ha_heap(TABLE *table): handler(table), file(0) {} ~ha_heap() {} const char *table_type() const { return "HEAP"; } + const char *index_type(uint key_number) { return "HASH"; } const char **bas_ext() const; ulong option_flag() const { return (HA_READ_RND_SAME | HA_NO_INDEX | HA_ONLY_WHOLE_INDEX | diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc index 836a1a4331e..3b6b15d1e79 100644 --- a/sql/ha_innobase.cc +++ b/sql/ha_innobase.cc @@ -580,7 +580,7 @@ innobase_init(void) ret = innobase_parse_data_file_paths_and_sizes(); if (ret == FALSE) { - fprintf(stderr, "InnoDB: syntax error in innodb_data_file_path\n"); + sql_print_error("InnoDB: syntax error in innodb_data_file_path"); DBUG_RETURN(TRUE); } @@ -928,13 +928,13 @@ ha_innobase::open( if (NULL == (ib_table = dict_table_get(norm_name, NULL))) { - fprintf(stderr, -"InnoDB: Error: cannot find table %s from the internal data dictionary\n" -"InnoDB: of InnoDB though the .frm file for the table exists. Maybe you\n" -"InnoDB: have deleted and recreated InnoDB data files but have forgotten\n" -"InnoDB: to delete the corresponding .frm files of InnoDB tables, or you\n" -"InnoDB: have moved .frm files to another database?\n", - norm_name); + sql_print_error("InnoDB error:\n\ +Cannot find table %s from the internal data dictionary\n\ +of InnoDB though the .frm file for the table exists. Maybe you\n\ +have deleted and recreated InnoDB data files but have forgotten\n\ +to delete the corresponding .frm files of InnoDB tables, or you\n\ +have moved .frm files to another database?", + norm_name); free_share(share); my_free((char*) upd_buff, MYF(0)); @@ -2034,10 +2034,7 @@ ha_innobase::change_active_index( prebuilt->index=dict_table_get_index_noninline(prebuilt->table, key->name); if (!prebuilt->index) { - fprintf(stderr, - "InnoDB: Could not find key n:o %u with name %s from dict cache\n" - "InnoDB: for table %s\n", keynr, key->name, - prebuilt->table->name); + sql_print_error("Innodb could not find key n:o %u with name %s from dict cache for table %s", keynr, key->name, prebuilt->table->name); return(1); } } diff --git a/sql/ha_innobase.h b/sql/ha_innobase.h index b1613c2503c..bcd11b8a96e 100644 --- a/sql/ha_innobase.h +++ b/sql/ha_innobase.h @@ -91,6 +91,7 @@ class ha_innobase: public handler ~ha_innobase() {} const char* table_type() const { return("InnoDB");} + const char *index_type(uint key_number) { return "BTREE"; } const char** bas_ext() const; ulong option_flag() const { return int_option_flag; } uint max_record_length() const { return HA_MAX_REC_LENGTH; } diff --git a/sql/ha_isam.h b/sql/ha_isam.h index 33ca99b5063..e878f0fe697 100644 --- a/sql/ha_isam.h +++ b/sql/ha_isam.h @@ -38,6 +38,7 @@ class ha_isam: public handler {} ~ha_isam() {} const char *table_type() const { return "ISAM"; } + const char *index_type(uint key_number) { return "BTREE"; } const char **bas_ext() const; ulong option_flag() const { return int_option_flag; } uint max_record_length() const { return HA_MAX_REC_LENGTH; } diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 0378ff7ba6f..77d541bfdfb 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -80,9 +80,8 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type, net_store_data(packet, msgbuf); if (my_net_write(&thd->net, (char*)thd->packet.ptr(), thd->packet.length())) - fprintf(stderr, - "Failed on my_net_write, writing to stderr instead: %s\n", - msgbuf); + sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n", + msgbuf); return; } @@ -122,6 +121,13 @@ const char **ha_myisam::bas_ext() const { static const char *ext[]= { ".MYD",".MYI", NullS }; return ext; } +const char *ha_myisam::index_type(uint key_number) +{ + return ((table->key_info[key_number].flags & HA_FULLTEXT) ? + "FULLTEXT" : + "BTREE"); +} + int ha_myisam::net_read_dump(NET* net) { int data_fd = file->dfile; @@ -1170,7 +1176,7 @@ longlong ha_myisam::get_auto_increment() longlong nr; int error; - byte key[MAX_KEY_LENGTH]; + byte key[MI_MAX_KEY_LENGTH]; (void) extra(HA_EXTRA_KEYREAD); key_copy(key,table,table->next_number_index, table->next_number_key_offset); diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h index 7b5c959ccfa..e2044dfe1e2 100644 --- a/sql/ha_myisam.h +++ b/sql/ha_myisam.h @@ -54,12 +54,13 @@ class ha_myisam: public handler {} ~ha_myisam() {} const char *table_type() const { return "MyISAM"; } + const char *index_type(uint key_number); const char **bas_ext() const; ulong option_flag() const { return int_option_flag; } uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_keys() const { return MI_MAX_KEY; } uint max_key_parts() const { return MAX_REF_PARTS; } - uint max_key_length() const { return MAX_KEY_LENGTH; } + uint max_key_length() const { return MI_MAX_KEY_LENGTH; } int open(const char *name, int mode, uint test_if_locked); int close(void); diff --git a/sql/handler.h b/sql/handler.h index 1e2c0074475..33cfa965363 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -236,6 +236,7 @@ public: virtual bool has_transactions(){ return 0;} virtual uint extra_rec_buf_length() { return 0; } virtual ha_rows estimate_number_of_rows() { return records+EXTRA_RECORDS; } + virtual const char *index_type(uint key_number) { return "";} virtual int index_init(uint idx) { active_index=idx; return 0;} virtual int index_end() {return 0; } diff --git a/sql/item_func.cc b/sql/item_func.cc index 4caa959bce8..93edcc64146 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1496,14 +1496,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout) thd->mysys_var->current_mutex= &LOCK_user_locks; thd->mysys_var->current_cond= &ull->cond; -#ifdef HAVE_TIMESPEC_TS_SEC - abstime.ts_sec=time((time_t*) 0)+(time_t) lock_timeout; - abstime.ts_nsec=0; -#else - abstime.tv_sec=time((time_t*) 0)+(time_t) lock_timeout; - abstime.tv_nsec=0; -#endif - + set_timespec(abstime,lock_timeout); while (!thd->killed && (error=pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime)) != ETIME && error != ETIMEDOUT && ull->locked) ; @@ -1591,14 +1584,7 @@ longlong Item_func_get_lock::val_int() thd->mysys_var->current_mutex= &LOCK_user_locks; thd->mysys_var->current_cond= &ull->cond; -#ifdef HAVE_TIMESPEC_TS_SEC - abstime.ts_sec=time((time_t*) 0)+(time_t) timeout; - abstime.ts_nsec=0; -#else - abstime.tv_sec=time((time_t*) 0)+(time_t) timeout; - abstime.tv_nsec=0; -#endif - + set_timespec(abstime,timeout); while (!thd->killed && (error=pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime)) != ETIME && error != ETIMEDOUT && ull->locked) ; diff --git a/sql/item_func.h b/sql/item_func.h index 23cdf7082cf..648ca6d0743 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -181,6 +181,27 @@ public: void fix_length_and_dec() { decimals=0; max_length=21; } }; +class Item_func_signed :public Item_int_func +{ +public: + Item_func_signed(Item *a) :Item_int_func(a) {} + double val() { return args[0]->val(); } + longlong val_int() { return args[0]->val_int(); } + void fix_length_and_dec() + { decimals=0; max_length=args[0]->max_length; unsigned_flag=0; } +}; + +class Item_func_unsigned :public Item_int_func +{ +public: + Item_func_unsigned(Item *a) :Item_int_func(a) {} + double val() { return args[0]->val(); } + longlong val_int() { return args[0]->val_int(); } + void fix_length_and_dec() + { decimals=0; max_length=args[0]->max_length; unsigned_flag=1; } +}; + + class Item_func_plus :public Item_num_op { public: diff --git a/sql/lex.h b/sql/lex.h index 59c71f20cd7..baabe2d16f0 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -301,6 +301,7 @@ static SYMBOL symbols[] = { { "SERIALIZABLE", SYM(SERIALIZABLE_SYM),0,0}, { "SESSION", SYM(SESSION_SYM),0,0}, { "SET", SYM(SET),0,0}, + { "SIGNED", SYM(SIGNED),0,0}, { "SHARE", SYM(SHARE_SYM),0,0}, { "SHOW", SYM(SHOW),0,0}, { "SHUTDOWN", SYM(SHUTDOWN),0,0}, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index e4e24c5ce53..a6eb447f1a1 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -447,15 +447,7 @@ static void close_connections(void) if (pthread_kill(select_thread,THR_CLIENT_ALARM)) break; // allready dead #endif -#ifdef HAVE_TIMESPEC_TS_SEC - abstime.ts_sec=time(NULL)+2; // Bsd 2.1 - abstime.ts_nsec=0; -#else - struct timeval tv; - gettimeofday(&tv,0); - abstime.tv_sec=tv.tv_sec+2; - abstime.tv_nsec=tv.tv_usec*1000; -#endif + set_timespec(abstime, 2); for (uint tmp=0 ; tmp < 10 ; tmp++) { error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count, diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc index 2f26ad81bd5..64c1b07a493 100644 --- a/sql/net_pkg.cc +++ b/sql/net_pkg.cc @@ -52,6 +52,7 @@ void send_error(NET *net, uint sql_errno, const char *err) { if (thd && thd->bootstrap) { + /* In bootstrap it's ok to print on stderr */ fprintf(stderr,"ERROR: %d %s\n",sql_errno,err); } DBUG_VOID_RETURN; @@ -120,6 +121,7 @@ net_printf(NET *net, uint errcode, ...) { if (thd && thd->bootstrap) { + /* In bootstrap it's ok to print on stderr */ fprintf(stderr,"ERROR: %d %s\n",errcode,text_pos); thd->fatal_error=1; } diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 3e4dcb75ebb..9a8d6b5e967 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -167,7 +167,7 @@ static my_bool net_realloc(NET *net, ulong length) void net_clear(NET *net) { -#ifndef EXTRA_DEBUG +#if !defined(EXTRA_DEBUG) && !defined(EMBEDDED_LIBRARY) int count; /* One may get 'unused' warn */ bool is_blocking=vio_is_blocking(net->vio); if (is_blocking) diff --git a/sql/slave.cc b/sql/slave.cc index 33c4273bcb0..f2c29146308 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -285,11 +285,11 @@ char* rewrite_db(char* db) I_List_iterator it(replicate_rewrite_db); i_string_pair* tmp; - while((tmp=it++)) - { - if (!strcmp(tmp->key, db)) - return tmp->val; - } + while ((tmp=it++)) + { + if (!strcmp(tmp->key, db)) + return tmp->val; + } return db; } @@ -310,7 +310,7 @@ int db_ok(const char* db, I_List &do_list, I_List_iterator it(do_list); i_string* tmp; - while((tmp=it++)) + while ((tmp=it++)) { if (!strcmp(tmp->ptr, db)) return 1; // match @@ -322,7 +322,7 @@ int db_ok(const char* db, I_List &do_list, I_List_iterator it(ignore_list); i_string* tmp; - while((tmp=it++)) + while ((tmp=it++)) { if (!strcmp(tmp->ptr, db)) return 0; // match @@ -346,7 +346,7 @@ static int init_strvar_from_file(char* var, int max_size, IO_CACHE* f, // if we truncated a line or stopped on last char, remove all chars // up to and including newline int c; - while( ((c=my_b_get(f)) != '\n' && c != my_b_EOF)); + while (((c=my_b_get(f)) != '\n' && c != my_b_EOF)); } return 0; } @@ -803,7 +803,7 @@ int st_master_info::wait_for_pos(THD* thd, String* log_name, ulonglong log_pos) bool pos_reached; int event_count = 0; pthread_mutex_lock(&lock); - while(!thd->killed) + while (!thd->killed) { int cmp_result; if (*log_file_name) @@ -1002,8 +1002,8 @@ server_errno=%d)", if (len == 1) { - sql_print_error("Slave: received 0 length packet from server, apparent\ - master shutdown: %s (%d)", + sql_print_error("Slave: received 0 length packet from server, apparent \ +master shutdown: %s (%d)", mc_mysql_error(mysql), read_errno); return packet_error; } @@ -1015,24 +1015,23 @@ server_errno=%d)", int check_expected_error(THD* thd, int expected_error) { - switch(expected_error) - { - case ER_NET_READ_ERROR: - case ER_NET_ERROR_ON_WRITE: - case ER_SERVER_SHUTDOWN: - case ER_NEW_ABORTING_CONNECTION: - my_snprintf(last_slave_error, sizeof(last_slave_error), - "Slave: query '%s' partially completed on the master \ + switch (expected_error) { + case ER_NET_READ_ERROR: + case ER_NET_ERROR_ON_WRITE: + case ER_SERVER_SHUTDOWN: + case ER_NEW_ABORTING_CONNECTION: + my_snprintf(last_slave_error, sizeof(last_slave_error),"\ +Slave: query '%s' partially completed on the master \ and was aborted. There is a chance that your master is inconsistent at this \ -point. If you are sure that your master is ok, run this query manually on the\ - slave and then restart the slave with SET SQL_SLAVE_SKIP_COUNTER=1;\ - SLAVE START;", thd->query); - last_slave_errno = expected_error; - sql_print_error("%s",last_slave_error); - return 1; - default: - return 0; - } +point. If you are sure that your master is ok, run this query manually on the \ +slave and then restart the slave with SET SQL_SLAVE_SKIP_COUNTER=1;\ +SLAVE START;", thd->query); + last_slave_errno = expected_error; + sql_print_error("%s",last_slave_error); + return 1; + default: + return 0; + } } @@ -1230,8 +1229,7 @@ try again, log '%s' at postion %s", RPL_LOG_NAME, goto connected; } - - while(!slave_killed(thd)) + while (!slave_killed(thd)) { thd->proc_info = "Reading master update"; ulong event_len = read_event(mysql, &glob_mi); @@ -1323,8 +1321,8 @@ the slave thread with \"mysqladmin start-slave\". We stopped at log \ events_till_disconnect++; } #endif - } // while(!slave_killed(thd)) - read/exec loop - } // while(!slave_killed(thd)) - slave loop + } // while (!slave_killed(thd)) - read/exec loop + } // while (!slave_killed(thd)) - slave loop // error = 0; err: diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 523e835f472..388abd99bd5 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -288,6 +288,11 @@ If join_results allocated new block(s) then we need call pack_cache again. pthread_mutex_lock(M);} #define MUTEX_UNLOCK(M) {DBUG_PRINT("lock", ("mutex unlock 0x%lx",\ (ulong)(M))); pthread_mutex_unlock(M);} +#define SEM_LOCK(M) { int val = 0; sem_getvalue (M, &val); \ + DBUG_PRINT("lock", ("sem lock 0x%lx (%d)", (ulong)(M), val)); \ + sem_wait(M); DBUG_PRINT("lock", ("sem lock ok")); } +#define SEM_UNLOCK(M) {DBUG_PRINT("info", ("sem unlock 0x%lx", (ulong)(M))); \ + sem_post(M); DBUG_PRINT("info", ("sem unlock ok")); } #define STRUCT_LOCK(M) {DBUG_PRINT("lock", ("%d struct lock...",__LINE__)); \ pthread_mutex_lock(M);DBUG_PRINT("lock", ("struct lock OK"));} #define STRUCT_UNLOCK(M) { \ @@ -310,6 +315,8 @@ If join_results allocated new block(s) then we need call pack_cache again. #else #define MUTEX_LOCK(M) pthread_mutex_lock(M) #define MUTEX_UNLOCK(M) pthread_mutex_unlock(M) +#define SEM_LOCK(M) sem_wait(M) +#define SEM_UNLOCK(M) sem_post(M) #define STRUCT_LOCK(M) pthread_mutex_lock(M) #define STRUCT_UNLOCK(M) pthread_mutex_unlock(M) #define BLOCK_LOCK_WR(B) B->query()->lock_writing() @@ -426,7 +433,7 @@ void Query_cache_query::init_n_lock() { DBUG_ENTER("Query_cache_query::init_n_lock"); res=0; wri = 0; len = 0; - pthread_cond_init(&lock, NULL); + sem_init(&lock, 0, 1); pthread_mutex_init(&clients_guard,MY_MUTEX_INIT_FAST); clients = 0; lock_writing(); @@ -446,7 +453,7 @@ void Query_cache_query::unlock_n_destroy() active semaphore */ this->unlock_writing(); - pthread_cond_destroy(&lock); + sem_destroy(&lock); pthread_mutex_destroy(&clients_guard); DBUG_VOID_RETURN; } @@ -462,9 +469,7 @@ void Query_cache_query::unlock_n_destroy() void Query_cache_query::lock_writing() { - MUTEX_LOCK(&clients_guard); - while (clients != 0) - pthread_cond_wait(&lock,&clients_guard); + SEM_LOCK(&lock); } @@ -478,18 +483,12 @@ void Query_cache_query::lock_writing() my_bool Query_cache_query::try_lock_writing() { DBUG_ENTER("Query_cache_block::try_lock_writing"); - if (pthread_mutex_trylock(&clients_guard)) + if (sem_trywait(&lock)!=0 || clients != 0) { - DBUG_PRINT("qcache", ("can't lock mutex")); + DBUG_PRINT("info", ("can't lock semaphore")); DBUG_RETURN(0); } - if (clients != 0) - { - DBUG_PRINT("info", ("already locked (r)")); - MUTEX_UNLOCK(&clients_guard); - DBUG_RETURN(0); - } - DBUG_PRINT("qcache", ("mutex 'lock' 0x%lx locked", (ulong) &lock)); + DBUG_PRINT("info", ("mutex 'lock' 0x%lx locked", (ulong) &lock)); DBUG_RETURN(1); } @@ -497,23 +496,28 @@ my_bool Query_cache_query::try_lock_writing() void Query_cache_query::lock_reading() { MUTEX_LOCK(&clients_guard); - clients++; + if ( ++clients == 1 ) + SEM_LOCK(&lock); MUTEX_UNLOCK(&clients_guard); } void Query_cache_query::unlock_writing() { - MUTEX_UNLOCK(&clients_guard); + SEM_UNLOCK(&lock); } void Query_cache_query::unlock_reading() { + /* + To avoid unlocking semaphore before unlocking mutex (that may cause + destroying locked mutex), we use temporary boolean variable 'unlock'. + */ MUTEX_LOCK(&clients_guard); - if (--clients == 0) - pthread_cond_broadcast(&lock); + bool ulock = ((--clients) == 0); MUTEX_UNLOCK(&clients_guard); + if (ulock) SEM_UNLOCK(&lock); } extern "C" @@ -1377,8 +1381,11 @@ void Query_cache::free_cache(my_bool destruction) /* Becasue we did a flush, all cache memory must be in one this block */ bins[0].free_blocks->destroy(); total_blocks--; - DBUG_PRINT("qcache", ("free memory %lu (should be %lu)", - free_memory , query_cache_size)); +#ifndef DBUG_OFF + if (free_memory != query_cache_size) + DBUG_PRINT("qcache", ("free memory %lu (should be %lu)", + free_memory , query_cache_size)); +#endif my_free((gptr) cache, MYF(MY_ALLOW_ZERO_PTR)); make_disabled(); hash_free(&queries); @@ -2573,7 +2580,7 @@ my_bool Query_cache::move_by_type(byte **border, } while ( result_block != first_result_block ); } Query_cache_query *new_query= ((Query_cache_query *) new_block->data()); - pthread_cond_init(&new_query->lock, NULL); + sem_init(&new_query->lock, 0, 1); pthread_mutex_init(&new_query->clients_guard,MY_MUTEX_INIT_FAST); /* @@ -2948,6 +2955,7 @@ my_bool Query_cache::check_integrity() my_bool result = 0; uint i; STRUCT_LOCK(&structure_guard_mutex); + DBUG_ENTER("check_integrity"); if (hash_check(&queries)) { @@ -3030,6 +3038,8 @@ my_bool Query_cache::check_integrity() result = 1; break; case Query_cache_block::RES_INCOMPLETE: + // This type of block can be not lincked yet (in multithread environment) + break; case Query_cache_block::RES_BEG: case Query_cache_block::RES_CONT: case Query_cache_block::RESULT: @@ -3048,11 +3058,13 @@ my_bool Query_cache::check_integrity() } else { + BLOCK_LOCK_RD(query_block); if (in_list(queries_blocks, query_block, "query from results")) result = 1; if (in_list(query_block->query()->result(), block, "results")) result = 1; + BLOCK_UNLOCK_RD(query_block); } break; } @@ -3160,15 +3172,15 @@ my_bool Query_cache::check_integrity() } while (block != bins[i].free_blocks); if (count != bins[i].number) { - DBUG_PRINT("qcache", ("bin[%d].number is %d, but bin have %d blocks", - bins[i].number, count)); + DBUG_PRINT("error", ("bin[%d].number is %d, but bin have %d blocks", + bins[i].number, count)); result = 1; } } } DBUG_ASSERT(result == 0); STRUCT_UNLOCK(&structure_guard_mutex); - return result; + DBUG_RETURN(result); } diff --git a/sql/sql_cache.h b/sql/sql_cache.h index 50ae765e446..bde11d2dbb6 100644 --- a/sql/sql_cache.h +++ b/sql/sql_cache.h @@ -55,6 +55,8 @@ #define TABLE_COUNTER_TYPE uint8 +#include + struct Query_cache_block; struct Query_cache_block_table; struct Query_cache_table; @@ -107,7 +109,7 @@ struct Query_cache_query Query_cache_block *res; NET *wri; ulong len; - pthread_cond_t lock; // R/W lock of block + sem_t lock; // R/W lock of block pthread_mutex_t clients_guard; uint clients; @@ -396,5 +398,8 @@ protected: }; extern Query_cache query_cache; +void query_cache_insert(NET *net, const char *packet, ulong length); +void query_cache_end_of_result(NET *net); +void query_cache_abort(NET *net); #endif diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 06a1818b50d..75feca8d759 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -988,23 +988,12 @@ static pthread_handler_decl(handle_delayed_insert,arg) if (!di->status && !di->stacked_inserts) { struct timespec abstime; -#if defined(HAVE_TIMESPEC_TS_SEC) - abstime.ts_sec=time((time_t*) 0)+(time_t) delayed_insert_timeout; - abstime.ts_nsec=0; -#elif defined(__WIN__) - abstime.tv_sec=time((time_t*) 0)+(time_t) delayed_insert_timeout; - abstime.tv_nsec=0; -#else - struct timeval tv; - gettimeofday(&tv,0); - abstime.tv_sec=tv.tv_sec+(time_t) delayed_insert_timeout; - abstime.tv_nsec=tv.tv_usec*1000; -#endif + set_timespec(abstime, delayed_insert_timeout); /* Information for pthread_kill */ di->thd.mysys_var->current_mutex= &di->mutex; di->thd.mysys_var->current_cond= &di->cond; - di->thd.proc_info=0; + di->thd.proc_info="Waiting for INSERT"; DBUG_PRINT("info",("Waiting for someone to insert rows")); while (!thd->killed) @@ -1039,6 +1028,7 @@ static pthread_handler_decl(handle_delayed_insert,arg) pthread_mutex_unlock(&di->thd.mysys_var->mutex); pthread_mutex_lock(&di->mutex); } + di->thd.proc_info=0; if (di->tables_in_use && ! thd->lock) { diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc index 53953c96d0b..13cac83fc3f 100644 --- a/sql/sql_manager.cc +++ b/sql/sql_manager.cc @@ -55,13 +55,7 @@ pthread_handler_decl(handle_manager,arg __attribute__((unused))) { if (reset_flush_time) { -#ifdef HAVE_TIMESPEC_TS_SEC - abstime.ts_sec = time(NULL)+flush_time; // Bsd 2.1 - abstime.ts_nsec = 0; -#else - abstime.tv_sec = time(NULL)+flush_time; // Linux or Solairs - abstime.tv_nsec = 0; -#endif + set_timespec(abstime, flush_time); reset_flush_time = FALSE; } while (!manager_status && !error && !abort_loop) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3662aa301e2..f61624dbe52 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -89,8 +89,8 @@ static void test_signal(int sig_ptr) MessageBox(NULL,"Test signal","DBUG",MB_OK); #endif #if defined(OS2) - fprintf( stderr, "Test signal %d\n", sig_ptr); - fflush( stderr); + fprintf(stderr, "Test signal %d\n", sig_ptr); + fflush(stderr); #endif } static void init_signals(void) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index bfee5f9235b..c65654faefb 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -607,25 +607,14 @@ int stop_slave(THD* thd, bool net_report ) // do not abort the slave in the middle of a query, so we do not set // thd->killed for the slave thread thd->proc_info = "waiting for slave to die"; - while(slave_running) + while (slave_running) { - /* there is a small chance that slave thread might miss the first - alarm. To protect againts it, resend the signal until it reacts + /* + There is a small chance that slave thread might miss the first + alarm. To protect againts it, resend the signal until it reacts */ - struct timespec abstime; -#ifdef HAVE_TIMESPEC_TS_SEC - abstime.ts_sec=time(NULL)+2; - abstime.ts_nsec=0; -#elif defined(__WIN__) - abstime.tv_sec=time((time_t*) 0)+2; - abstime.tv_nsec=0; -#else - struct timeval tv; - gettimeofday(&tv,0); - abstime.tv_sec=tv.tv_sec+2; - abstime.tv_nsec=tv.tv_usec*1000; -#endif + set_timespec(abstime, 2); pthread_cond_timedwait(&COND_slave_stopped, &LOCK_slave, &abstime); if (slave_running) KICK_SLAVE; @@ -659,8 +648,8 @@ void reset_slave() pthread_mutex_lock(&LOCK_slave); if ((slave_was_running = slave_running)) { - pthread_mutex_unlock(&LOCK_slave); - stop_slave(0,0); + pthread_mutex_unlock(&LOCK_slave); + stop_slave(0,0); } else pthread_mutex_unlock(&LOCK_slave); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 821ec3fe972..8ffeb70e912 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -652,6 +652,8 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list) item->maybe_null=1; field_list.push_back(item=new Item_empty_string("Packed",10)); item->maybe_null=1; + field_list.push_back(new Item_empty_string("Null",3)); + field_list.push_back(new Item_empty_string("Index_type",16)); field_list.push_back(new Item_empty_string("Comment",255)); item->maybe_null=1; @@ -691,6 +693,8 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list) } else net_store_null(packet); + + /* Check if we have a key part that only uses part of the field */ if (!key_part->field || key_part->length != table->field[key_part->fieldnr-1]->key_length()) @@ -701,8 +705,14 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list) else net_store_null(packet); net_store_null(packet); // No pack_information yet - net_store_data(packet,convert, - key_info->flags & HA_FULLTEXT ? "FULLTEXT":""); + + /* Null flag */ + uint flags= key_part->field ? key_part->field->flags : 0; + char *pos=(byte*) ((flags & NOT_NULL_FLAG) ? "" : "YES"); + net_store_data(packet,convert,(const char*) pos); + net_store_data(packet,convert,table->file->index_type(i)); + /* Comment */ + net_store_data(packet,convert,""); if (my_net_write(&thd->net,(char*) packet->ptr(),packet->length())) DBUG_RETURN(1); /* purecov: inspected */ } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6ded046ccbf..ac0748d1497 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -26,6 +26,7 @@ #endif extern HASH open_cache; +static const char *primary_key_name="PRIMARY"; static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end); static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end); @@ -196,6 +197,48 @@ int quick_rm_table(enum db_type base,const char *db, return ha_delete_table(base,path) || error; } +/* + Sort keys in the following order: + - PRIMARY KEY + - UNIQUE keyws where all column are NOT NULL + - Other UNIQUE keys + - Normal keys + - Fulltext keys + + This will make checking for duplicated keys faster and ensure that + PRIMARY keys are prioritized. +*/ + + +static int sort_keys(KEY *a, KEY *b) +{ + if (a == b) // Safety + return 0; + if (a->flags & HA_NOSAME) + { + if (!(b->flags & HA_NOSAME)) + return -1; + if ((a->flags ^ b->flags) & HA_NULL_PART_KEY) + { + /* Sort NOT NULL keys before other keys */ + return (a->flags & HA_NULL_PART_KEY) ? 1 : -1; + } + if (a->name == primary_key_name) + return -1; + if (b->name == primary_key_name) + return 1; + } + else if (b->flags & HA_NOSAME) + return 1; // Prefer b + + if ((a->flags ^ b->flags) & HA_FULLTEXT) + { + return (a->flags & HA_FULLTEXT) ? 1 : -1; + } + return a < b ? -1 : 1; // Prefer original key order +} + + /***************************************************************************** * Create a table. * If one creates a temporary table, this is automaticly opened @@ -351,8 +394,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, List_iterator key_iterator(keys); uint key_parts=0,key_count=keys.elements; List keys_in_order; // Add new keys here - Key *primary_key=0; - bool unique_key=0; + bool primary_key=0,unique_key=0; Key *key; uint tmp; tmp=min(file->max_keys(), MAX_KEY); @@ -362,12 +404,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, DBUG_RETURN(-1); } - /* - Check keys; - Put PRIMARY KEY first, then UNIQUE keys and other keys last - This will make checking for duplicated keys faster and ensure that - primary keys are prioritized. - */ + /* Calculate number of key segements */ while ((key=key_iterator++)) { @@ -383,33 +420,6 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, DBUG_RETURN(-1); } key_parts+=key->columns.elements; - if (key->type == Key::PRIMARY) - { - if (primary_key) - { - my_error(ER_MULTIPLE_PRI_KEY,MYF(0)); - DBUG_RETURN(-1); - } - primary_key=key; - } - else if (key->type == Key::UNIQUE) - { - unique_key=1; - if (keys_in_order.push_front(key)) - DBUG_RETURN(-1); - } - else if (keys_in_order.push_back(key)) - DBUG_RETURN(-1); - } - if (primary_key) - { - if (keys_in_order.push_front(primary_key)) - DBUG_RETURN(-1); - } - else if (!unique_key && (file->option_flag() & HA_REQUIRE_PRIMARY_KEY)) - { - my_error(ER_REQUIRES_PRIMARY_KEY,MYF(0)); - DBUG_RETURN(-1); } key_info_buffer=key_info=(KEY*) sql_calloc(sizeof(KEY)*key_count); @@ -417,8 +427,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, if (!key_info_buffer || ! key_part_info) DBUG_RETURN(-1); // Out of memory - List_iterator key_iterator_in_order(keys_in_order); - for (; (key=key_iterator_in_order++) ; key_info++) + key_iterator.rewind(); + for (; (key=key_iterator++) ; key_info++) { uint key_length=0; key_part_spec *column; @@ -486,6 +496,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, MYF(0),column->field_name); DBUG_RETURN(-1); } + key_info->flags|= HA_NULL_PART_KEY; } if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) { @@ -545,7 +556,15 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, if (column_nr == 0) { if (key->type == Key::PRIMARY) - key_name="PRIMARY"; + { + if (primary_key) + { + my_error(ER_MULTIPLE_PRI_KEY,MYF(0)); + DBUG_RETURN(-1); + } + key_name=primary_key_name; + primary_key=1; + } else if (!(key_name = key->name())) key_name=make_unique_key_name(sql_field->field_name, key_info_buffer,key_info); @@ -557,6 +576,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, key_info->name=(char*) key_name; } } + if (!(key_info->flags & HA_NULL_PART_KEY)) + unique_key=1; key_info->key_length=(uint16) key_length; uint max_key_length= max(file->max_key_length(), MAX_KEY_LENGTH); if (key_length > max_key_length && key->type != Key::FULLTEXT) @@ -565,11 +586,19 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, DBUG_RETURN(-1); } } + if (!unique_key && !primary_key && + (file->option_flag() & HA_REQUIRE_PRIMARY_KEY)) + { + my_error(ER_REQUIRES_PRIMARY_KEY,MYF(0)); + DBUG_RETURN(-1); + } if (auto_increment > 0) { my_error(ER_WRONG_AUTO_KEY,MYF(0)); DBUG_RETURN(-1); } + /* Sort keys in optimized order */ + qsort((gptr) key_info_buffer, key_count, sizeof(KEY), (qsort_cmp) sort_keys); /* Check if table exists */ if (create_info->options & HA_LEX_CREATE_TMP_TABLE) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 5282fb157e6..382e007447d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -351,6 +351,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token PRECISION %token QUICK %token REAL +%token SIGNED %token SMALLINT %token STRING_SYM %token TEXT_SYM @@ -1009,7 +1010,8 @@ field_opt_list: | field_option {} field_option: - UNSIGNED { Lex->type|= UNSIGNED_FLAG;} + SIGNED {} + | UNSIGNED { Lex->type|= UNSIGNED_FLAG;} | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; } opt_len: @@ -1595,7 +1597,9 @@ simple_expr: | MATCH ident_list_arg AGAINST '(' expr IN_SYM BOOLEAN_SYM MODE_SYM ')' { Select->ftfunc_list.push_back((Item_func_match *) ($$=new Item_func_match_bool(*$2,$5))); } - | BINARY expr %prec NEG { $$= new Item_func_binary($2); } + | BINARY expr %prec NEG { $$= new Item_func_binary($2); } + | SIGNED expr %prec NEG { $$= new Item_func_signed($2); } + | UNSIGNED expr %prec NEG { $$= new Item_func_unsigned($2); } | CASE_SYM opt_expr WHEN_SYM when_list opt_else END { $$= new Item_func_case(* $4, $2, $5 ) } | FUNC_ARG0 '(' ')'