mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Merge work:/home/bk/mysql-4.0 into hundin.mysql.fi:/my/bk/mysql-4.0
BitKeeper/etc/logging_ok: auto-union sql/mysqld.cc: Auto merged
This commit is contained in:
commit
6f38e3083f
28 changed files with 427 additions and 85 deletions
|
@ -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);
|
||||
|
|
|
@ -50797,6 +50797,9 @@ each individual 4.0.x release.
|
|||
@appendixsubsec Changes in release 4.0.5
|
||||
@itemize
|
||||
@item
|
||||
Fixed a newly introduced bug that caused @code{ORDER BY ... LIMIT #}
|
||||
to not return all rows.
|
||||
@item
|
||||
Fixed a bug in multi-table deletes when outer join is used on an empty
|
||||
table, which get's first to be deleted
|
||||
@item
|
||||
|
@ -51589,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)
|
||||
|
@ -51646,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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)*
|
||||
|
|
|
@ -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,9 +2590,12 @@ 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;
|
||||
|
||||
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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
} else if (diverged && !diverged_lot) {
|
||||
|
||||
if (slot1->nth_rec < slot1->n_recs
|
||||
|| slot2->nth_rec > 1) {
|
||||
|
||||
diverged_lot = TRUE;
|
||||
divergence_level = i;
|
||||
|
||||
diverged = TRUE;
|
||||
} else if (diverged) {
|
||||
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) {
|
||||
|
||||
n_rows = (n_rows * (slot1->n_recs + slot2->n_recs))
|
||||
/ 2;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -2012,6 +2012,19 @@ lock_grant(
|
|||
|
||||
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",
|
||||
ut_dulint_get_low(lock->trx->id));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,6 +319,7 @@ void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags)
|
|||
|
||||
#ifndef HAVE_purify
|
||||
/* Mark this data as free'ed */
|
||||
if (!sf_malloc_quick)
|
||||
bfill(&pRec->aData[sf_malloc_prehunc],pRec->uDataSize,(pchar) FREE_VAL);
|
||||
#endif
|
||||
*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) = ~MAGICKEY;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -112,13 +112,30 @@ 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())
|
||||
{
|
||||
field->set_null();
|
||||
field->reset();
|
||||
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();
|
||||
|
@ -136,11 +153,11 @@ set_field_to_null(Field *field)
|
|||
my_printf_error(ER_BAD_NULL_ERROR,ER(ER_BAD_NULL_ERROR),MYF(0),
|
||||
field->field_name);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void do_skip(Copy_field *copy __attribute__((unused)))
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
42
sql/item.cc
42
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,8 +445,41 @@ 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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -4159,7 +4159,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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -111,7 +111,8 @@ static Item* part_of_refkey(TABLE *form,Field *field);
|
|||
static uint find_shortest_key(TABLE *table, key_map usable_keys);
|
||||
static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,
|
||||
ha_rows select_limit, bool no_changes);
|
||||
static int create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit);
|
||||
static int create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows filesort_limit,
|
||||
ha_rows select_limit);
|
||||
static int remove_duplicates(JOIN *join,TABLE *entry,List<Item> &fields,
|
||||
Item *having);
|
||||
static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field,
|
||||
|
@ -207,6 +208,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||
int error, tmp_error;
|
||||
bool need_tmp,hidden_group_fields;
|
||||
bool simple_order,simple_group,no_order, skip_sort_order;
|
||||
ha_rows select_limit;
|
||||
Item::cond_result cond_value;
|
||||
SQL_SELECT *select;
|
||||
DYNAMIC_ARRAY keyuse;
|
||||
|
@ -662,7 +664,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||
DBUG_PRINT("info",("Sorting for group"));
|
||||
thd->proc_info="Sorting for group";
|
||||
if (create_sort_index(&join.join_tab[join.const_tables],group,
|
||||
HA_POS_ERROR) ||
|
||||
HA_POS_ERROR, HA_POS_ERROR) ||
|
||||
make_sum_func_list(&join,all_fields) ||
|
||||
alloc_group_fields(&join,group))
|
||||
goto err;
|
||||
|
@ -677,7 +679,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||
DBUG_PRINT("info",("Sorting for order"));
|
||||
thd->proc_info="Sorting for order";
|
||||
if (create_sort_index(&join.join_tab[join.const_tables],order,
|
||||
HA_POS_ERROR))
|
||||
HA_POS_ERROR, HA_POS_ERROR))
|
||||
goto err; /* purecov: inspected */
|
||||
order=0;
|
||||
}
|
||||
|
@ -778,7 +780,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||
if (group)
|
||||
{
|
||||
thd->proc_info="Creating sort index";
|
||||
if (create_sort_index(join.join_tab,group,HA_POS_ERROR) ||
|
||||
if (create_sort_index(join.join_tab,group,HA_POS_ERROR, HA_POS_ERROR) ||
|
||||
alloc_group_fields(&join,group))
|
||||
{
|
||||
free_tmp_table(thd,tmp_table2); /* purecov: inspected */
|
||||
|
@ -872,11 +874,31 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
|
|||
DBUG_EXECUTE("where",print_where(conds,"having after sort"););
|
||||
}
|
||||
}
|
||||
select_limit= thd->select_limit;
|
||||
if (having || group || (join.select_options & OPTION_FOUND_ROWS))
|
||||
select_limit= HA_POS_ERROR;
|
||||
else
|
||||
{
|
||||
/*
|
||||
We can abort sorting after thd->select_limit rows if we there is no
|
||||
WHERE clause for any tables after the sorted one.
|
||||
*/
|
||||
JOIN_TAB *table= &join.join_tab[join.const_tables+1];
|
||||
JOIN_TAB *end_table= &join.join_tab[join.tables];
|
||||
for (; table < end_table ; table++)
|
||||
{
|
||||
if (table->select_cond)
|
||||
{
|
||||
/* We have to sort all rows */
|
||||
select_limit= HA_POS_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (create_sort_index(&join.join_tab[join.const_tables],
|
||||
group ? group : order,
|
||||
(having || group ||
|
||||
(join.select_options & OPTION_FOUND_ROWS)) ?
|
||||
HA_POS_ERROR : thd->select_limit))
|
||||
select_limit,
|
||||
thd->select_limit))
|
||||
goto err; /* purecov: inspected */
|
||||
}
|
||||
join.having=having; // Actually a parameter
|
||||
|
@ -3505,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;
|
||||
|
@ -3550,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,
|
||||
|
@ -3580,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;
|
||||
|
@ -3589,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 */
|
||||
|
||||
|
@ -3636,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);
|
||||
}
|
||||
}
|
||||
|
@ -3659,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++;
|
||||
|
@ -3672,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 ||
|
||||
|
@ -3929,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 */
|
||||
|
@ -4074,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();
|
||||
|
@ -5639,7 +5681,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
|||
*****************************************************************************/
|
||||
|
||||
static int
|
||||
create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
|
||||
create_sort_index(JOIN_TAB *tab, ORDER *order, ha_rows filesort_limit,
|
||||
ha_rows select_limit)
|
||||
{
|
||||
SORT_FIELD *sortorder;
|
||||
uint length;
|
||||
|
@ -5684,7 +5727,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
|
|||
if (table->tmp_table)
|
||||
table->file->info(HA_STATUS_VARIABLE); // Get record count
|
||||
table->found_records=filesort(table,sortorder,length,
|
||||
select, 0L, select_limit, &examined_rows);
|
||||
select, 0L, filesort_limit, &examined_rows);
|
||||
tab->records=table->found_records; // For SQL_CALC_ROWS
|
||||
delete select; // filesort did select
|
||||
tab->select=0;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue