summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <monty@hundin.mysql.fi>2002-10-16 13:11:25 +0300
committerunknown <monty@hundin.mysql.fi>2002-10-16 13:11:25 +0300
commit7013d8ef0ae0a21fadfcc0a159ee1d83fdad8a9d (patch)
treed165b4baadac24102545d94c8f9fe180537a64f5
parente1d7b8414f14de681127f4e19340e4f7737d5bdb (diff)
parent74b73109c1304e62430faa85d2a63a6f2ffa626d (diff)
downloadmariadb-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_ok6
-rwxr-xr-xBuild-tools/Do-compile8
-rw-r--r--Docs/manual.texi36
-rw-r--r--configure.in2
-rw-r--r--heap/heapdef.h11
-rw-r--r--heap/hp_open.c10
-rw-r--r--innobase/btr/btr0cur.c62
-rw-r--r--innobase/include/btr0cur.h2
-rw-r--r--innobase/include/os0thread.h9
-rw-r--r--innobase/lock/lock0lock.c33
-rw-r--r--innobase/os/os0file.c2
-rw-r--r--innobase/os/os0thread.c4
-rw-r--r--myisam/mi_open.c2
-rw-r--r--mysql-test/r/distinct.result2
-rw-r--r--mysql-test/r/null_key.result6
-rw-r--r--mysql-test/t/null_key.test44
-rw-r--r--mysys/safemalloc.c7
-rw-r--r--scripts/mysqlhotcopy.sh6
-rw-r--r--sql/field.h1
-rw-r--r--sql/field_conv.cc55
-rw-r--r--sql/ha_innodb.cc63
-rw-r--r--sql/item.cc42
-rw-r--r--sql/item.h3
-rw-r--r--sql/log.cc4
-rw-r--r--sql/mysqld.cc1
-rw-r--r--sql/sql_db.cc2
-rw-r--r--sql/sql_parse.cc8
-rw-r--r--sql/sql_select.cc30
-rw-r--r--sql/table.cc7
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),
- &reg_field,sizeof(Field*)*(field_count+1),
- &from_field,sizeof(Field*)*field_count,
+ &reg_field, sizeof(Field*)*(field_count+1),
+ &blob_field, sizeof(Field*)*(field_count+1),
+ &from_field, sizeof(Field*)*field_count,
&copy_func,sizeof(*copy_func)*(param->func_count+1),
&param->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