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:
unknown 2002-10-16 16:34:29 +03:00
commit 6f38e3083f
28 changed files with 427 additions and 85 deletions

View file

@ -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);

View file

@ -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.

View file

@ -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;

View file

@ -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;

View file

@ -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)*

View file

@ -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;
}

View file

@ -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 */

View file

@ -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

View file

@ -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;
}

View file

@ -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);

View file

@ -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));

View file

@ -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,

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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
{
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;
}
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;
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();
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;
}
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)))
{
}

View file

@ -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 */

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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:

View file

@ -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;

View file

@ -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;
}

View file

@ -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),
&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,
@ -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;

View file

@ -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