diff options
author | unknown <monty@hundin.mysql.fi> | 2002-10-16 13:11:25 +0300 |
---|---|---|
committer | unknown <monty@hundin.mysql.fi> | 2002-10-16 13:11:25 +0300 |
commit | 7013d8ef0ae0a21fadfcc0a159ee1d83fdad8a9d (patch) | |
tree | d165b4baadac24102545d94c8f9fe180537a64f5 | |
parent | e1d7b8414f14de681127f4e19340e4f7737d5bdb (diff) | |
parent | 74b73109c1304e62430faa85d2a63a6f2ffa626d (diff) | |
download | mariadb-git-7013d8ef0ae0a21fadfcc0a159ee1d83fdad8a9d.tar.gz |
Merge with 3.23.54
BitKeeper/etc/logging_ok:
auto-union
BitKeeper/deleted/.del-LICENSE~4cfaff8de837acb8:
Auto merged
BitKeeper/deleted/.del-MySQLEULA.txt:
Delete: Docs/MySQLEULA.txt
BitKeeper/deleted/.del-global.h~e80d28157acfdcb5:
Auto merged
Build-tools/mysql-copyright-2:
Auto merged
Build-tools/mysql-copyright:
Auto merged
heap/heapdef.h:
Auto merged
heap/hp_open.c:
Auto merged
innobase/btr/btr0cur.c:
Auto merged
innobase/lock/lock0lock.c:
Auto merged
innobase/os/os0file.c:
Auto merged
innobase/os/os0thread.c:
Auto merged
myisam/mi_open.c:
Auto merged
mysql-test/Makefile.am:
Auto merged
mysql-test/t/null_key.test:
Auto merged
mysys/safemalloc.c:
Auto merged
scripts/make_binary_distribution.sh:
Auto merged
scripts/mysqld_safe.sh:
Auto merged
scripts/mysqlhotcopy.sh:
Auto merged
sql/field.h:
Auto merged
sql/field_conv.cc:
Auto merged
sql/ha_innodb.h:
Auto merged
sql/item.cc:
Auto merged
sql/sql_db.cc:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_select.cc:
Auto merged
sql/table.cc:
Auto merged
tests/grant.res:
Auto merged
Build-tools/Do-compile:
merge
Docs/manual.texi:
merge
configure.in:
merge
mysql-test/r/distinct.result:
merge
mysql-test/r/null_key.result:
merge
sql/ha_innodb.cc:
merge
sql/item.h:
merge
sql/log.cc:
merge
sql/mysqld.cc:
merge
support-files/mysql.spec.sh:
merge
-rw-r--r-- | BitKeeper/etc/logging_ok | 6 | ||||
-rwxr-xr-x | Build-tools/Do-compile | 8 | ||||
-rw-r--r-- | Docs/manual.texi | 36 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | heap/heapdef.h | 11 | ||||
-rw-r--r-- | heap/hp_open.c | 10 | ||||
-rw-r--r-- | innobase/btr/btr0cur.c | 62 | ||||
-rw-r--r-- | innobase/include/btr0cur.h | 2 | ||||
-rw-r--r-- | innobase/include/os0thread.h | 9 | ||||
-rw-r--r-- | innobase/lock/lock0lock.c | 33 | ||||
-rw-r--r-- | innobase/os/os0file.c | 2 | ||||
-rw-r--r-- | innobase/os/os0thread.c | 4 | ||||
-rw-r--r-- | myisam/mi_open.c | 2 | ||||
-rw-r--r-- | mysql-test/r/distinct.result | 2 | ||||
-rw-r--r-- | mysql-test/r/null_key.result | 6 | ||||
-rw-r--r-- | mysql-test/t/null_key.test | 44 | ||||
-rw-r--r-- | mysys/safemalloc.c | 7 | ||||
-rw-r--r-- | scripts/mysqlhotcopy.sh | 6 | ||||
-rw-r--r-- | sql/field.h | 1 | ||||
-rw-r--r-- | sql/field_conv.cc | 55 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 63 | ||||
-rw-r--r-- | sql/item.cc | 42 | ||||
-rw-r--r-- | sql/item.h | 3 | ||||
-rw-r--r-- | sql/log.cc | 4 | ||||
-rw-r--r-- | sql/mysqld.cc | 1 | ||||
-rw-r--r-- | sql/sql_db.cc | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 8 | ||||
-rw-r--r-- | sql/sql_select.cc | 30 | ||||
-rw-r--r-- | sql/table.cc | 7 |
29 files changed, 392 insertions, 76 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 55c64144268..5e3b2fae9bd 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -1,3 +1,4 @@ +Administrador@light. Administrator@co3064164-a. Administrator@co3064164-a.rochd1.qld.optushome.com.au Administrator@fred. @@ -47,6 +48,7 @@ monty@tramp.mysql.fi monty@work.mysql.com mwagner@cash.mwagner.org mwagner@evoq.mwagner.org +mwagner@work.mysql.com nick@mysql.com nick@nick.leippe.com paul@central.snake.net @@ -62,6 +64,7 @@ serg@build.mysql2.com serg@serg.mysql.com serg@sergbook.mysql.com sinisa@rhols221.adsl.netsonic.fi +tfr@beta.frontier86.ee tfr@indrek.tfr.cafe.ee tfr@sarvik.tfr.cafe.ee tim@bitch.mysql.fi @@ -82,6 +85,3 @@ worm@altair.is.lan zak@balfor.local zak@linux.local zgreant@mysql.com -tfr@beta.frontier86.ee -Administrador@light. -mwagner@work.mysql.com diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile index 2e4da3091b0..9f62b617056 100755 --- a/Build-tools/Do-compile +++ b/Build-tools/Do-compile @@ -374,14 +374,14 @@ if ($opt_stage <= 9 && !$opt_no_test) log_system("rm -f output/*"); $tmp= $opt_fast_benchmark ? "--fast --user root --small-test" : ""; check_system("perl ./run-all-tests --log --die-on-errors $connect_option $tmp","RUN-mysql"); - if ($opt_bdb) - { - check_system("perl ./run-all-tests --log --suffix=\"_bdb\" --die-on-errors $connect_option $tmp --create-option=\"type=bdb\"","RUN-mysql"); - } if ($opt_innodb) { check_system("perl ./run-all-tests --log --suffix=\"_innodb\" --die-on-errors $connect_option $tmp --create-option=\"type=innodb\"","RUN-mysql"); } + if ($opt_bdb) + { + check_system("perl ./run-all-tests --log --suffix=\"_bdb\" --die-on-errors $connect_option $tmp --create-option=\"type=bdb\"","RUN-mysql"); + } } rm_all($bench_tmpdir); diff --git a/Docs/manual.texi b/Docs/manual.texi index 5d67cb08fff..c53bd24ac86 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -51592,6 +51592,7 @@ users use this code as the rest of the code and because of this we are not yet 100% confident in this code. @menu +* News-3.23.54:: Changes in release 3.23.54 * News-3.23.53:: Changes in release 3.23.53 * News-3.23.52:: Changes in release 3.23.52 (14 Aug 2002) * News-3.23.51:: Changes in release 3.23.51 (31 May 2002) @@ -51649,12 +51650,45 @@ not yet 100% confident in this code. * News-3.23.0:: Changes in release 3.23.0 (05 Aug 1999: Alpha) @end menu -@node News-3.23.53, News-3.23.52, News-3.23.x, News-3.23.x +@node News-3.23.54, News-3.23.53, News-3.23.x, News-3.23.x +@appendixsubsec Changes in release 3.23.54 +@itemize +@item +Fixed reference to freed memory when doing complicated @code{GROUP BY +... ORDER BY} queries. Symptom was that @code{mysqld} died in function +@code{send_fields}. +@item +Allocate heap rows in smaller blocks to get better memory usage. +@item +Fixed memory allocation bug when storing BLOB values in internal +temporary tables used for some (unlikely) @code{GROUP BY} queries. +@item +Fixed a bug in key optimizing handling where the expression +@code{WHERE column_name = key_column_name} was calculated as true +for @code{NULL} values. +@item +Fixed core dump bug when doing @code{LEFT JOIN ... WHERE key_column=NULL}. +@end itemize + +@node News-3.23.53, News-3.23.52, News-3.23.54, News-3.23.x @appendixsubsec Changes in release 3.23.53 @itemize @bullet @item +Fixed crash when @code{SHOW INNODB STATUS} was used and @code{skip-innodb} +was defined. +@item +Fixed possible memory corruption bug in binary log file handling when +slave rotated the logs (only affected 3.23, not 4.0). +@item +Fixed problem in @code{LOCK TABLES} on windows when one connects to a +database that contains upper case letters. +@item +Fixed that @code{--skip-show-databases} doesn't reset the @code{--port} option. +@item Small fix in @code{safe_mysqld} for some shells. @item +Fixed that @code{FLUSH STATUS} doesn't reset @code{Delayed_insert_threads}. +@item Fixed that @code{SHOW STATUS} doesn't reset @code{Delayed_insert_threads}. @item Fixed core dump bug when using the @code{BINARY} cast on a @code{NULL} value. diff --git a/configure.in b/configure.in index 417e28b29d4..093b5aa8344 100644 --- a/configure.in +++ b/configure.in @@ -737,7 +737,7 @@ AC_ARG_WITH(libwrap, _libs=${LIBS} AC_CHECK_HEADER(tcpd.h, - LIBS="$LIBS -lwrap" + LIBS="-lwrap $LIBS" AC_MSG_CHECKING(for TCP wrappers library -lwrap) AC_TRY_LINK([#include <tcpd.h> int allow_severity = 0; diff --git a/heap/heapdef.h b/heap/heapdef.h index bdd7de45370..ef55cf5efd2 100644 --- a/heap/heapdef.h +++ b/heap/heapdef.h @@ -22,6 +22,17 @@ #endif #include "heap.h" /* Structs & some defines */ +/* + When allocating keys /rows in the internal block structure, do it + within the following boundaries. + + The challenge is to find the balance between allocate as few blocks + as possible and keep memory consumption down. +*/ + +#define HP_MIN_RECORDS_IN_BLOCK 16 +#define HP_MAX_RECORDS_IN_BLOCK 8192 + /* Some extern variables */ extern LIST *heap_open_list,*heap_share_list; diff --git a/heap/hp_open.c b/heap/hp_open.c index 938ab8c4f78..1bb28e5ffdf 100644 --- a/heap/hp_open.c +++ b/heap/hp_open.c @@ -162,8 +162,14 @@ static void init_block(HP_BLOCK *block, uint reclength, ulong min_records, max_records=1000; /* As good as quess as anything */ recbuffer=(uint) (reclength+sizeof(byte**)-1) & ~(sizeof(byte**)-1); records_in_block=max_records/10; - if (records_in_block < 10 && max_records) - records_in_block=10; + if (records_in_block < HP_MIN_RECORDS_IN_BLOCK && max_records) + records_in_block= HP_MIN_RECORDS_IN_BLOCK; + /* + Don't allocate too many rows at one time too keep memory consumption + done when we don't need it. + */ + if (records_in_block > HP_MAX_RECORDS_IN_BLOCK) + records_in_block= HP_MAX_RECORDS_IN_BLOCK; if (!records_in_block || records_in_block*recbuffer > (my_default_record_cache_size-sizeof(HP_PTRS)*HP_MAX_LEVELS)) records_in_block=(my_default_record_cache_size-sizeof(HP_PTRS)* diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index e35ff2ca69e..3d6b63def6c 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -2531,7 +2531,7 @@ btr_cur_add_path_info( /*********************************************************************** Estimates the number of rows in a given index range. */ -ulint +ib_longlong btr_estimate_n_rows_in_range( /*=========================*/ /* out: estimated number of rows */ @@ -2547,8 +2547,9 @@ btr_estimate_n_rows_in_range( btr_path_t* slot1; btr_path_t* slot2; ibool diverged; + ibool diverged_lot; ulint divergence_level; - ulint n_rows; + ib_longlong n_rows; ulint i; mtr_t mtr; @@ -2589,10 +2590,13 @@ btr_estimate_n_rows_in_range( /* We have the path information for the range in path1 and path2 */ n_rows = 1; - diverged = FALSE; - divergence_level = 1000000; - - for (i = 0; ; i++) { + diverged = FALSE; /* This becomes true when the path is not + the same any more */ + diverged_lot = FALSE; /* This becomes true when the paths are + not the same or adjacent any more */ + divergence_level = 1000000; /* This is the level where paths diverged + a lot */ + for (i = 0; ; i++) { ut_ad(i < BTR_PATH_ARRAY_N_SLOTS); slot1 = path1 + i; @@ -2608,13 +2612,36 @@ btr_estimate_n_rows_in_range( n_rows = n_rows * 2; } + + /* Do not estimate the number of rows in the range + to over 1 / 2 of the estimated rows in the whole + table */ + + if (n_rows > index->table->stat_n_rows / 2) { + n_rows = index->table->stat_n_rows / 2; + + /* If there are just 0 or 1 rows in the table, + then we estimate all rows are in the range */ + + if (n_rows == 0) { + n_rows = index->table->stat_n_rows; + } + } + return(n_rows); } if (!diverged && slot1->nth_rec != slot2->nth_rec) { + diverged = TRUE; + if (slot1->nth_rec < slot2->nth_rec) { n_rows = slot2->nth_rec - slot1->nth_rec; + + if (n_rows > 1) { + diverged_lot = TRUE; + divergence_level = i; + } } else { /* Maybe the tree has changed between searches */ @@ -2622,10 +2649,27 @@ btr_estimate_n_rows_in_range( return(10); } - divergence_level = i; + } else if (diverged && !diverged_lot) { + + if (slot1->nth_rec < slot1->n_recs + || slot2->nth_rec > 1) { + + diverged_lot = TRUE; + divergence_level = i; + + n_rows = 0; + + if (slot1->nth_rec < slot1->n_recs) { + n_rows += slot1->n_recs + - slot1->nth_rec; + } + + if (slot2->nth_rec > 1) { + n_rows += slot2->nth_rec - 1; + } + } + } else if (diverged_lot) { - diverged = TRUE; - } else if (diverged) { n_rows = (n_rows * (slot1->n_recs + slot2->n_recs)) / 2; } diff --git a/innobase/include/btr0cur.h b/innobase/include/btr0cur.h index b01cbd9a875..7039ceba245 100644 --- a/innobase/include/btr0cur.h +++ b/innobase/include/btr0cur.h @@ -417,7 +417,7 @@ btr_cur_parse_del_mark_set_sec_rec( /*********************************************************************** Estimates the number of rows in a given index range. */ -ulint +ib_longlong btr_estimate_n_rows_in_range( /*=========================*/ /* out: estimated number of rows */ diff --git a/innobase/include/os0thread.h b/innobase/include/os0thread.h index 9459750719f..8355afa46e9 100644 --- a/innobase/include/os0thread.h +++ b/innobase/include/os0thread.h @@ -15,7 +15,16 @@ Created 9/8/1995 Heikki Tuuri /* Maximum number of threads which can be created in the program; this is also the size of the wait slot array for MySQL threads which can wait inside InnoDB */ +#ifdef __WIN__ +/* Windows 95/98/ME seemed to have difficulties creating the all +the event semaphores for the wait array slots. If the computer had +<= 64 MB memory, InnoDB startup could take minutes or even crash. +That is why we set this to only 1000 in Windows. */ + +#define OS_THREAD_MAX_N 1000 +#else #define OS_THREAD_MAX_N 10000 +#endif /* Possible fixed priorities for threads */ #define OS_THREAD_PRIORITY_NONE 100 diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index ebd063b6ca5..866fe556af9 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -2011,6 +2011,19 @@ lock_grant( ut_ad(mutex_own(&kernel_mutex)); lock_reset_lock_and_trx_wait(lock); + + if (lock_get_mode(lock) == LOCK_AUTO_INC) { + + if (lock->trx->auto_inc_lock != NULL) { + fprintf(stderr, + "InnoDB: Error: trx already had an AUTO-INC lock!\n"); + } + + /* Store pointer to lock to trx so that we know to + release it at the end of the SQL statement */ + + lock->trx->auto_inc_lock = lock; + } if (lock_print_waits) { printf("Lock wait for trx %lu ends\n", @@ -3763,6 +3776,8 @@ lock_print_info( mtr_t mtr; if (buf_end - buf < 600) { + sprintf(buf, "... output truncated!\n"); + return; } @@ -3787,6 +3802,9 @@ lock_print_info( if ((ulint)(buf_end - buf) < 100 + strlen(lock_latest_err_buf)) { + lock_mutex_exit_kernel(); + sprintf(buf, "... output truncated!\n"); + return; } @@ -3794,6 +3812,9 @@ lock_print_info( } if (buf_end - buf < 600) { + lock_mutex_exit_kernel(); + sprintf(buf, "... output truncated!\n"); + return; } @@ -3805,6 +3826,9 @@ lock_print_info( while (trx) { if (buf_end - buf < 900) { + lock_mutex_exit_kernel(); + sprintf(buf, "... output truncated!\n"); + return; } @@ -3842,6 +3866,9 @@ loop: } if (buf_end - buf < 900) { + lock_mutex_exit_kernel(); + sprintf(buf, "... output truncated!\n"); + return; } @@ -3852,6 +3879,9 @@ loop: buf += strlen(buf); if (buf_end - buf < 500) { + lock_mutex_exit_kernel(); + sprintf(buf, "... output truncated!\n"); + return; } @@ -3906,6 +3936,9 @@ loop: } if (buf_end - buf < 500) { + lock_mutex_exit_kernel(); + sprintf(buf, "... output truncated!\n"); + return; } diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index b2881581fc7..098d5b25e89 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -1034,6 +1034,8 @@ try_again: ibool retry; ssize_t ret; + os_bytes_read_since_printout += n; + try_again: ret = os_file_pread(file, buf, n, offset, offset_high); diff --git a/innobase/os/os0thread.c b/innobase/os/os0thread.c index 146303b2791..48aea4b8abb 100644 --- a/innobase/os/os0thread.c +++ b/innobase/os/os0thread.c @@ -52,8 +52,8 @@ os_thread_pf( /*=========*/ os_thread_id_t a) { -#ifdef UNIV_HPUX - /* In HP-UX a pthread_t is a struct of 3 fields: field1, field2, +#ifdef UNIV_HPUX10 + /* In HP-UX-10.20 a pthread_t is a struct of 3 fields: field1, field2, field3. We do not know if field1 determines the thread uniquely. */ return((ulint)(a.field1)); diff --git a/myisam/mi_open.c b/myisam/mi_open.c index f621e4b760c..e06726fcaaa 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -213,7 +213,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) max_data_file_length= (share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? (((ulonglong) 1 << (share->base.rec_reflength*8))-1) : - (mi_safe_mul(share->base.reclength, + (mi_safe_mul(share->base.pack_reclength, (ulonglong) 1 << (share->base.rec_reflength*8))-1); max_key_file_length= mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH, diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 68fb8c39e6c..c9b90094f77 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -190,7 +190,7 @@ insert into t3 select * from t4; explain select distinct t1.a from t1,t3 where t1.a=t3.a; table type possible_keys key key_len ref rows Extra t1 index PRIMARY PRIMARY 4 NULL 2 Using index; Using temporary -t3 ref a a 5 t1.a 10 Using index; Distinct +t3 ref a a 5 t1.a 10 where used; Using index; Distinct select distinct t1.a from t1,t3 where t1.a=t3.a; a 1 diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result index a28830a696d..91cd9dbbc7c 100644 --- a/mysql-test/r/null_key.result +++ b/mysql-test/r/null_key.result @@ -188,4 +188,10 @@ id uniq_id 4 2 7 3 8 4 +order_id product_id product_type +order_id product_id product_type +3d7ce39b5d4b3e3d22aaafe9b633de51 1206029 3 +3d7ce39b5d4b3e3d22aaafe9b633de51 5880836 3 +id id +id id DROP table t1,t2; diff --git a/mysql-test/t/null_key.test b/mysql-test/t/null_key.test index e5d8fc59e4f..3ab8b993f43 100644 --- a/mysql-test/t/null_key.test +++ b/mysql-test/t/null_key.test @@ -91,3 +91,47 @@ DELETE FROM t2 WHERE uniq_id IS NULL; SELECT * FROM t1 ORDER BY uniq_id, id; SELECT * FROM t2 ORDER BY uniq_id, id; DROP table t1,t2; + +# +# This crashed MySQL 3.23.47 +# + +CREATE TABLE `t1` ( + `order_id` char(32) NOT NULL default '', + `product_id` char(32) NOT NULL default '', + `product_type` int(11) NOT NULL default '0', + PRIMARY KEY (`order_id`,`product_id`,`product_type`) +) TYPE=MyISAM; +CREATE TABLE `t2` ( + `order_id` char(32) NOT NULL default '', + `product_id` char(32) NOT NULL default '', + `product_type` int(11) NOT NULL default '0', + PRIMARY KEY (`order_id`,`product_id`,`product_type`) +) TYPE=MyISAM; +INSERT INTO t1 (order_id, product_id, product_type) VALUES +('3d7ce39b5d4b3e3d22aaafe9b633de51',1206029, 3), +('3d7ce39b5d4b3e3d22aaafe9b633de51',5880836, 3), +('9d9aad7764b5b2c53004348ef8d34500',2315652, 3); +INSERT INTO t2 (order_id, product_id, product_type) VALUES +('9d9aad7764b5b2c53004348ef8d34500',2315652, 3); + +select t1.* from t1 +left join t2 using(order_id, product_id, product_type) +where t2.order_id=NULL; +select t1.* from t1 +left join t2 using(order_id, product_id, product_type) +where t2.order_id is NULL; +drop table t1,t2; + +# +# The last select returned wrong results in 3.23.52 +# + +create table t1 (id int); +insert into t1 values (null), (0); +create table t2 (id int); +insert into t2 values (null); +select * from t1, t2 where t1.id = t2.id; +alter table t1 add key id (id); +select * from t1, t2 where t1.id = t2.id; +drop table t1,t2; diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index 2b990448b08..89079fba31c 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -201,9 +201,7 @@ gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags) pthread_mutex_unlock(&THR_LOCK_malloc); /* Set the memory to the aribtrary wierd value */ -#ifdef HAVE_purify - if (MyFlags & MY_ZEROFILL) -#endif + if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick) bfill(&pTmp -> aData[sf_malloc_prehunc],uSize, (char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL)); /* Return a pointer to the real data */ @@ -321,7 +319,8 @@ void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags) #ifndef HAVE_purify /* Mark this data as free'ed */ - bfill(&pRec->aData[sf_malloc_prehunc],pRec->uDataSize,(pchar) FREE_VAL); + if (!sf_malloc_quick) + bfill(&pRec->aData[sf_malloc_prehunc],pRec->uDataSize,(pchar) FREE_VAL); #endif *((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) = ~MAGICKEY; diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh index 1aad5c95c25..d808ffdcaef 100644 --- a/scripts/mysqlhotcopy.sh +++ b/scripts/mysqlhotcopy.sh @@ -37,7 +37,7 @@ WARNING: THIS PROGRAM IS STILL IN BETA. Comments/patches welcome. # Documentation continued at end of file -my $VERSION = "1.16"; +my $VERSION = "1.17"; my $opt_tmpdir = $ENV{TMPDIR} || "/tmp"; @@ -388,6 +388,8 @@ foreach my $rdb ( @db_desc ) { foreach my $td ( '', @{$rdb->{raid_dirs}} ) { my $tgt_dirpath = "$rdb->{target}/$td"; + # Remove trailing slashes (needed for Mac OS X) + substr($tgt_dirpath, 1) =~ s|/+$||; if ( $opt{dryrun} ) { print "mkdir $tgt_dirpath, 0750\n"; } @@ -1001,3 +1003,5 @@ resulted in nothing being copied when a regexp was specified but no database name(s). Martin Waite - Fix to handle database name that contains space. + +Paul DuBois - Remove end '/' from directory names diff --git a/sql/field.h b/sql/field.h index 0f0225da3d2..4290f99ea3e 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1056,6 +1056,7 @@ Field *make_field(char *ptr, uint32 field_length, uint pack_length_to_packflag(uint type); uint32 calc_pack_length(enum_field_types type,uint32 length); bool set_field_to_null(Field *field); +bool set_field_to_null_with_conversions(Field *field); uint find_enum(TYPELIB *typelib,const char *x, uint length); ulonglong find_set(TYPELIB *typelib,const char *x, uint length); bool test_if_int(const char *str,int length); diff --git a/sql/field_conv.cc b/sql/field_conv.cc index c7a6d778953..53b26920c14 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -112,35 +112,52 @@ static void do_outer_field_to_null_str(Copy_field *copy) bool set_field_to_null(Field *field) { - if (field->maybe_null()) + if (field->real_maybe_null()) { field->set_null(); field->reset(); + return 0; } - else + return 1; +} + + +bool +set_field_to_null_with_conversions(Field *field) +{ + if (field->real_maybe_null()) { - if (field->type() == FIELD_TYPE_TIMESTAMP) - { - ((Field_timestamp*) field)->set_time(); - return 0; // Ok to set time to NULL - } + field->set_null(); field->reset(); - if (field == field->table->next_number_field) - return 0; // field is set in handler.cc - if (current_thd->count_cuted_fields) - { - current_thd->cuted_fields++; // Increment error counter - return 0; - } - if (!current_thd->no_errors) - my_printf_error(ER_BAD_NULL_ERROR,ER(ER_BAD_NULL_ERROR),MYF(0), - field->field_name); - return 1; + return 0; + } + + /* + Check if this is a special type, which will get a special walue + when set to NULL + */ + if (field->type() == FIELD_TYPE_TIMESTAMP) + { + ((Field_timestamp*) field)->set_time(); + return 0; // Ok to set time to NULL + } + field->reset(); + if (field == field->table->next_number_field) + return 0; // field is set in handler.cc + if (current_thd->count_cuted_fields) + { + current_thd->cuted_fields++; // Increment error counter + return 0; } - return 0; + if (!current_thd->no_errors) + my_printf_error(ER_BAD_NULL_ERROR,ER(ER_BAD_NULL_ERROR),MYF(0), + field->field_name); + return 1; } + + static void do_skip(Copy_field *copy __attribute__((unused))) { } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 2c27f565895..bb3f254bc03 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2179,16 +2179,8 @@ convert_search_mode_to_innobase( case HA_READ_AFTER_KEY: return(PAGE_CUR_G); case HA_READ_BEFORE_KEY: return(PAGE_CUR_L); case HA_READ_PREFIX: return(PAGE_CUR_GE); - case HA_READ_PREFIX_LAST: - /* ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Warning: Using HA_READ_PREFIX_LAST\n"); */ - return(PAGE_CUR_LE); - - /* InnoDB does not yet support ..PREFIX_LAST! - We have to add a new search flag - PAGE_CUR_LE_OR_PREFIX to InnoDB. */ - + case HA_READ_PREFIX_LAST: return(PAGE_CUR_LE); + /* HA_READ_PREFIX_LAST does not yet work in InnoDB! */ /* the above PREFIX flags mean that the last field in the key value may just be a prefix of the complete fixed length field */ @@ -3262,7 +3254,7 @@ ha_innobase::records_in_range( MYF(MY_WME)); dtuple_t* range_start; dtuple_t* range_end; - ulint n_rows; + ib_longlong n_rows; ulint mode1; ulint mode2; void* heap1; @@ -3647,6 +3639,47 @@ ha_innobase::reset(void) return(0); } + +/********************************************************************** +When we create a temporary table inside MySQL LOCK TABLES, MySQL will +not call external_lock for the temporary table when it uses it. Instead, +it will call this function. */ + +int +ha_innobase::start_stmt( +/*====================*/ + /* out: 0 or error code */ + THD* thd) /* in: handle to the user thread */ +{ + row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; + trx_t* trx; + + update_thd(thd); + + trx = prebuilt->trx; + + innobase_release_stat_resources(trx); + trx_mark_sql_stat_end(trx); + + auto_inc_counter_for_this_stat = 0; + prebuilt->sql_stat_start = TRUE; + prebuilt->hint_no_need_to_fetch_extra_cols = TRUE; + prebuilt->read_just_key = 0; + + if (prebuilt->select_lock_type == LOCK_NONE) { + /* This handle is for a temporary table created inside + this same LOCK TABLES; since MySQL does NOT call external_lock + in this case, we must use x-row locks inside InnoDB to be + prepared for an update of a row */ + + prebuilt->select_lock_type = LOCK_X; + } + + thd->transaction.all.innodb_active_trans = 1; + + return(0); +} + /********************************************************************** When we create a temporary table inside MySQL LOCK TABLES, MySQL will not call external_lock for the temporary table when it uses it. Instead, @@ -3785,6 +3818,14 @@ innodb_show_status( DBUG_ENTER("innodb_show_status"); + if (innodb_skip) { + + fprintf(stderr, + "Cannot call SHOW INNODB STATUS because skip-innodb is defined\n"); + + DBUG_RETURN(-1); + } + /* We let the InnoDB Monitor to output at most 100 kB of text, add a safety margin of 10 kB for buffer overruns */ diff --git a/sql/item.cc b/sql/item.cc index bb39a141e9f..b3b4e99e28a 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -419,7 +419,7 @@ void Item_field::save_org_in_field(Field *to) if (field->is_null()) { null_value=1; - set_field_to_null(to); + set_field_to_null_with_conversions(to); } else { @@ -434,7 +434,7 @@ bool Item_field::save_in_field(Field *to) if (result_field->is_null()) { null_value=1; - return set_field_to_null(to); + return set_field_to_null_with_conversions(to); } else { @@ -445,9 +445,42 @@ bool Item_field::save_in_field(Field *to) return 0; } +/* + Store null in field + + SYNOPSIS + save_in_field() + field Field where we want to store NULL + + DESCRIPTION + This is used on INSERT. + Allow NULL to be inserted in timestamp and auto_increment values + + RETURN VALUES + 0 ok + 1 Field doesn't support NULL values and can't handle 'field = NULL' +*/ bool Item_null::save_in_field(Field *field) { + return set_field_to_null_with_conversions(field); +} + + +/* + Store null in field + + SYNOPSIS + save_safe_in_field() + field Field where we want to store NULL + + RETURN VALUES + 0 ok + 1 Field doesn't support NULL values +*/ + +bool Item_null::save_safe_in_field(Field *field) +{ return set_field_to_null(field); } @@ -463,7 +496,7 @@ bool Item::save_in_field(Field *field) str_value.set_quick(buff,sizeof(buff)); result=val_str(&str_value); if (null_value) - return set_field_to_null(field); + return set_field_to_null_with_conversions(field); field->set_notnull(); field->store(result->ptr(),result->length()); str_value.set_quick(0, 0); @@ -480,13 +513,14 @@ bool Item::save_in_field(Field *field) { longlong nr=val_int(); if (null_value) - return set_field_to_null(field); + return set_field_to_null_with_conversions(field); field->set_notnull(); field->store(nr); } return 0; } + bool Item_string::save_in_field(Field *field) { String *result; diff --git a/sql/item.h b/sql/item.h index 70729afe28e..246e1fbcbd6 100644 --- a/sql/item.h +++ b/sql/item.h @@ -56,6 +56,8 @@ public: virtual bool save_in_field(Field *field); virtual void save_org_in_field(Field *field) { (void) save_in_field(field); } + virtual bool save_safe_in_field(Field *field) + { return save_in_field(field); } virtual bool send(THD *thd, String *str); virtual bool eq(const Item *, bool binary_cmp) const; virtual Item_result result_type () const { return REAL_RESULT; } @@ -154,6 +156,7 @@ public: String *val_str(String *str); void make_field(Send_field *field); bool save_in_field(Field *field); + bool save_safe_in_field(Field *field); enum Item_result result_type () const { return STRING_RESULT; } bool send(THD *thd, String *str); diff --git a/sql/log.cc b/sql/log.cc index ccd3954e172..72e1b60f6b3 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -938,8 +938,8 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, int error=0; VOID(pthread_mutex_lock(&LOCK_log)); - /* Test if someone closed after the is_open test */ - if (log_type != LOG_CLOSED) + /* Test if someone closed between the is_open test and lock */ + if (is_open()) { time_t skr; ulong id; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c418ef34174..7e2bc9512cd 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4160,7 +4160,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case (int) OPT_SKIP_SHOW_DB: opt_skip_show_db=1; opt_specialflag|=SPECIAL_SKIP_SHOW_DB; - mysql_port=0; break; #ifdef ONE_THREAD case (int) OPT_ONE_THREAD: diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 6c2ba4b6429..287df717aec 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -382,6 +382,8 @@ bool mysql_change_db(THD *thd,const char *name) } send_ok(&thd->net); x_free(thd->db); + if (lower_case_table_names) + casedn_str(dbname); thd->db=dbname; thd->db_length=db_length; thd->db_access=db_access; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d6e40889eed..2642a27cfff 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3356,10 +3356,10 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) } if (options & REFRESH_LOG) { - mysql_log.new_file(); - mysql_update_log.new_file(); - mysql_bin_log.new_file(); - mysql_slow_log.new_file(); + mysql_log.new_file(0); + mysql_update_log.new_file(0); + mysql_bin_log.new_file(0); + mysql_slow_log.new_file(0); if (ha_flush_logs()) result=1; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 042fb779ec2..fc5fe33288f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3527,7 +3527,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, char *tmpname,path[FN_REFLEN]; byte *pos,*group_buff; uchar *null_flags; - Field **reg_field,**from_field; + Field **reg_field, **from_field, **blob_field; Copy_field *copy=0; KEY *keyinfo; KEY_PART_INFO *key_part_info; @@ -3572,8 +3572,9 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, hidden_field_count=param->hidden_field_count; if (!my_multi_malloc(MYF(MY_WME), &table,sizeof(*table), - ®_field,sizeof(Field*)*(field_count+1), - &from_field,sizeof(Field*)*field_count, + ®_field, sizeof(Field*)*(field_count+1), + &blob_field, sizeof(Field*)*(field_count+1), + &from_field, sizeof(Field*)*field_count, ©_func,sizeof(*copy_func)*(param->func_count+1), ¶m->keyinfo,sizeof(*param->keyinfo), &key_part_info, @@ -3602,8 +3603,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, bzero((char*) reg_field,sizeof(Field*)*(field_count+1)); bzero((char*) from_field,sizeof(Field*)*field_count); table->field=reg_field; + table->blob_field= (Field_blob**) blob_field; table->real_name=table->path=tmpname; - table->table_name=base_name(tmpname); + /* + This must be "" as field may refer to it after tempory table is dropped + */ + table->table_name= (char*) ""; table->reginfo.lock_type=TL_WRITE; /* Will be updated */ table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE; table->blob_ptr_size=mi_portable_sizeof_char_ptr; @@ -3611,7 +3616,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, table->tmp_table= TMP_TABLE; table->db_low_byte_first=1; // True for HEAP and MyISAM table->temp_pool_slot = temp_pool_slot; - + table->copy_blobs= 1; /* Calculate which type of fields we will store in the temporary table */ @@ -3658,7 +3663,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, if (!(new_field->flags & NOT_NULL_FLAG)) null_count++; if (new_field->flags & BLOB_FLAG) + { + *blob_field++= new_field; blob_count++; + } ((Item_sum*) item)->args[i]= new Item_field(new_field); } } @@ -3681,7 +3689,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, if (!(new_field->flags & NOT_NULL_FLAG)) null_count++; if (new_field->flags & BLOB_FLAG) + { + *blob_field++= new_field; blob_count++; + } if (item->marker == 4 && item->maybe_null) { group_null_items++; @@ -3694,6 +3705,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, } DBUG_ASSERT(field_count >= (uint) (reg_field - table->field)); field_count= (uint) (reg_field - table->field); + *blob_field= 0; // End marker /* If result table is small; use a heap */ if (blob_count || using_unique_constraint || group_null_items || @@ -3951,10 +3963,17 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, if (create_myisam_tmp_table(table,param,select_options)) goto err; } + /* Set table_name for easier debugging */ + table->table_name= base_name(tmpname); if (!open_tmp_table(table)) DBUG_RETURN(table); err: + /* + Hack to ensure that free_blobs() doesn't fail if blob_field is not yet + complete + */ + *table->blob_field= 0; free_tmp_table(thd,table); /* purecov: inspected */ bitmap_clear_bit(&temp_pool, temp_pool_slot); DBUG_RETURN(NULL); /* purecov: inspected */ @@ -4096,6 +4115,7 @@ free_tmp_table(THD *thd, TABLE *entry) save_proc_info=thd->proc_info; thd->proc_info="removing tmp table"; + free_blobs(entry); if (entry->db_stat && entry->file) { (void) entry->file->close(); diff --git a/sql/table.cc b/sql/table.cc index cc5666ff5fb..d3b719c553d 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -482,6 +482,13 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, field->field_length=key_part->length; } } + /* + If the field can be NULL, don't optimize away the test + key_part_column = expression from the WHERE clause + as we need to test for NULL = NULL. + */ + if (field->real_maybe_null()) + key_part->key_part_flag|= HA_PART_KEY; } else { // Error: shorten key |