Merge work:/home/bk/mysql-4.1 into mashka.mysql.fi:/home/my/mysql-4.1
This commit is contained in:
commit
c9dc5a206b
@ -135,6 +135,7 @@ $ENV{'MYSQL_UNIX_PORT'}=$mysql_unix_port="$opt_tmp/mysql$opt_suffix.build";
|
||||
$ENV{"PERL5LIB"}="$pwd/$host/perl5:$pwd/$host/perl5/site_perl";
|
||||
$slave_port=$mysql_tcp_port+16;
|
||||
$manager_port=$mysql_tcp_port+1;
|
||||
$mysqladmin_args="--no-defaults -u root --connect_timeout=5 --shutdown_timeout=20";
|
||||
|
||||
if ($opt_stage == 0)
|
||||
{
|
||||
@ -154,13 +155,18 @@ log_timestamp();
|
||||
|
||||
if (-x "$host/bin/mysqladmin")
|
||||
{
|
||||
log_system("$host/bin/mysqladmin --no-defaults -u root -S $mysql_unix_port -s shutdown");
|
||||
log_system("$host/bin/mysqladmin --no-defaults -u root -P $mysql_tcp_port -h $host -s shutdown");
|
||||
log_system("$host/bin/mysqladmin --no-defaults -u root -P $slave_port -h $host -s shutdown");
|
||||
log_system("$host/bin/mysqladmin --no-defaults -u root -P 9306 -h $host -s shutdown");
|
||||
log_system("$host/bin/mysqladmin --no-defaults -u root -P 9307 -h $host -s shutdown");
|
||||
log_system("$host/bin/mysqladmin $mysqladmin_args -S $mysql_unix_port -s shutdown");
|
||||
log_system("$host/bin/mysqladmin $mysqladmin_args -P $mysql_tcp_port -h $host -s shutdown");
|
||||
log_system("$host/bin/mysqladmin $mysqladmin_args -P $slave_port -h $host -s shutdown");
|
||||
log_system("$host/bin/mysqladmin $mysqladmin_args -P 9306 -h $host -s shutdown");
|
||||
log_system("$host/bin/mysqladmin $mysqladmin_args -P 9307 -h $host -s shutdown");
|
||||
}
|
||||
kill_all("mysqlmanager");
|
||||
#
|
||||
# Kill all old processes that are in the build directories
|
||||
# This is to find any old mysqld servers left from previous builds
|
||||
kill_all("$pwd/host/mysql");
|
||||
kill_all("$pwd/host/test");
|
||||
|
||||
if ($opt_stage == 0)
|
||||
{
|
||||
@ -308,8 +314,9 @@ if ($opt_stage <= 4 && !$opt_no_test)
|
||||
$tar_file =~ /(mysql[^\/]*)\.tar/;
|
||||
$ver=$1;
|
||||
$test_dir="$pwd/$host/test/$ver";
|
||||
$ENV{"LD_LIBRARY_PATH"}= "$test_dir/lib:" . $ENV{"LD_LIBRARY_PATH"};
|
||||
|
||||
$ENV{"LD_LIBRARY_PATH"}= ("$test_dir/lib" .
|
||||
(defined($ENV{"LD_LIBRARY_PATH"}) ?
|
||||
":" . $ENV{"LD_LIBRARY_PATH"} : ""));
|
||||
#
|
||||
# Run the test suite
|
||||
#
|
||||
@ -328,7 +335,7 @@ if (!$opt_no_test && !$opt_no_benchmark)
|
||||
{
|
||||
my $extra;
|
||||
safe_cd($test_dir);
|
||||
log_system("./bin/mysqladmin --no-defaults -u root -S $mysql_unix_port -s shutdown") || info("There was no mysqld running\n");
|
||||
log_system("./bin/mysqladmin $mysqladmin_args -S $mysql_unix_port -s shutdown") || info("There was no mysqld running\n");
|
||||
sleep(2);
|
||||
log_system("rm -f ./data/mysql/*");
|
||||
check_system("scripts/mysql_install_db --no-defaults --skip-locking","https://order");
|
||||
@ -418,7 +425,7 @@ if ($opt_stage <= 9 && !$opt_no_test && !$opt_no_benchmark)
|
||||
rm_all($bench_tmpdir);
|
||||
rm_all("$opt_tmp") if ($new_opt_tmp);
|
||||
|
||||
log_system("$pwd/$host/bin/mysqladmin --no-defaults -S $mysql_unix_port -u root shutdown");
|
||||
log_system("$pwd/$host/bin/mysqladmin $mysqladmin_args -S $mysql_unix_port -u root shutdown");
|
||||
print LOG "ok\n";
|
||||
close LOG;
|
||||
print "$host: ok\n";
|
||||
@ -429,7 +436,7 @@ exit 0;
|
||||
sub usage
|
||||
{
|
||||
print <<EOF;
|
||||
$0 version 1.4
|
||||
$0 version 1.5
|
||||
|
||||
$0 takes the following options:
|
||||
|
||||
|
@ -96,13 +96,84 @@ cached for each user/database combination.
|
||||
Many use of @code{GROUP BY} or @code{DISTINCT} caches all found rows in
|
||||
a @code{HEAP} table. (This is a very quick in-memory table with hash index.)
|
||||
|
||||
@item Join Row Cache
|
||||
@item Join buffer Cache
|
||||
For every full join in a @code{SELECT} statement (a full join here means
|
||||
there were no keys that one could use to find the next table in a list),
|
||||
the found rows are cached in a join cache. One @code{SELECT} query can
|
||||
use many join caches in the worst case.
|
||||
@end table
|
||||
|
||||
@node join_buffer_size, flush tables, caching, Top
|
||||
@subchapter How MySQL uses the join_buffer cache
|
||||
|
||||
Basic information about @code{join_buffer_size}:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
It's only used in the case when join type is of type @code{ALL} or
|
||||
@code{index}; In other words: no possible keys can be used.
|
||||
@item
|
||||
A join buffer is never allocated for the first not-const table,
|
||||
even it it would be of type @code{ALL}/@code{index}.
|
||||
@item
|
||||
The buffer is allocated when we need to do a each full join between two
|
||||
tables and freed after the query is done.
|
||||
@item
|
||||
Accepted row combinations of tables before the @code{ALL}/@code{index}
|
||||
able is stored in the cache and is used to compare against each read
|
||||
row in the @code{ALL} table.
|
||||
@item
|
||||
We only store the used fields in the join_buffer cache, not the
|
||||
whole rows.
|
||||
@end itemize
|
||||
|
||||
Assume you have the following join:
|
||||
|
||||
@example
|
||||
Table name Type
|
||||
t1 range
|
||||
t2 ref
|
||||
t3 @code{ALL}
|
||||
@end example
|
||||
|
||||
The join is then done as follows:
|
||||
|
||||
@example
|
||||
- While rows in t1 matching range
|
||||
- Read through all rows in t2 according to reference key
|
||||
- Store used fields form t1,t2 in cache
|
||||
- If cache is full
|
||||
- Read through all rows in t3
|
||||
- Compare t3 row against all t1,t2 combination in cache
|
||||
- If rows satisfying join condition, send it to client
|
||||
- Empty cache
|
||||
|
||||
- Read through all rows in t3
|
||||
- Compare t3 row against all stored t1,t2 combinations in cache
|
||||
- If rows satisfying join condition, send it to client
|
||||
@end example
|
||||
|
||||
The above means that table t3 is scanned
|
||||
|
||||
@example
|
||||
(size-of-stored-row(t1,t2) * accepted-row-cominations(t1,t2))/
|
||||
join_buffer_size+1
|
||||
@end example
|
||||
times.
|
||||
|
||||
Some conclusions:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
The larger the join_buff_size, the fewer scans of t3.
|
||||
If @code{join_buff_size} is already large enough to hold all previous row
|
||||
combinations then there is no speed to gain by making it bigger.
|
||||
@item
|
||||
If there is several tables of @code{ALL}/@code{index} then the we
|
||||
allocate one @code{join_buffer_size buffer} for each of them and use the
|
||||
same algorithm described above to handle it. (In other words, we store
|
||||
the same row combination several times into different buffers)
|
||||
@end itemize
|
||||
|
||||
@node flush tables, filesort, caching, Top
|
||||
@chapter How MySQL Handles @code{FLUSH TABLES}
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <mysql.h>
|
||||
|
||||
#define ADMIN_VERSION "8.38"
|
||||
#define ADMIN_VERSION "8.39"
|
||||
#define MAX_MYSQL_VAR 128
|
||||
#define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */
|
||||
#define MAX_TRUNC_LENGTH 3
|
||||
@ -76,8 +76,8 @@ static void print_relative_header();
|
||||
static void print_relative_line();
|
||||
static void truncate_names();
|
||||
static my_bool get_pidfile(MYSQL *mysql, char *pidfile);
|
||||
static void wait_pidfile(char *pidfile, time_t last_modified,
|
||||
struct stat *pidfile_status);
|
||||
static my_bool wait_pidfile(char *pidfile, time_t last_modified,
|
||||
struct stat *pidfile_status);
|
||||
static void store_values(MYSQL_RES *result);
|
||||
|
||||
/*
|
||||
@ -513,7 +513,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
||||
printf("Shutdown signal sent to server; Waiting for pid file to disappear\n");
|
||||
|
||||
/* Wait until pid file is gone */
|
||||
wait_pidfile(pidfile, last_modified, &pidfile_status);
|
||||
if (wait_pidfile(pidfile, last_modified, &pidfile_status))
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1150,34 +1151,51 @@ static my_bool get_pidfile(MYSQL *mysql, char *pidfile)
|
||||
return 1; /* Error */
|
||||
}
|
||||
|
||||
/*
|
||||
Return 1 if pid file didn't disappear or change
|
||||
*/
|
||||
|
||||
static void wait_pidfile(char *pidfile, time_t last_modified,
|
||||
struct stat *pidfile_status)
|
||||
static my_bool wait_pidfile(char *pidfile, time_t last_modified,
|
||||
struct stat *pidfile_status)
|
||||
{
|
||||
char buff[FN_REFLEN];
|
||||
int fd = -1;
|
||||
uint count=0;
|
||||
int error= 1;
|
||||
uint count= 0;
|
||||
DBUG_ENTER("wait_pidfile");
|
||||
|
||||
system_filename(buff, pidfile);
|
||||
while (count++ <= opt_shutdown_timeout && !interrupted &&
|
||||
(!last_modified || (last_modified == pidfile_status->st_mtime)) &&
|
||||
(fd= my_open(buff, O_RDONLY, MYF(0))) >= 0)
|
||||
do
|
||||
{
|
||||
if (!my_close(fd,MYF(0)))
|
||||
fd= -1;
|
||||
int fd;
|
||||
if ((fd= my_open(buff, O_RDONLY, MYF(0))) < 0)
|
||||
{
|
||||
error= 0;
|
||||
break;
|
||||
}
|
||||
(void) my_close(fd,MYF(0));
|
||||
if (last_modified && !stat(pidfile, pidfile_status))
|
||||
{
|
||||
if (last_modified != pidfile_status->st_mtime)
|
||||
{
|
||||
/* File changed; Let's assume that mysqld did restart */
|
||||
if (opt_verbose)
|
||||
printf("pid file '%s' changed while waiting for it to disappear!\nmysqld did probably restart\n",
|
||||
buff);
|
||||
error= 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (count++ == opt_shutdown_timeout)
|
||||
break;
|
||||
sleep(1);
|
||||
if (last_modified && stat(pidfile, pidfile_status))
|
||||
last_modified= 0;
|
||||
}
|
||||
if (opt_verbose && last_modified &&
|
||||
last_modified != pidfile_status->st_mtime)
|
||||
printf("Warning; pid file '%s' changed while waiting for it to disappear!\n",
|
||||
buff);
|
||||
if (fd >= 0)
|
||||
} while (!interrupted);
|
||||
|
||||
if (error)
|
||||
{
|
||||
my_close(fd,MYF(0));
|
||||
DBUG_PRINT("warning",("Pid file didn't disappear"));
|
||||
fprintf(stderr,
|
||||
"Warning; Aborted waiting on pid file: '%s' after %d seconds\n",
|
||||
buff, count-1);
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
@ -42,7 +42,7 @@
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#define MTEST_VERSION "1.25"
|
||||
#define MTEST_VERSION "1.26"
|
||||
|
||||
#include <my_global.h>
|
||||
#include <mysql_embed.h>
|
||||
@ -1809,10 +1809,8 @@ int read_query(struct st_query** q_ptr)
|
||||
|
||||
static struct my_option my_long_options[] =
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
{"debug", '#', "Output debug log. Often this is 'd:t:o,filename'",
|
||||
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
|
||||
#endif
|
||||
{"database", 'D', "Database to use.", (gptr*) &db, (gptr*) &db, 0,
|
||||
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"basedir", 'b', "Basedir for tests", (gptr*) &opt_basedir,
|
||||
@ -1905,7 +1903,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||
{
|
||||
switch(optid) {
|
||||
case '#':
|
||||
#ifndef DBUG_OFF
|
||||
DBUG_PUSH(argument ? argument : "d:t:S:i:O,/tmp/mysqltest.trace");
|
||||
#endif
|
||||
break;
|
||||
case 'r':
|
||||
record = 1;
|
||||
@ -1983,7 +1983,7 @@ int parse_args(int argc, char **argv)
|
||||
default_argv= argv;
|
||||
|
||||
if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
|
||||
exit(ho_error);
|
||||
exit(1);
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include
|
||||
LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.a \
|
||||
../dbug/libdbug.a ../strings/libmystrings.a
|
||||
bin_PROGRAMS = replace comp_err perror resolveip my_print_defaults \
|
||||
resolve_stack_dump mysql_install
|
||||
resolve_stack_dump mysql_install mysql_waitpid
|
||||
|
||||
# Don't update the files from bitkeeper
|
||||
%::SCCS/s.%
|
||||
|
86
extra/mysql_waitpid.c
Normal file
86
extra/mysql_waitpid.c
Normal file
@ -0,0 +1,86 @@
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <my_global.h>
|
||||
#include <my_getopt.h>
|
||||
|
||||
static const char *VER= "1.1";
|
||||
static char *progname;
|
||||
static my_bool verbose;
|
||||
|
||||
void usage(void);
|
||||
|
||||
static struct my_option my_long_options[] =
|
||||
{
|
||||
{"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
|
||||
0, 0, 0, 0, 0},
|
||||
{"help", 'I', "Synonym for -?.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
|
||||
0, 0, 0, 0, 0},
|
||||
{"verbose", 'v',
|
||||
"Be more verbose. Give a warning, if kill can't handle signal 0.",
|
||||
(gptr*) &verbose, (gptr*) &verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"version", 'V', "Print version information and exit.", 0, 0, 0,
|
||||
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static my_bool
|
||||
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||
char *argument __attribute__((unused)))
|
||||
{
|
||||
switch(optid) {
|
||||
case 'V':
|
||||
printf("%s version %s by Jani Tolonen\n", progname, VER);
|
||||
exit(-1);
|
||||
case 'I':
|
||||
case '?':
|
||||
usage();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int pid= 0, t= 0, sig= 0;
|
||||
|
||||
progname= argv[0];
|
||||
|
||||
if (handle_options(&argc, &argv, my_long_options, get_one_option))
|
||||
exit(-1);
|
||||
if (!argv[0] || !argv[1] || (pid= atoi(argv[0])) <= 0 ||
|
||||
(t= atoi(argv[1])) <= 0)
|
||||
usage();
|
||||
for (; t > 0; t--)
|
||||
{
|
||||
if (kill((pid_t) pid, sig))
|
||||
{
|
||||
if (errno == EINVAL)
|
||||
{
|
||||
if (verbose)
|
||||
printf("WARNING: kill couldn't handle signal 0, using signal 1.\n");
|
||||
sig= 1;
|
||||
t++;
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
sleep(1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
printf("%s version %s by Jani Tolonen\n\n", progname, VER);
|
||||
printf("usage: %s [options] #pid #time\n\n", progname);
|
||||
printf("Description: Waits for a program, which program id is #pid, to\n");
|
||||
printf("terminate within #time seconds. If the program terminates within\n");
|
||||
printf("this time, or if the #pid no longer exists, value 0 is returned.\n");
|
||||
printf("Otherwise 1 is returned. Both #pid and #time must be positive\n");
|
||||
printf("integer arguments.\n\n");
|
||||
printf("Options:\n");
|
||||
my_print_help(my_long_options);
|
||||
exit(-1);
|
||||
}
|
@ -264,6 +264,7 @@ enum ha_base_keytype {
|
||||
#define MBR_EQUAL 8192
|
||||
#define MBR_DATA 16384
|
||||
#define SEARCH_NULL_ARE_EQUAL 32768 /* NULL in keys are equal */
|
||||
#define SEARCH_NULL_ARE_NOT_EQUAL 65536 /* NULL in keys are not equal */
|
||||
|
||||
/* bits in opt_flag */
|
||||
#define QUICK_USED 1
|
||||
|
@ -97,6 +97,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
|
||||
|
||||
r=_mi_search(aio->info, aio->keyinfo, aio->keybuff, keylen,
|
||||
SEARCH_FIND | SEARCH_PREFIX, aio->key_root);
|
||||
aio->info->update|= HA_STATE_AKTIV; /* for _mi_test_if_changed() */
|
||||
|
||||
while (!r)
|
||||
{
|
||||
|
@ -601,7 +601,8 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
|
||||
if (*keys != 1L) /* not first_key */
|
||||
{
|
||||
uint diff;
|
||||
ha_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY,SEARCH_FIND,
|
||||
ha_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY,
|
||||
SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL,
|
||||
&diff);
|
||||
param->unique_count[diff-1]++;
|
||||
}
|
||||
|
@ -55,12 +55,17 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
|
||||
/*
|
||||
Free buffers and reset the following flags:
|
||||
EXTRA_CACHE, EXTRA_WRITE_CACHE, EXTRA_KEYREAD, EXTRA_QUICK
|
||||
|
||||
If the row buffer cache is large (for dynamic tables), reduce it
|
||||
to save memory.
|
||||
*/
|
||||
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
|
||||
{
|
||||
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
|
||||
error=end_io_cache(&info->rec_cache);
|
||||
}
|
||||
if (share->base.blobs)
|
||||
mi_alloc_rec_buff(info, -1, &info->rec_buff);
|
||||
#if defined(HAVE_MMAP) && defined(HAVE_MADVICE)
|
||||
if (info->opt_flag & MEMMAP_USED)
|
||||
madvise(share->file_map,share->state.state.data_file_length,MADV_RANDOM);
|
||||
|
@ -573,28 +573,36 @@ err:
|
||||
DBUG_RETURN (NULL);
|
||||
} /* mi_open */
|
||||
|
||||
|
||||
byte *mi_alloc_rec_buff(MI_INFO *info, ulong length, byte **buf)
|
||||
{
|
||||
uint extra;
|
||||
uint32 old_length;
|
||||
LINT_INIT(old_length);
|
||||
|
||||
if (! *buf || length > mi_get_rec_buff_len(info, *buf))
|
||||
if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
|
||||
{
|
||||
byte *newptr = *buf;
|
||||
|
||||
/* to simplify initial init of info->rec_buf in mi_open and mi_extra */
|
||||
if (length == (ulong) -1)
|
||||
{
|
||||
length= max(info->s->base.pack_reclength+info->s->base.pack_bits,
|
||||
info->s->base.max_key_length);
|
||||
/* Avoid unnecessary realloc */
|
||||
if (newptr && length == old_length)
|
||||
return newptr;
|
||||
}
|
||||
|
||||
extra= ((info->s->options & HA_OPTION_PACK_RECORD) ?
|
||||
ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER)+MI_SPLIT_LENGTH+
|
||||
MI_REC_BUFF_OFFSET : 0);
|
||||
if (extra && newptr)
|
||||
newptr-=MI_REC_BUFF_OFFSET;
|
||||
newptr-= MI_REC_BUFF_OFFSET;
|
||||
if (!(newptr=(byte*) my_realloc((gptr)newptr, length+extra+8,
|
||||
MYF(MY_ALLOW_ZERO_PTR))))
|
||||
return newptr;
|
||||
*((uint *)newptr)=length;
|
||||
*((uint32 *) newptr)= (uint32) length;
|
||||
*buf= newptr+(extra ? MI_REC_BUFF_OFFSET : 0);
|
||||
}
|
||||
return *buf;
|
||||
|
@ -260,9 +260,11 @@ int _mi_prefix_search(MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *page,
|
||||
uchar *key, uint key_len, uint nextflag, uchar **ret_pos,
|
||||
uchar *buff, my_bool *last_key)
|
||||
{
|
||||
/* my_flag is raw comparison result to be changed according to
|
||||
SEARCH_NO_FIND,SEARCH_LAST and HA_REVERSE_SORT flags.
|
||||
flag is the value returned by ha_key_cmp and as treated as final */
|
||||
/*
|
||||
my_flag is raw comparison result to be changed according to
|
||||
SEARCH_NO_FIND,SEARCH_LAST and HA_REVERSE_SORT flags.
|
||||
flag is the value returned by ha_key_cmp and as treated as final
|
||||
*/
|
||||
int flag=0, my_flag=-1;
|
||||
uint nod_flag, length, len, matched, cmplen, kseg_len;
|
||||
uint prefix_len,suffix_len;
|
||||
|
@ -385,7 +385,7 @@ typedef struct st_mi_sort_param
|
||||
#define MI_DYN_ALIGN_SIZE 4 /* Align blocks on this */
|
||||
#define MI_MAX_DYN_HEADER_BYTE 13 /* max header byte for dynamic rows */
|
||||
#define MI_MAX_BLOCK_LENGTH ((((ulong) 1 << 24)-1) & (~ (ulong) (MI_DYN_ALIGN_SIZE-1)))
|
||||
#define MI_REC_BUFF_OFFSET ALIGN_SIZE(MI_DYN_DELETE_BLOCK_HEADER+sizeof(uint))
|
||||
#define MI_REC_BUFF_OFFSET ALIGN_SIZE(MI_DYN_DELETE_BLOCK_HEADER+sizeof(uint32))
|
||||
|
||||
#define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for file */
|
||||
|
||||
@ -554,7 +554,7 @@ extern byte *mi_alloc_rec_buff(MI_INFO *,ulong, byte**);
|
||||
((((info)->s->options & HA_OPTION_PACK_RECORD) && (buf)) ? \
|
||||
(buf) - MI_REC_BUFF_OFFSET : (buf))
|
||||
#define mi_get_rec_buff_len(info,buf) \
|
||||
(*((uint *)(mi_get_rec_buff_ptr(info,buf))))
|
||||
(*((uint32 *)(mi_get_rec_buff_ptr(info,buf))))
|
||||
|
||||
extern ulong _mi_rec_unpack(MI_INFO *info,byte *to,byte *from,
|
||||
ulong reclength);
|
||||
|
@ -88,6 +88,7 @@ sleep_until_file_created ()
|
||||
wait_for_pid()
|
||||
{
|
||||
pid=$1
|
||||
#$WAIT_PID pid $SLEEP_TIME_FOR_DELETE
|
||||
}
|
||||
|
||||
# No paths below as we can't be sure where the program is!
|
||||
@ -347,9 +348,9 @@ while test $# -gt 0; do
|
||||
;;
|
||||
--debug)
|
||||
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT \
|
||||
--debug=d:t:i:O,$MYSQL_TEST_DIR/var/log/master.trace"
|
||||
--debug=d:t:i:A,$MYSQL_TEST_DIR/var/log/master.trace"
|
||||
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT \
|
||||
--debug=d:t:i:O,$MYSQL_TEST_DIR/var/log/slave.trace"
|
||||
--debug=d:t:i:A,$MYSQL_TEST_DIR/var/log/slave.trace"
|
||||
EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT --debug"
|
||||
;;
|
||||
--fast)
|
||||
@ -423,6 +424,7 @@ if [ x$SOURCE_DIST = x1 ] ; then
|
||||
fi
|
||||
|
||||
MYSQLADMIN="$BASEDIR/client/mysqladmin"
|
||||
WAIT_PID="$BASEDIR/extra/mysql_waitpid"
|
||||
MYSQL_MANAGER_CLIENT="$BASEDIR/client/mysqlmanagerc"
|
||||
MYSQL_MANAGER="$BASEDIR/tools/mysqlmanager"
|
||||
MYSQL_MANAGER_PWGEN="$BASEDIR/client/mysqlmanager-pwgen"
|
||||
@ -439,6 +441,7 @@ else
|
||||
fi
|
||||
MYSQL_TEST="$BASEDIR/bin/mysqltest"
|
||||
MYSQLADMIN="$BASEDIR/bin/mysqladmin"
|
||||
WAIT_PID="$BASEDIR/bin/mysql_waitpid"
|
||||
MYSQL_MANAGER="$BASEDIR/bin/mysqlmanager"
|
||||
MYSQL_MANAGER_CLIENT="$BASEDIR/bin/mysqlmanagerc"
|
||||
MYSQL_MANAGER_PWGEN="$BASEDIR/bin/mysqlmanager-pwgen"
|
||||
@ -753,9 +756,9 @@ manager_term()
|
||||
{
|
||||
pid=$1
|
||||
ident=$2
|
||||
shift
|
||||
if [ $USE_MANAGER = 0 ] ; then
|
||||
$MYSQLADMIN --no-defaults -uroot --socket=$MYSQL_TMP_DIR/$ident.sock --connect_timeout=5 --shutdown_timeout=20 shutdown >> $MYSQL_MANAGER_LOG 2>&1
|
||||
# Shutdown time must be high as slave may be in reconnect
|
||||
$MYSQLADMIN --no-defaults -uroot --socket=$MYSQL_TMP_DIR/$ident.sock --connect_timeout=5 --shutdown_timeout=70 shutdown >> $MYSQL_MANAGER_LOG 2>&1
|
||||
res=$?
|
||||
# Some systems require an extra connect
|
||||
$MYSQLADMIN --no-defaults -uroot --socket=$MYSQL_TMP_DIR/$ident.sock --connect_timeout=1 ping >> $MYSQL_MANAGER_LOG 2>&1
|
||||
@ -875,8 +878,8 @@ start_slave()
|
||||
[ x$SKIP_SLAVE = x1 ] && return
|
||||
eval "this_slave_running=\$SLAVE$1_RUNNING"
|
||||
[ x$this_slave_running = 1 ] && return
|
||||
#when testing fail-safe replication, we will have more than one slave
|
||||
#in this case, we start secondary slaves with an argument
|
||||
# When testing fail-safe replication, we will have more than one slave
|
||||
# in this case, we start secondary slaves with an argument
|
||||
slave_ident="slave$1"
|
||||
if [ -n "$1" ] ;
|
||||
then
|
||||
@ -984,9 +987,12 @@ EOF
|
||||
|
||||
mysql_start ()
|
||||
{
|
||||
$ECHO "Starting MySQL daemon"
|
||||
start_master
|
||||
start_slave
|
||||
# We should not start the deamon here as we don't know the argumens
|
||||
# for the test. Better to let the test start the deamon
|
||||
|
||||
# $ECHO "Starting MySQL daemon"
|
||||
# start_master
|
||||
# start_slave
|
||||
cd $MYSQL_TEST_DIR
|
||||
return 1
|
||||
}
|
||||
@ -1087,8 +1093,6 @@ run_testcase ()
|
||||
slave_init_script=$TESTDIR/$tname-slave.sh
|
||||
slave_master_info_file=$TESTDIR/$tname-slave-master-info.opt
|
||||
echo $tname > $CURRENT_TEST
|
||||
echo "CURRENT_TEST: $tname" >> $SLAVE_MYERR
|
||||
echo "CURRENT_TEST: $tname" >> $MASTER_MYERR
|
||||
SKIP_SLAVE=`$EXPR \( $tname : rpl \) = 0`
|
||||
if [ $USE_MANAGER = 1 ] ; then
|
||||
many_slaves=`$EXPR \( $tname : rpl_failsafe \) != 0`
|
||||
@ -1125,13 +1129,17 @@ run_testcase ()
|
||||
then
|
||||
EXTRA_MASTER_OPT=`$CAT $master_opt_file | $SED -e "s;\\$MYSQL_TEST_DIR;$MYSQL_TEST_DIR;"`
|
||||
stop_master
|
||||
echo "CURRENT_TEST: $tname" >> $MASTER_MYERR
|
||||
start_master
|
||||
else
|
||||
if [ ! -z "$EXTRA_MASTER_OPT" ] || [ x$MASTER_RUNNING != x1 ] ;
|
||||
then
|
||||
EXTRA_MASTER_OPT=""
|
||||
stop_master
|
||||
echo "CURRENT_TEST: $tname" >> $MASTER_MYERR
|
||||
start_master
|
||||
else
|
||||
echo "CURRENT_TEST: $tname" >> $MASTER_MYERR
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -1161,7 +1169,10 @@ run_testcase ()
|
||||
|
||||
if [ x$do_slave_restart = x1 ] ; then
|
||||
stop_slave
|
||||
echo "CURRENT_TEST: $tname" >> $SLAVE_MYERR
|
||||
start_slave
|
||||
else
|
||||
echo "CURRENT_TEST: $tname" >> $SLAVE_MYERR
|
||||
fi
|
||||
if [ x$many_slaves = x1 ]; then
|
||||
start_slave 1
|
||||
|
@ -1,4 +1,4 @@
|
||||
drop table if exists t1;
|
||||
drop table if exists t1,t2;
|
||||
CREATE TABLE t1 (
|
||||
STRING_DATA char(255) default NULL,
|
||||
KEY string_data (STRING_DATA)
|
||||
@ -316,3 +316,51 @@ CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255));
|
||||
ALTER TABLE t1 ADD INDEX t1 (a, b, c);
|
||||
Specified key was too long. Max key length is 500
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
|
||||
INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
|
||||
create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
|
||||
INSERT into t2 values (1,1,1), (2,2,2);
|
||||
optimize table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize status OK
|
||||
show index from t1;
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
t1 1 b 1 b A 5 NULL NULL YES BTREE
|
||||
t1 1 c 1 c A 5 NULL NULL YES BTREE
|
||||
t1 1 a 1 a A 1 NULL NULL BTREE
|
||||
t1 1 a 2 b A 5 NULL NULL YES BTREE
|
||||
t1 1 c_2 1 c A 5 NULL NULL YES BTREE
|
||||
t1 1 c_2 2 a A 5 NULL NULL BTREE
|
||||
explain select * from t1,t2 where t1.a=t2.a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL a NULL NULL NULL 5
|
||||
1 SIMPLE t2 ALL a NULL NULL NULL 2 Using where
|
||||
explain select * from t1,t2 force index(a) where t1.a=t2.a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ALL a NULL NULL NULL 2
|
||||
1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where
|
||||
explain select * from t1 force index(a),t2 force index(a) where t1.a=t2.a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ALL a NULL NULL NULL 2
|
||||
1 SIMPLE t1 ref a a 4 t2.a 3
|
||||
explain select * from t1,t2 where t1.b=t2.b;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ALL b NULL NULL NULL 2
|
||||
1 SIMPLE t1 ref b b 5 t2.b 1 Using where
|
||||
explain select * from t1,t2 force index(c) where t1.a=t2.a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL a NULL NULL NULL 5
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where
|
||||
explain select * from t1 where a=0 or a=2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where
|
||||
explain select * from t1 force index (a) where a=0 or a=2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range a a 4 NULL 4 Using where
|
||||
explain select * from t1 where c=1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref c,c_2 c 5 const 1 Using where
|
||||
explain select * from t1 use index() where c=1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where
|
||||
drop table t1,t2;
|
||||
|
@ -2,10 +2,15 @@
|
||||
# Test bugs in the MyISAM code
|
||||
#
|
||||
|
||||
# Initialise
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
drop table if exists t1,t2;
|
||||
--enable_warnings
|
||||
|
||||
#
|
||||
# Test problem with CHECK TABLE;
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
STRING_DATA char(255) default NULL,
|
||||
KEY string_data (STRING_DATA)
|
||||
@ -327,3 +332,23 @@ CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255));
|
||||
ALTER TABLE t1 ADD INDEX t1 (a, b, c);
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Test of cardinality of keys with NULL
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
|
||||
INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
|
||||
create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
|
||||
INSERT into t2 values (1,1,1), (2,2,2);
|
||||
optimize table t1;
|
||||
show index from t1;
|
||||
explain select * from t1,t2 where t1.a=t2.a;
|
||||
explain select * from t1,t2 force index(a) where t1.a=t2.a;
|
||||
explain select * from t1 force index(a),t2 force index(a) where t1.a=t2.a;
|
||||
explain select * from t1,t2 where t1.b=t2.b;
|
||||
explain select * from t1,t2 force index(c) where t1.a=t2.a;
|
||||
explain select * from t1 where a=0 or a=2;
|
||||
explain select * from t1 force index (a) where a=0 or a=2;
|
||||
explain select * from t1 where c=1;
|
||||
explain select * from t1 use index() where c=1;
|
||||
drop table t1,t2;
|
||||
|
@ -40,15 +40,33 @@ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
|
||||
return (int) (a_length-b_length);
|
||||
}
|
||||
|
||||
#define FCMP(A,B) ((int) (A) - (int) (B))
|
||||
|
||||
/*
|
||||
Compare two keys
|
||||
Returns <0, 0, >0 acording to which is bigger
|
||||
Key_length specifies length of key to use. Number-keys can't be splited
|
||||
If flag <> SEARCH_FIND compare also position
|
||||
|
||||
SYNOPSIS
|
||||
ha_key_cmp()
|
||||
keyseg Key segments of key to compare
|
||||
a First key to compare, in format from _mi_pack_key()
|
||||
This is normally key specified by user
|
||||
b Second key to compare. This is always from a row
|
||||
key_length Length of key to compare. This can be shorter than
|
||||
a to just compare sub keys
|
||||
next_flag How keys should be compared
|
||||
If bit SEARCH_FIND is not set the keys includes the row
|
||||
position and this should also be compared
|
||||
|
||||
NOTES
|
||||
Number-keys can't be splited
|
||||
|
||||
RETURN VALUES
|
||||
<0 If a < b
|
||||
0 If a == b
|
||||
>0 If a > b
|
||||
*/
|
||||
|
||||
#define FCMP(A,B) ((int) (A) - (int) (B))
|
||||
|
||||
int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
register uchar *b, uint key_length, uint nextflag,
|
||||
uint *diff_pos)
|
||||
@ -59,9 +77,10 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
uint32 u_1,u_2;
|
||||
float f_1,f_2;
|
||||
double d_1,d_2;
|
||||
uint next_key_length;
|
||||
|
||||
*diff_pos=0;
|
||||
for ( ; (int) key_length >0 ; keyseg++)
|
||||
for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++)
|
||||
{
|
||||
uchar *end;
|
||||
uint piks=! (keyseg->flag & HA_NO_SORT);
|
||||
@ -81,10 +100,21 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
{
|
||||
if (nextflag == (SEARCH_FIND | SEARCH_UPDATE))
|
||||
nextflag=SEARCH_SAME; /* Allow duplicate keys */
|
||||
else if (nextflag & SEARCH_NULL_ARE_NOT_EQUAL)
|
||||
{
|
||||
/*
|
||||
This is only used from mi_check() to calculate cardinality.
|
||||
It can't be used when searching for a key as this would cause
|
||||
compare of (a,b) and (b,a) to return the same value.
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
next_key_length=key_length;
|
||||
continue; /* To next key part */
|
||||
}
|
||||
}
|
||||
end= a+ min(keyseg->length,key_length);
|
||||
next_key_length=key_length-keyseg->length;
|
||||
|
||||
switch ((enum ha_base_keytype) keyseg->type) {
|
||||
case HA_KEYTYPE_TEXT: /* Ascii; Key is converted */
|
||||
@ -93,12 +123,12 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
int a_length,b_length,pack_length;
|
||||
get_key_length(a_length,a);
|
||||
get_key_pack_length(b_length,pack_length,b);
|
||||
key_length-= b_length + pack_length;
|
||||
next_key_length=key_length-b_length-pack_length;
|
||||
|
||||
if (piks &&
|
||||
(flag= mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||
key_length <= 0))))
|
||||
(flag=mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||
next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a+=a_length;
|
||||
b+=b_length;
|
||||
@ -107,7 +137,6 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
else
|
||||
{
|
||||
uint length=(uint) (end-a), a_length=length, b_length=length;
|
||||
key_length-= keyseg->length;
|
||||
if (!(nextflag & SEARCH_PREFIX))
|
||||
{
|
||||
while (a_length && a[a_length-1] == ' ')
|
||||
@ -116,9 +145,9 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
b_length--;
|
||||
}
|
||||
if (piks &&
|
||||
(flag= mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||
key_length <= 0))))
|
||||
(flag= mi_compare_text(keyseg->charset, a, a_length, b, b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||
next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a=end;
|
||||
b+=length;
|
||||
@ -130,12 +159,12 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
int a_length,b_length,pack_length;
|
||||
get_key_length(a_length,a);
|
||||
get_key_pack_length(b_length,pack_length,b);
|
||||
key_length-= b_length + pack_length;
|
||||
next_key_length=key_length-b_length-pack_length;
|
||||
|
||||
if (piks &&
|
||||
(flag=compare_bin(a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||
key_length <= 0))))
|
||||
next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a+=a_length;
|
||||
b+=b_length;
|
||||
@ -144,11 +173,10 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
else
|
||||
{
|
||||
uint length=keyseg->length;
|
||||
key_length-= keyseg->length;
|
||||
if (piks &&
|
||||
(flag=compare_bin(a,length,b,length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||
key_length <= 0))))
|
||||
next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a+=length;
|
||||
b+=length;
|
||||
@ -159,12 +187,12 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
int a_length,b_length,pack_length;
|
||||
get_key_length(a_length,a);
|
||||
get_key_pack_length(b_length,pack_length,b);
|
||||
key_length-= b_length + pack_length;
|
||||
next_key_length=key_length-b_length-pack_length;
|
||||
|
||||
if (piks &&
|
||||
(flag= mi_compare_text(keyseg->charset,a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||
key_length <= 0))))
|
||||
next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a+=a_length;
|
||||
b+=b_length;
|
||||
@ -176,12 +204,12 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
int a_length,b_length,pack_length;
|
||||
get_key_length(a_length,a);
|
||||
get_key_pack_length(b_length,pack_length,b);
|
||||
key_length-= b_length + pack_length;
|
||||
next_key_length=key_length-b_length-pack_length;
|
||||
|
||||
if (piks &&
|
||||
(flag=compare_bin(a,a_length,b,b_length,
|
||||
(my_bool) ((nextflag & SEARCH_PREFIX) &&
|
||||
key_length <= 0))))
|
||||
next_key_length <= 0))))
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a+=a_length;
|
||||
b+=b_length;
|
||||
@ -196,7 +224,6 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b++;
|
||||
key_length-= keyseg->length;
|
||||
break;
|
||||
}
|
||||
case HA_KEYTYPE_SHORT_INT:
|
||||
@ -206,7 +233,6 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 2; /* sizeof(short int); */
|
||||
key_length-= keyseg->length;
|
||||
break;
|
||||
case HA_KEYTYPE_USHORT_INT:
|
||||
{
|
||||
@ -217,7 +243,6 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+=2; /* sizeof(short int); */
|
||||
key_length-= keyseg->length;
|
||||
break;
|
||||
}
|
||||
case HA_KEYTYPE_LONG_INT:
|
||||
@ -227,7 +252,6 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 4; /* sizeof(long int); */
|
||||
key_length-= keyseg->length;
|
||||
break;
|
||||
case HA_KEYTYPE_ULONG_INT:
|
||||
u_1= mi_sint4korr(a);
|
||||
@ -236,7 +260,6 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 4; /* sizeof(long int); */
|
||||
key_length-= keyseg->length;
|
||||
break;
|
||||
case HA_KEYTYPE_INT24:
|
||||
l_1=mi_sint3korr(a);
|
||||
@ -245,7 +268,6 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 3;
|
||||
key_length-= keyseg->length;
|
||||
break;
|
||||
case HA_KEYTYPE_UINT24:
|
||||
l_1=mi_uint3korr(a);
|
||||
@ -254,7 +276,6 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 3;
|
||||
key_length-= keyseg->length;
|
||||
break;
|
||||
case HA_KEYTYPE_FLOAT:
|
||||
mi_float4get(f_1,a);
|
||||
@ -263,7 +284,6 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 4; /* sizeof(float); */
|
||||
key_length-= keyseg->length;
|
||||
break;
|
||||
case HA_KEYTYPE_DOUBLE:
|
||||
mi_float8get(d_1,a);
|
||||
@ -272,13 +292,12 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 8; /* sizeof(double); */
|
||||
key_length-= keyseg->length;
|
||||
break;
|
||||
case HA_KEYTYPE_NUM: /* Numeric key */
|
||||
{
|
||||
int swap_flag= 0;
|
||||
int alength,blength;
|
||||
|
||||
|
||||
if (keyseg->flag & HA_REVERSE_SORT)
|
||||
{
|
||||
swap(uchar*,a,b);
|
||||
@ -289,7 +308,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
{
|
||||
alength= *a++; blength= *b++;
|
||||
end=a+alength;
|
||||
key_length-= blength + 1;
|
||||
next_key_length=key_length-blength-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -298,9 +317,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
/* remove pre space from keys */
|
||||
for ( ; alength && *a == ' ' ; a++, alength--) ;
|
||||
for ( ; blength && *b == ' ' ; b++, blength--) ;
|
||||
key_length-= keyseg->length;
|
||||
}
|
||||
|
||||
if (piks)
|
||||
{
|
||||
if (*a == '-')
|
||||
@ -350,7 +367,6 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 8;
|
||||
key_length-= keyseg->length;
|
||||
break;
|
||||
}
|
||||
case HA_KEYTYPE_ULONGLONG:
|
||||
@ -362,7 +378,6 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
|
||||
return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag);
|
||||
a= end;
|
||||
b+= 8;
|
||||
key_length-= keyseg->length;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -48,7 +48,10 @@ $opt_optimization="None";
|
||||
$opt_hw="";
|
||||
$opt_threads=5;
|
||||
|
||||
$opt_time_limit=10*60; # Don't wait more than 10 min for some tests
|
||||
if (!defined($opt_time_limit))
|
||||
{
|
||||
$opt_time_limit=10*60; # Don't wait more than 10 min for some tests
|
||||
}
|
||||
|
||||
$log_prog_args=join(" ", skip_arguments(\@ARGV,"comments","cmp","server",
|
||||
"user", "host", "database", "password",
|
||||
|
@ -39,7 +39,7 @@
|
||||
# as such, and clarify ones such as "mediumint" with comments such as
|
||||
# "3-byte int" or "same as xxx".
|
||||
|
||||
$version="1.59";
|
||||
$version="1.60";
|
||||
|
||||
use DBI;
|
||||
use Getopt::Long;
|
||||
@ -50,7 +50,7 @@ $opt_server="mysql"; $opt_host="localhost"; $opt_database="test";
|
||||
$opt_dir="limits";
|
||||
$opt_user=$opt_password="";$opt_verbose="";
|
||||
$opt_debug=$opt_help=$opt_Information=$opt_restart=$opt_force=$opt_quick=0;
|
||||
$opt_log_all_queries=$opt_fix_limit_file=$opt_batch_mode=0;
|
||||
$opt_log_all_queries=$opt_fix_limit_file=$opt_batch_mode=$opt_version=0;
|
||||
$opt_db_start_cmd=""; # the db server start command
|
||||
$opt_check_server=0; # Check if server is alive before each query
|
||||
$opt_sleep=10; # time to sleep while starting the db server
|
||||
@ -68,8 +68,10 @@ GetOptions("Information","help","server=s","debug","user=s","password=s",
|
||||
"database=s","restart","force","quick","log-all-queries","comment=s",
|
||||
"host=s","fix-limit-file","dir=s","db-start-cmd=s","sleep=s","suffix=s",
|
||||
"batch-mode","config-file=s","log-queries-to-file=s","check-server",
|
||||
"version",
|
||||
"verbose!" => \$opt_verbose) || usage();
|
||||
usage() if ($opt_help || $opt_Information);
|
||||
version() && exit(0) if ($opt_version);
|
||||
|
||||
$opt_suffix = '-'.$opt_suffix if (length($opt_suffix) != 0);
|
||||
$opt_config_file = "$pwd/$opt_dir/$opt_server$opt_suffix.cfg"
|
||||
@ -1190,7 +1192,7 @@ else
|
||||
|
||||
# Test: NOROUND
|
||||
{
|
||||
my $resultat = 'undefined';
|
||||
my $result = 'undefined';
|
||||
my $error;
|
||||
print "NOROUND: ";
|
||||
save_incomplete('func_extra_noround','Function NOROUND');
|
||||
@ -1199,21 +1201,25 @@ else
|
||||
$error = safe_query_l('func_extra_noround',"select noround(22.6) $end_query");
|
||||
if ($error ne 1) # syntax error -- noround is not supported
|
||||
{
|
||||
$resultat = 'no'
|
||||
} else # Ok, now check if it really works
|
||||
{
|
||||
$result = 'no'
|
||||
}
|
||||
else # Ok, now check if it really works
|
||||
{
|
||||
$error=safe_query_l('func_extra_noround',
|
||||
["create table crash_me_nr (a int)",
|
||||
"insert into crash_me_nr values(noround(10.2))",
|
||||
"drop table crash_me_nr $drop_attr"]);
|
||||
if ($error eq 1) {
|
||||
$resultat = "syntax only";
|
||||
} else {
|
||||
$resultat = 'yes';
|
||||
}
|
||||
}
|
||||
print "$resultat\n";
|
||||
save_config_data('func_extra_noround',$resultat,"Function NOROUND");
|
||||
if ($error == 1)
|
||||
{
|
||||
$result= "syntax only";
|
||||
}
|
||||
else
|
||||
{
|
||||
$result= 'yes';
|
||||
}
|
||||
}
|
||||
print "$result\n";
|
||||
save_config_data('func_extra_noround',$result,"Function NOROUND");
|
||||
}
|
||||
|
||||
check_parenthesis("func_sql_","CURRENT_USER");
|
||||
@ -1377,7 +1383,7 @@ if ($limits{'type_sql_date'} eq 'yes')
|
||||
|
||||
# Test: WEEK()
|
||||
{
|
||||
my $resultat="no";
|
||||
my $result="no";
|
||||
my $error;
|
||||
print "WEEK:";
|
||||
save_incomplete('func_odbc_week','WEEK');
|
||||
@ -1388,17 +1394,17 @@ if ($limits{'type_sql_date'} eq 'yes')
|
||||
# and 0 - EURO weeks
|
||||
if ($error == -1) {
|
||||
if ($last_result == 4) {
|
||||
$resultat = 'USA';
|
||||
$result = 'USA';
|
||||
} else {
|
||||
$resultat='error';
|
||||
$result='error';
|
||||
add_log('func_odbc_week',
|
||||
" must return 4 or 5, but $last_result");
|
||||
}
|
||||
} elsif ($error == 0) {
|
||||
$resultat = 'EURO';
|
||||
$result = 'EURO';
|
||||
}
|
||||
print " $resultat\n";
|
||||
save_config_data('func_odbc_week',$resultat,"WEEK");
|
||||
print " $result\n";
|
||||
save_config_data('func_odbc_week',$result,"WEEK");
|
||||
}
|
||||
|
||||
my $insert_query ='insert into crash_me_d values('.
|
||||
@ -1498,7 +1504,7 @@ if ($limits{'type_sql_date'} eq 'yes')
|
||||
# NOT id BETWEEN a and b
|
||||
if ($limits{'func_where_not_between'} eq 'yes')
|
||||
{
|
||||
my $resultat = 'error';
|
||||
my $result = 'error';
|
||||
my $err;
|
||||
my $key='not_id_between';
|
||||
my $prompt='NOT ID BETWEEN interprets as ID NOT BETWEEN';
|
||||
@ -1512,15 +1518,15 @@ if ($limits{'func_where_not_between'} eq 'yes')
|
||||
5,0);
|
||||
if ($err eq 1) {
|
||||
if (not defined($last_result)) {
|
||||
$resultat='no';
|
||||
$result='no';
|
||||
};
|
||||
};
|
||||
if ( $err eq 0) {
|
||||
$resultat = 'yes';
|
||||
$result = 'yes';
|
||||
};
|
||||
safe_query_l($key,["drop table crash_me_b"]);
|
||||
save_config_data($key,$resultat,$prompt);
|
||||
print "$resultat\n";
|
||||
save_config_data($key,$result,$prompt);
|
||||
print "$result\n";
|
||||
};
|
||||
|
||||
|
||||
@ -2018,37 +2024,44 @@ report("views","views",
|
||||
|
||||
# Test: foreign key
|
||||
{
|
||||
my $resultat = 'undefined';
|
||||
my $result = 'undefined';
|
||||
my $error;
|
||||
print "foreign keys: ";
|
||||
save_incomplete('foreign_key','foreign keys');
|
||||
|
||||
# 1) check if foreign keys are supported
|
||||
safe_query_l('foreign_key',create_table("crash_me_qf",["a integer not null"],
|
||||
["primary key (a)"]));
|
||||
$error = safe_query_l('foreign_key',
|
||||
create_table("crash_me_qf2",["a integer not null",
|
||||
"foreign key (a) references crash_me_qf (a)"], []));
|
||||
|
||||
if ($error eq 1) # OK -- syntax is supported
|
||||
safe_query_l('foreign_key',
|
||||
create_table("crash_me_qf",
|
||||
["a integer not null"],
|
||||
["primary key (a)"]));
|
||||
$error= safe_query_l('foreign_key',
|
||||
create_table("crash_me_qf2",
|
||||
["a integer not null",
|
||||
"foreign key (a) references crash_me_qf (a)"],
|
||||
[]));
|
||||
|
||||
if ($error == 1) # OK -- syntax is supported
|
||||
{
|
||||
$resultat = 'error';
|
||||
$result = 'error';
|
||||
# now check if foreign key really works
|
||||
safe_query_l('foreign_key', "insert into crash_me_qf values (1)");
|
||||
if (safe_query_l('foreign_key', "insert into crash_me_qf2 values (2)") eq 1)
|
||||
if (safe_query_l('foreign_key', "insert into crash_me_qf2 values (2)") eq 1)
|
||||
{
|
||||
$resultat = 'syntax only';
|
||||
} else {
|
||||
$resultat = 'yes';
|
||||
}
|
||||
|
||||
} else {
|
||||
$resultat = "no";
|
||||
}
|
||||
safe_query_l('foreign_key',
|
||||
"drop table crash_me_qf2 $drop_attr","drop table crash_me_qf $drop_attr");
|
||||
print "$resultat\n";
|
||||
save_config_data('foreign_key',$resultat,"foreign keys");
|
||||
$result = 'syntax only';
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = 'yes';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = "no";
|
||||
}
|
||||
safe_query_l('foreign_key', "drop table crash_me_qf2 $drop_attr");
|
||||
safe_query_l('foreign_key', "drop table crash_me_qf $drop_attr");
|
||||
print "$result\n";
|
||||
save_config_data('foreign_key',$result,"foreign keys");
|
||||
}
|
||||
|
||||
report("Create SCHEMA","create_schema",
|
||||
@ -2607,7 +2620,7 @@ sub detect_null_position
|
||||
sub check_parenthesis {
|
||||
my $prefix=shift;
|
||||
my $fn=shift;
|
||||
my $resultat='no';
|
||||
my $result='no';
|
||||
my $param_name=$prefix.lc($fn);
|
||||
my $r;
|
||||
|
||||
@ -2616,18 +2629,18 @@ sub check_parenthesis {
|
||||
add_log($param_name,$safe_query_log);
|
||||
if ($r == 1)
|
||||
{
|
||||
$resultat="yes";
|
||||
$result="yes";
|
||||
}
|
||||
else{
|
||||
$r = safe_query("select $fn() $end_query");
|
||||
add_log($param_name,$safe_query_log);
|
||||
if ( $r == 1)
|
||||
{
|
||||
$resultat="with_parenthesis";
|
||||
$result="with_parenthesis";
|
||||
}
|
||||
}
|
||||
|
||||
save_config_data($param_name,$resultat,$fn);
|
||||
save_config_data($param_name,$result,$fn);
|
||||
}
|
||||
|
||||
sub check_constraint {
|
||||
@ -2699,10 +2712,16 @@ sub make_date {
|
||||
}
|
||||
|
||||
|
||||
sub version
|
||||
{
|
||||
print "$0 Ver $version\n";
|
||||
}
|
||||
|
||||
|
||||
sub usage
|
||||
{
|
||||
version();
|
||||
print <<EOF;
|
||||
$0 Ver $version
|
||||
|
||||
This program tries to find all limits and capabilities for a SQL
|
||||
server. As it will use the server in some 'unexpected' ways, one
|
||||
@ -3048,7 +3067,7 @@ sub safe_query_l {
|
||||
my $r = safe_query($q);
|
||||
add_log($key,$safe_query_log);
|
||||
return $r;
|
||||
}
|
||||
}
|
||||
|
||||
sub safe_query
|
||||
{
|
||||
@ -3110,7 +3129,6 @@ sub safe_query
|
||||
$retry = $retry_limit;
|
||||
$retry_ok = 1;
|
||||
$safe_query_log .= "> OK\n";
|
||||
|
||||
}
|
||||
$sth->finish;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ $opt_start_field_count=8; # start with this many fields
|
||||
$opt_loop_count=20; # How many tests to do
|
||||
$opt_row_count=1000; # Rows in the table
|
||||
$opt_field_count=1000; # Add until this many fields.
|
||||
$opt_time_limit=10*60; # Don't wait more than 10 min for some tests
|
||||
|
||||
chomp($pwd = `pwd`); $pwd = "." if ($pwd eq '');
|
||||
require "$pwd/bench-init.pl" || die "Can't read Configuration file: $!\n";
|
||||
@ -113,10 +114,9 @@ if ($opt_fast)
|
||||
}
|
||||
else
|
||||
{
|
||||
$add=1 if (!$limits{'alter_add_multi_col'});
|
||||
$add=1 if (!$limits->{'alter_add_multi_col'});
|
||||
}
|
||||
|
||||
|
||||
$count=0;
|
||||
while ($field_count < $opt_field_count)
|
||||
{
|
||||
@ -131,19 +131,43 @@ while ($field_count < $opt_field_count)
|
||||
$tmp="" if (!$multi_add); # Adabas
|
||||
}
|
||||
do_query($dbh,"ALTER TABLE bench " . substr($fields,1));
|
||||
$end_time=new Benchmark;
|
||||
last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$count,
|
||||
$opt_field_count/$add+1));
|
||||
}
|
||||
|
||||
$end_time=new Benchmark;
|
||||
print "Time for alter_table_add ($count): " .
|
||||
if ($estimated)
|
||||
{ print "Estimated time"; }
|
||||
else
|
||||
{ print "Time"; }
|
||||
print " for alter_table_add ($count): " .
|
||||
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
|
||||
|
||||
#
|
||||
# If estimated, fix table to have known number of fields
|
||||
#
|
||||
if ($estimated && $field_count < $opt_field_count)
|
||||
{
|
||||
$fields="";
|
||||
$tmp="ADD ";
|
||||
while ($field_count < $opt_field_count)
|
||||
{
|
||||
$field_count++;
|
||||
$fields.=",$tmp i${field_count} integer";
|
||||
$tmp="" if (!$multi_add); # Adabas
|
||||
}
|
||||
do_query($dbh,"ALTER TABLE bench " . substr($fields,1));
|
||||
}
|
||||
|
||||
####
|
||||
#### Test adding and deleting index on the first $opt_start_fields
|
||||
####
|
||||
|
||||
$loop_time=new Benchmark;
|
||||
|
||||
for ($i=1; $i < $opt_start_field_count ; $i++)
|
||||
$count= 0;
|
||||
for ($i=1; $i <= $opt_start_field_count ; $i++)
|
||||
{
|
||||
$dbh->do("CREATE INDEX bench_ind$i ON bench (i${i})") || die $DBI::errstr;
|
||||
}
|
||||
@ -153,7 +177,7 @@ print "Time for create_index ($opt_start_field_count): " .
|
||||
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
|
||||
|
||||
$loop_time=new Benchmark;
|
||||
for ($i=1; $i < $opt_start_field_count ; $i++)
|
||||
for ($i=1; $i <= $opt_start_field_count ; $i++)
|
||||
{
|
||||
$dbh->do($server->drop_index("bench","bench_ind$i")) || die $DBI::errstr;
|
||||
}
|
||||
@ -182,10 +206,17 @@ while ($field_count > $opt_start_field_count)
|
||||
}
|
||||
$dbh->do("ALTER TABLE bench " . substr($fields,1) . $server->{'drop_attr'})
|
||||
|| die $DBI::errstr;
|
||||
$end_time=new Benchmark;
|
||||
last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$count,
|
||||
$opt_field_count/$add+1));
|
||||
}
|
||||
|
||||
$end_time=new Benchmark;
|
||||
print "Time for alter_table_drop ($count): " .
|
||||
if ($estimated)
|
||||
{ print "Estimated time"; }
|
||||
else
|
||||
{ print "Time"; }
|
||||
print " for alter_table_drop ($count): " .
|
||||
timestr(timediff($end_time, $loop_time),"all") . "\n\n";
|
||||
|
||||
skip_dropcol:
|
||||
|
@ -21,10 +21,11 @@
|
||||
# $opt_loop_count rows in random order
|
||||
#
|
||||
# changes made for Oracle compatibility
|
||||
# - $limits{'func_odbc_mod'} is OK from crash-me, but it fails here so set we
|
||||
# - $limits->{'func_odbc_mod'} is OK from crash-me, but it fails here so set we
|
||||
# set it to 0 in server-cfg
|
||||
# - the default server config runs out of rollback segments, so I added a couple
|
||||
# of disconnect/connects to reset
|
||||
# - the default server config runs out of rollback segments, so we added a
|
||||
# couple of disconnect/connects to reset
|
||||
#
|
||||
##################### Standard benchmark inits ##############################
|
||||
|
||||
use DBI;
|
||||
|
@ -161,6 +161,7 @@ static SYMBOL symbols[] = {
|
||||
{ "FLUSH", SYM(FLUSH_SYM),0,0},
|
||||
{ "FALSE", SYM(FALSE_SYM),0,0},
|
||||
{ "FOREIGN", SYM(FOREIGN),0,0},
|
||||
{ "FORCE", SYM(FORCE_SYM),0,0},
|
||||
{ "RAID_TYPE", SYM(RAID_TYPE),0,0},
|
||||
{ "RAID_CHUNKS", SYM(RAID_CHUNKS),0,0},
|
||||
{ "RAID_CHUNKSIZE", SYM(RAID_CHUNKSIZE),0,0},
|
||||
|
@ -294,7 +294,19 @@ Log_event::Log_event(const char* buf, bool old_format)
|
||||
****************************************************************************/
|
||||
int Log_event::exec_event(struct st_relay_log_info* rli)
|
||||
{
|
||||
if (rli) // QQ When is this not true ?
|
||||
/*
|
||||
rli is null when (as far as I (Guilhem) know)
|
||||
the caller is
|
||||
Load_log_event::exec_event *and* that one is called from
|
||||
Execute_load_log_event::exec_event.
|
||||
In this case, we don't do anything here ;
|
||||
Execute_load_log_event::exec_event will call Log_event::exec_event
|
||||
again later with the proper rli.
|
||||
Strictly speaking, if we were sure that rli is null
|
||||
only in the case discussed above, 'if (rli)' is useless here.
|
||||
But as we are not 100% sure, keep it for now.
|
||||
*/
|
||||
if (rli)
|
||||
{
|
||||
if (rli->inside_transaction)
|
||||
rli->inc_pending(get_event_len());
|
||||
@ -1435,13 +1447,36 @@ void Load_log_event::set_fields(List<Item> &field_list)
|
||||
}
|
||||
#endif // !MYSQL_CLIENT
|
||||
|
||||
/*****************************************************************************
|
||||
|
||||
Load_log_event::exec_event()
|
||||
|
||||
****************************************************************************/
|
||||
#ifndef MYSQL_CLIENT
|
||||
int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli)
|
||||
|
||||
/*
|
||||
Does the data loading job when executing a LOAD DATA on the slave
|
||||
|
||||
SYNOPSIS
|
||||
Load_log_event::exec_event
|
||||
net
|
||||
rli
|
||||
use_rli_only_for_errors - if set to 1, rli is provided to
|
||||
Load_log_event::exec_event only for this
|
||||
function to have RPL_LOG_NAME and
|
||||
rli->last_slave_error, both being used by
|
||||
error reports. rli's position advancing
|
||||
is skipped (done by the caller which is
|
||||
Execute_load_log_event::exec_event).
|
||||
- if set to 0, rli is provided for full use,
|
||||
i.e. for error reports and position
|
||||
advancing.
|
||||
|
||||
DESCRIPTION
|
||||
Does the data loading job when executing a LOAD DATA on the slave
|
||||
|
||||
RETURN VALUE
|
||||
0 Success
|
||||
1 Failure
|
||||
*/
|
||||
|
||||
int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
|
||||
bool use_rli_only_for_errors)
|
||||
{
|
||||
init_sql_alloc(&thd->mem_root, 8192,0);
|
||||
thd->db = rewrite_db((char*)db);
|
||||
@ -1503,9 +1538,15 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli)
|
||||
TL_WRITE))
|
||||
thd->query_error = 1;
|
||||
if (thd->cuted_fields)
|
||||
{
|
||||
/*
|
||||
log_pos is the position of the LOAD
|
||||
event in the master log
|
||||
*/
|
||||
sql_print_error("Slave: load data infile at position %s in log \
|
||||
'%s' produced %d warning(s)", llstr(rli->master_log_pos,llbuff), RPL_LOG_NAME,
|
||||
'%s' produced %d warning(s)", llstr(log_pos,llbuff), RPL_LOG_NAME,
|
||||
thd->cuted_fields );
|
||||
}
|
||||
if (net)
|
||||
net->pkt_nr= thd->net.pkt_nr;
|
||||
}
|
||||
@ -1544,7 +1585,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return Log_event::exec_event(rli);
|
||||
return ( use_rli_only_for_errors ? 0 : Log_event::exec_event(rli) );
|
||||
}
|
||||
#endif // !MYSQL_CLIENT
|
||||
|
||||
@ -2680,7 +2721,11 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
|
||||
save_options = thd->options;
|
||||
thd->options &= ~ (ulong) (OPTION_BIN_LOG);
|
||||
lev->thd = thd;
|
||||
if (lev->exec_event(0,0))
|
||||
/*
|
||||
lev->exec_event should use rli only for errors
|
||||
i.e. should not advance rli's position
|
||||
*/
|
||||
if (lev->exec_event(0,rli,1))
|
||||
{
|
||||
slave_print_error(rli,my_errno, "Failed executing load from '%s'", fname);
|
||||
thd->options = save_options;
|
||||
|
@ -460,9 +460,10 @@ public:
|
||||
const char* get_db() { return db; }
|
||||
int exec_event(struct st_relay_log_info* rli)
|
||||
{
|
||||
return exec_event(thd->slave_net,rli);
|
||||
return exec_event(thd->slave_net,rli,0);
|
||||
}
|
||||
int exec_event(NET* net, struct st_relay_log_info* rli);
|
||||
int exec_event(NET* net, struct st_relay_log_info* rli,
|
||||
bool use_rli_only_for_errors);
|
||||
#else
|
||||
void print(FILE* file, bool short_form = 0, char* last_db = 0);
|
||||
#endif
|
||||
|
@ -235,6 +235,10 @@ void debug_sync_point(const char* lock_name, uint lock_timeout);
|
||||
#define SHOW_LOG_STATUS_FREE "FREE"
|
||||
#define SHOW_LOG_STATUS_INUSE "IN USE"
|
||||
|
||||
/* Options to add_table_to_list() */
|
||||
#define TL_OPTION_UPDATING 1
|
||||
#define TL_OPTION_FORCE_INDEX 2
|
||||
|
||||
/* Some portable defines */
|
||||
|
||||
#define portable_sizeof_char_ptr 8
|
||||
@ -820,7 +824,6 @@ uint calc_week(TIME *ltime, bool with_year, bool sunday_first_day_of_week,
|
||||
void find_date(char *pos,uint *vek,uint flag);
|
||||
TYPELIB *convert_strings_to_array_type(my_string *typelibs, my_string *end);
|
||||
TYPELIB *typelib(List<String> &strings);
|
||||
void clean_up(bool print_message=1);
|
||||
ulong get_form_pos(File file, uchar *head, TYPELIB *save_names);
|
||||
ulong make_new_entry(File file,uchar *fileinfo,TYPELIB *formnames,
|
||||
const char *newname);
|
||||
|
@ -491,6 +491,7 @@ extern "C" pthread_handler_decl(handle_slave,arg);
|
||||
static uint set_maximum_open_files(uint max_file_limit);
|
||||
#endif
|
||||
static ulong find_bit_type(const char *x, TYPELIB *bit_lib);
|
||||
static void clean_up(bool print_message);
|
||||
|
||||
/****************************************************************************
|
||||
** Code to end mysqld
|
||||
@ -763,13 +764,13 @@ void kill_mysql(void)
|
||||
|
||||
#if defined(OS2)
|
||||
extern "C" void kill_server(int sig_ptr)
|
||||
#define RETURN_FROM_KILL_SERVER return
|
||||
#define RETURN_FROM_KILL_SERVER DBUG_RETURN
|
||||
#elif !defined(__WIN__)
|
||||
static void *kill_server(void *sig_ptr)
|
||||
#define RETURN_FROM_KILL_SERVER return 0
|
||||
#define RETURN_FROM_KILL_SERVER DBUG_RETURN(0)
|
||||
#else
|
||||
static void __cdecl kill_server(int sig_ptr)
|
||||
#define RETURN_FROM_KILL_SERVER return
|
||||
#define RETURN_FROM_KILL_SERVER DBUG_RETURN
|
||||
#endif
|
||||
{
|
||||
int sig=(int) (long) sig_ptr; // This is passed a int
|
||||
@ -848,7 +849,7 @@ extern "C" sig_handler print_signal_warning(int sig)
|
||||
|
||||
void unireg_end(void)
|
||||
{
|
||||
clean_up();
|
||||
clean_up(1);
|
||||
my_thread_end();
|
||||
#ifdef SIGNALS_DONT_BREAK_READ
|
||||
exit(0);
|
||||
@ -863,7 +864,7 @@ extern "C" void unireg_abort(int exit_code)
|
||||
DBUG_ENTER("unireg_abort");
|
||||
if (exit_code)
|
||||
sql_print_error("Aborting\n");
|
||||
clean_up(); /* purecov: inspected */
|
||||
clean_up(1); /* purecov: inspected */
|
||||
DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
|
||||
my_thread_end();
|
||||
exit(exit_code); /* purecov: inspected */
|
||||
@ -908,12 +909,12 @@ void clean_up(bool print_message)
|
||||
regex_end();
|
||||
#endif
|
||||
|
||||
if (print_message && errmesg)
|
||||
sql_print_error(ER(ER_SHUTDOWN_COMPLETE),my_progname);
|
||||
#if !defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
|
||||
if (!opt_bootstrap)
|
||||
(void) my_delete(pidfile_name,MYF(0)); // This may not always exist
|
||||
#endif
|
||||
if (print_message && errmesg)
|
||||
sql_print_error(ER(ER_SHUTDOWN_COMPLETE),my_progname);
|
||||
x_free((gptr) my_errmsg[ERRMAPP]); /* Free messages */
|
||||
DBUG_PRINT("quit", ("Error messages freed"));
|
||||
/* Tell main we are ready */
|
||||
@ -923,6 +924,10 @@ void clean_up(bool print_message)
|
||||
/* do the broadcast inside the lock to ensure that my_end() is not called */
|
||||
(void) pthread_cond_broadcast(&COND_thread_count);
|
||||
(void) pthread_mutex_unlock(&LOCK_thread_count);
|
||||
/*
|
||||
The following lines may never be executed as the main thread may have
|
||||
killed us
|
||||
*/
|
||||
DBUG_PRINT("quit", ("done with cleanup"));
|
||||
} /* clean_up */
|
||||
|
||||
@ -1502,7 +1507,7 @@ static void init_signals(void)
|
||||
/* Change limits so that we will get a core file */
|
||||
struct rlimit rl;
|
||||
rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
|
||||
if (setrlimit(RLIMIT_CORE, &rl))
|
||||
if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
|
||||
sql_print_error("Warning: setrlimit could not change the size of core files to 'infinity'; We may not be able to generate a core file on signals");
|
||||
}
|
||||
#endif
|
||||
@ -1571,8 +1576,11 @@ extern "C" void *signal_hand(void *arg __attribute__((unused)))
|
||||
my_thread_init(); // Init new thread
|
||||
DBUG_ENTER("signal_hand");
|
||||
SIGNAL_THD;
|
||||
/* Setup alarm handler */
|
||||
init_thr_alarm(max_connections+max_insert_delayed_threads);
|
||||
/*
|
||||
Setup alarm handler
|
||||
The two extra handlers are for slave threads
|
||||
*/
|
||||
init_thr_alarm(max_connections+max_insert_delayed_threads+2);
|
||||
#if SIGINT != THR_KILL_SIGNAL
|
||||
(void) sigemptyset(&set); // Setup up SIGINT for debug
|
||||
(void) sigaddset(&set,SIGINT); // For debugging
|
||||
@ -1660,12 +1668,15 @@ extern "C" void *signal_hand(void *arg __attribute__((unused)))
|
||||
}
|
||||
break;
|
||||
case SIGHUP:
|
||||
reload_acl_and_cache((THD*) 0,
|
||||
(REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
|
||||
REFRESH_STATUS | REFRESH_GRANT | REFRESH_THREADS |
|
||||
REFRESH_HOSTS),
|
||||
(TABLE_LIST*) 0); // Flush logs
|
||||
mysql_print_status((THD*) 0); // Send debug some info
|
||||
if (!abort_loop)
|
||||
{
|
||||
reload_acl_and_cache((THD*) 0,
|
||||
(REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
|
||||
REFRESH_STATUS | REFRESH_GRANT |
|
||||
REFRESH_THREADS | REFRESH_HOSTS),
|
||||
(TABLE_LIST*) 0); // Flush logs
|
||||
mysql_print_status((THD*) 0); // Send debug some info
|
||||
}
|
||||
break;
|
||||
#ifdef USE_ONE_SIGNAL_HAND
|
||||
case THR_SERVER_ALARM:
|
||||
|
@ -603,12 +603,14 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
|
||||
records++; /* purecov: inspected */
|
||||
scan_time=(double) records / TIME_FOR_COMPARE+1;
|
||||
read_time=(double) head->file->scan_time()+ scan_time + 1.0;
|
||||
if (head->force_index)
|
||||
scan_time= read_time= DBL_MAX;
|
||||
if (limit < records)
|
||||
read_time=(double) records+scan_time+1; // Force to use index
|
||||
else if (read_time <= 2.0 && !force_quick_range)
|
||||
DBUG_RETURN(0); /* No need for quick select */
|
||||
|
||||
DBUG_PRINT("info",("Time to scan table: %ld",(long) read_time));
|
||||
DBUG_PRINT("info",("Time to scan table: %g", read_time));
|
||||
|
||||
keys_to_use&=head->keys_in_use_for_query;
|
||||
if (keys_to_use)
|
||||
|
@ -171,7 +171,10 @@ net_printf(THD *thd, uint errcode, ...)
|
||||
{
|
||||
if (thd->bootstrap)
|
||||
{
|
||||
/* In bootstrap it's ok to print on stderr */
|
||||
/*
|
||||
In bootstrap it's ok to print on stderr
|
||||
This may also happen when we get an error from a slave thread
|
||||
*/
|
||||
fprintf(stderr,"ERROR: %d %s\n",errcode,text_pos);
|
||||
thd->fatal_error=1;
|
||||
}
|
||||
|
@ -413,6 +413,7 @@ int terminate_slave_threads(MASTER_INFO* mi,int thread_mask,bool skip_lock)
|
||||
}
|
||||
if ((thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL)) && mi->slave_running)
|
||||
{
|
||||
DBUG_PRINT("info",("Terminating IO thread"));
|
||||
mi->abort_slave=1;
|
||||
if ((error=terminate_slave_thread(mi->io_thd,io_lock,
|
||||
io_cond_lock,
|
||||
@ -423,6 +424,7 @@ int terminate_slave_threads(MASTER_INFO* mi,int thread_mask,bool skip_lock)
|
||||
}
|
||||
if ((thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL)) && mi->rli.slave_running)
|
||||
{
|
||||
DBUG_PRINT("info",("Terminating SQL thread"));
|
||||
DBUG_ASSERT(mi->rli.sql_thd != 0) ;
|
||||
mi->rli.abort_slave=1;
|
||||
if ((error=terminate_slave_thread(mi->rli.sql_thd,sql_lock,
|
||||
@ -2572,12 +2574,6 @@ static int process_io_rotate(MASTER_INFO *mi, Rotate_log_event *rev)
|
||||
|
||||
memcpy(mi->master_log_name, rev->new_log_ident, rev->ident_len+1);
|
||||
mi->master_log_pos= rev->pos;
|
||||
|
||||
pthread_mutex_lock(&mi->rli.data_lock);
|
||||
memcpy(mi->rli.master_log_name, rev->new_log_ident, rev->ident_len+1);
|
||||
mi->rli.master_log_pos= rev->pos;
|
||||
pthread_mutex_unlock(&mi->rli.data_lock);
|
||||
|
||||
DBUG_PRINT("info", ("master_log_pos: '%s' %d",
|
||||
mi->master_log_name, (ulong) mi->master_log_pos));
|
||||
#ifndef DBUG_OFF
|
||||
|
@ -747,7 +747,7 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
|
||||
table->tablenr=thd->current_tablenr++;
|
||||
table->used_fields=0;
|
||||
table->const_table=0;
|
||||
table->outer_join=table->null_row=table->maybe_null=0;
|
||||
table->outer_join= table->null_row= table->maybe_null= table->force_index= 0;
|
||||
table->status=STATUS_NO_RECORD;
|
||||
table->keys_in_use_for_query= table->keys_in_use;
|
||||
table->used_keys= table->keys_for_keyread;
|
||||
@ -906,7 +906,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
|
||||
table->tablenr=thd->current_tablenr++;
|
||||
table->used_fields=0;
|
||||
table->const_table=0;
|
||||
table->outer_join=table->null_row=table->maybe_null=0;
|
||||
table->outer_join= table->null_row= table->maybe_null= table->force_index= 0;
|
||||
table->status=STATUS_NO_RECORD;
|
||||
table->keys_in_use_for_query= table->keys_in_use;
|
||||
table->used_keys= table->keys_for_keyread;
|
||||
@ -977,6 +977,7 @@ bool reopen_table(TABLE *table,bool locked)
|
||||
tmp.status= table->status;
|
||||
tmp.keys_in_use_for_query= tmp.keys_in_use;
|
||||
tmp.used_keys= tmp.keys_for_keyread;
|
||||
tmp.force_index= tmp.force_index;
|
||||
|
||||
/* Get state */
|
||||
tmp.key_length= table->key_length;
|
||||
@ -1969,6 +1970,7 @@ bool setup_tables(TABLE_LIST *tables)
|
||||
table->maybe_null=test(table->outer_join=table_list->outer_join);
|
||||
table->tablenr=tablenr;
|
||||
table->map= (table_map) 1 << tablenr;
|
||||
table->force_index= table_list->force_index;
|
||||
if (table_list->use_index)
|
||||
{
|
||||
key_map map= get_key_map_from_key_list(table,
|
||||
|
@ -1171,13 +1171,14 @@ List<String>* st_select_lex_node::get_use_index() { return 0; }
|
||||
List<String>* st_select_lex_node::get_ignore_index() { return 0; }
|
||||
TABLE_LIST *st_select_lex_node::add_table_to_list(THD *thd, Table_ident *table,
|
||||
LEX_STRING *alias,
|
||||
bool updating,
|
||||
ulong table_join_options,
|
||||
thr_lock_type flags,
|
||||
List<String> *use_index,
|
||||
List<String> *ignore_index)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
ulong st_select_lex_node::get_table_join_options() { return 0; }
|
||||
|
||||
/*
|
||||
This is used for UNION & subselect to create a new table list of all used
|
||||
@ -1334,6 +1335,11 @@ List<String>* st_select_lex::get_ignore_index()
|
||||
return ignore_index_ptr;
|
||||
}
|
||||
|
||||
ulong st_select_lex::get_table_join_options()
|
||||
{
|
||||
return table_join_options;
|
||||
}
|
||||
|
||||
/*
|
||||
There are st_select_lex::add_table_to_list &
|
||||
st_select_lex::set_lock_for_tables in sql_parse.cc
|
||||
|
@ -243,9 +243,10 @@ public:
|
||||
virtual List<Item>* get_item_list();
|
||||
virtual List<String>* get_use_index();
|
||||
virtual List<String>* get_ignore_index();
|
||||
virtual ulong get_table_join_options();
|
||||
virtual TABLE_LIST *add_table_to_list(THD *thd, Table_ident *table,
|
||||
LEX_STRING *alias,
|
||||
bool updating,
|
||||
ulong table_options,
|
||||
thr_lock_type flags= TL_UNLOCK,
|
||||
List<String> *use_index= 0,
|
||||
List<String> *ignore_index= 0);
|
||||
@ -336,6 +337,7 @@ public:
|
||||
List<Item_func_match> ftfunc_list_alloc;
|
||||
JOIN *join; /* after JOIN::prepare it is pointer to corresponding JOIN */
|
||||
const char *type; /* type of select for EXPLAIN */
|
||||
ulong table_join_options;
|
||||
uint in_sum_expr;
|
||||
uint select_number; /* number of select (used for EXPLAIN) */
|
||||
bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */
|
||||
@ -373,9 +375,10 @@ public:
|
||||
List<Item>* get_item_list();
|
||||
List<String>* get_use_index();
|
||||
List<String>* get_ignore_index();
|
||||
ulong get_table_join_options();
|
||||
TABLE_LIST* add_table_to_list(THD *thd, Table_ident *table,
|
||||
LEX_STRING *alias,
|
||||
bool updating,
|
||||
ulong table_options,
|
||||
thr_lock_type flags= TL_UNLOCK,
|
||||
List<String> *use_index= 0,
|
||||
List<String> *ignore_index= 0);
|
||||
|
@ -518,7 +518,8 @@ check_connections(THD *thd)
|
||||
vio_in_addr(net->vio,&thd->remote.sin_addr);
|
||||
thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors);
|
||||
/* Cut very long hostnames to avoid possible overflows */
|
||||
thd->host[min(strlen(thd->host), HOSTNAME_LENGTH)]= 0;
|
||||
if (thd->host)
|
||||
thd->host[min(strlen(thd->host), HOSTNAME_LENGTH)]= 0;
|
||||
if (connect_errors > max_connect_errors)
|
||||
return(ER_HOST_IS_BLOCKED);
|
||||
}
|
||||
@ -3597,11 +3598,30 @@ bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Add a table to list of used tables
|
||||
|
||||
SYNOPSIS
|
||||
add_table_to_list()
|
||||
table Table to add
|
||||
alias alias for table (or null if no alias)
|
||||
table_options A set of the following bits:
|
||||
TL_OPTION_UPDATING Table will be updated
|
||||
TL_OPTION_FORCE_INDEX Force usage of index
|
||||
lock_type How table should be locked
|
||||
use_index List of indexed used in USE INDEX
|
||||
ignore_index List of indexed used in IGNORE INDEX
|
||||
|
||||
RETURN
|
||||
0 Error
|
||||
# Pointer to TABLE_LIST element added to the total table list
|
||||
*/
|
||||
|
||||
TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
||||
Table_ident *table,
|
||||
LEX_STRING *alias,
|
||||
bool updating,
|
||||
thr_lock_type flags,
|
||||
ulong table_options,
|
||||
thr_lock_type lock_type,
|
||||
List<String> *use_index,
|
||||
List<String> *ignore_index)
|
||||
{
|
||||
@ -3658,8 +3678,9 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
||||
}
|
||||
ptr->real_name=table->table.str;
|
||||
ptr->real_name_length=table->table.length;
|
||||
ptr->lock_type=flags;
|
||||
ptr->updating=updating;
|
||||
ptr->lock_type= lock_type;
|
||||
ptr->updating= test(table_options & TL_OPTION_UPDATING);
|
||||
ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
|
||||
ptr->derived= (SELECT_LEX_UNIT *) table->sel;
|
||||
if (use_index)
|
||||
ptr->use_index=(List<String> *) thd->memdup((gptr) use_index,
|
||||
@ -3669,7 +3690,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
||||
sizeof(*ignore_index));
|
||||
|
||||
/* check that used name is unique */
|
||||
if (flags != TL_IGNORE)
|
||||
if (lock_type != TL_IGNORE)
|
||||
{
|
||||
for (TABLE_LIST *tables=(TABLE_LIST*) table_list.first ;
|
||||
tables ;
|
||||
|
@ -2305,7 +2305,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
|
||||
!(s->quick && best_key && s->quick->index == best_key->key &&
|
||||
best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&
|
||||
!((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) &&
|
||||
s->table->used_keys && best_key))
|
||||
s->table->used_keys && best_key) &&
|
||||
!(s->table->force_index && best_key))
|
||||
{ // Check full join
|
||||
if (s->on_expr)
|
||||
{
|
||||
|
@ -1497,6 +1497,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
|
||||
case SHOW_RPL_STATUS:
|
||||
end= strmov(buff, rpl_status_type[(int)rpl_status]);
|
||||
break;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
case SHOW_SLAVE_RUNNING:
|
||||
{
|
||||
LOCK_ACTIVE_MI;
|
||||
@ -1505,6 +1506,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables,
|
||||
UNLOCK_ACTIVE_MI;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case SHOW_OPENTABLES:
|
||||
end= int10_to_str((long) cached_tables(), buff, 10);
|
||||
break;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2000-2001 MySQL AB
|
||||
/* Copyright (C) 2000-2003 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -222,6 +222,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
||||
%token FIRST_SYM
|
||||
%token FIXED_SYM
|
||||
%token FLOAT_NUM
|
||||
%token FORCE_SYM
|
||||
%token FOREIGN
|
||||
%token FROM
|
||||
%token FULL
|
||||
@ -823,7 +824,8 @@ create:
|
||||
($2 &
|
||||
HA_LEX_CREATE_TMP_TABLE ?
|
||||
&tmp_table_alias :
|
||||
(LEX_STRING*) 0),1,
|
||||
(LEX_STRING*) 0),
|
||||
TL_OPTION_UPDATING,
|
||||
((using_update_log)?
|
||||
TL_READ_NO_INSERT:
|
||||
TL_READ)))
|
||||
@ -844,7 +846,8 @@ create:
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->sql_command= SQLCOM_CREATE_INDEX;
|
||||
if (!lex->current_select->add_table_to_list(lex->thd, $7,NULL,1))
|
||||
if (!lex->current_select->add_table_to_list(lex->thd, $7, NULL,
|
||||
TL_OPTION_UPDATING))
|
||||
YYABORT;
|
||||
lex->create_list.empty();
|
||||
lex->key_list.empty();
|
||||
@ -1380,6 +1383,7 @@ opt_unique_or_fulltext:
|
||||
key_alg:
|
||||
/* empty */ { $$= HA_KEY_ALG_UNDEF; }
|
||||
| USING opt_btree_or_rtree { $$= $2; };
|
||||
| TYPE_SYM opt_btree_or_rtree { $$= $2; };
|
||||
|
||||
opt_btree_or_rtree:
|
||||
BTREE_SYM { $$= HA_KEY_ALG_BTREE; }
|
||||
@ -1413,7 +1417,8 @@ alter:
|
||||
LEX *lex=&thd->lex;
|
||||
lex->sql_command = SQLCOM_ALTER_TABLE;
|
||||
lex->name=0;
|
||||
if (!lex->select_lex.add_table_to_list(thd, $4, NULL,1))
|
||||
if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
|
||||
TL_OPTION_UPDATING))
|
||||
YYABORT;
|
||||
lex->drop_primary=0;
|
||||
lex->create_list.empty();
|
||||
@ -1679,8 +1684,10 @@ table_to_table:
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
SELECT_LEX_NODE *sl= lex->current_select;
|
||||
if (!sl->add_table_to_list(lex->thd, $1,NULL,1,TL_IGNORE) ||
|
||||
!sl->add_table_to_list(lex->thd, $3,NULL,1,TL_IGNORE))
|
||||
if (!sl->add_table_to_list(lex->thd, $1,NULL,TL_OPTION_UPDATING,
|
||||
TL_IGNORE) ||
|
||||
!sl->add_table_to_list(lex->thd, $3,NULL,TL_OPTION_UPDATING,
|
||||
TL_IGNORE))
|
||||
YYABORT;
|
||||
};
|
||||
|
||||
@ -2532,12 +2539,14 @@ join_table:
|
||||
{
|
||||
SELECT_LEX *sel= Select->select_lex();
|
||||
sel->use_index_ptr=sel->ignore_index_ptr=0;
|
||||
sel->table_join_options= 0;
|
||||
}
|
||||
table_ident opt_table_alias opt_key_definition
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
SELECT_LEX_NODE *sel= lex->current_select;
|
||||
if (!($$= sel->add_table_to_list(lex->thd, $2, $3, 0,
|
||||
if (!($$= sel->add_table_to_list(lex->thd, $2, $3,
|
||||
sel->get_table_join_options(),
|
||||
lex->lock_option,
|
||||
sel->get_use_index(),
|
||||
sel->get_ignore_index())))
|
||||
@ -2583,6 +2592,13 @@ opt_key_definition:
|
||||
sel->use_index= *$2;
|
||||
sel->use_index_ptr= &sel->use_index;
|
||||
}
|
||||
| FORCE_SYM key_usage_list
|
||||
{
|
||||
SELECT_LEX *sel= Select->select_lex();
|
||||
sel->use_index= *$2;
|
||||
sel->use_index_ptr= &sel->use_index;
|
||||
sel->table_join_options|= TL_OPTION_FORCE_INDEX;
|
||||
}
|
||||
| IGNORE_SYM key_usage_list
|
||||
{
|
||||
SELECT_LEX *sel= Select->select_lex();
|
||||
@ -2592,8 +2608,14 @@ opt_key_definition:
|
||||
|
||||
key_usage_list:
|
||||
key_or_index { Select->select_lex()->interval_list.empty(); }
|
||||
'(' key_usage_list2 ')'
|
||||
{ $$= &Select->select_lex()->interval_list; };
|
||||
'(' key_list_or_empty ')'
|
||||
{ $$= &Select->select_lex()->interval_list; }
|
||||
;
|
||||
|
||||
key_list_or_empty:
|
||||
/* empty */ {}
|
||||
| key_usage_list2 {}
|
||||
;
|
||||
|
||||
key_usage_list2:
|
||||
key_usage_list2 ',' ident
|
||||
@ -2954,7 +2976,8 @@ drop:
|
||||
lex->drop_list.empty();
|
||||
lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
|
||||
$3.str));
|
||||
if (!lex->current_select->add_table_to_list(lex->thd, $5,NULL, 1))
|
||||
if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL,
|
||||
TL_OPTION_UPDATING))
|
||||
YYABORT;
|
||||
}
|
||||
| DROP DATABASE if_exists ident
|
||||
@ -2978,7 +3001,11 @@ table_list:
|
||||
|
||||
table_name:
|
||||
table_ident
|
||||
{ if (!Select->add_table_to_list(YYTHD, $1, NULL, 1)) YYABORT; };
|
||||
{
|
||||
if (!Select->add_table_to_list(YYTHD, $1, NULL, TL_OPTION_UPDATING))
|
||||
YYABORT;
|
||||
}
|
||||
;
|
||||
|
||||
if_exists:
|
||||
/* empty */ { $$= 0; }
|
||||
@ -3213,7 +3240,8 @@ delete:
|
||||
single_multi:
|
||||
FROM table_ident
|
||||
{
|
||||
if (!Select->add_table_to_list(YYTHD, $2, NULL, 1, Lex->lock_option))
|
||||
if (!Select->add_table_to_list(YYTHD, $2, NULL, TL_OPTION_UPDATING,
|
||||
Lex->lock_option))
|
||||
YYABORT;
|
||||
}
|
||||
where_clause opt_order_clause
|
||||
@ -3234,14 +3262,15 @@ table_wild_list:
|
||||
table_wild_one:
|
||||
ident opt_wild opt_table_alias
|
||||
{
|
||||
if (!Select->add_table_to_list(YYTHD, new Table_ident($1), $3, 1,
|
||||
Lex->lock_option))
|
||||
if (!Select->add_table_to_list(YYTHD, new Table_ident($1), $3,
|
||||
TL_OPTION_UPDATING, Lex->lock_option))
|
||||
YYABORT;
|
||||
}
|
||||
| ident '.' ident opt_wild opt_table_alias
|
||||
{
|
||||
if (!Select->add_table_to_list(YYTHD, new Table_ident($1, $3, 0),
|
||||
$5, 1, Lex->lock_option))
|
||||
$5, TL_OPTION_UPDATING,
|
||||
Lex->lock_option))
|
||||
YYABORT;
|
||||
}
|
||||
;
|
||||
@ -3405,7 +3434,7 @@ show_param:
|
||||
| CREATE TABLE_SYM table_ident
|
||||
{
|
||||
Lex->sql_command = SQLCOM_SHOW_CREATE;
|
||||
if(!Select->add_table_to_list(YYTHD, $3, NULL,0))
|
||||
if (!Select->add_table_to_list(YYTHD, $3, NULL,0))
|
||||
YYABORT;
|
||||
}
|
||||
| MASTER_SYM STATUS_SYM
|
||||
@ -3574,14 +3603,14 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING
|
||||
opt_duplicate INTO TABLE_SYM table_ident opt_field_term opt_line_term
|
||||
opt_ignore_lines opt_field_spec
|
||||
{
|
||||
if (!Select->add_table_to_list(YYTHD, $11, NULL, 1))
|
||||
if (!Select->add_table_to_list(YYTHD, $11, NULL, TL_OPTION_UPDATING))
|
||||
YYABORT;
|
||||
}
|
||||
|
|
||||
LOAD TABLE_SYM table_ident FROM MASTER_SYM
|
||||
{
|
||||
Lex->sql_command = SQLCOM_LOAD_MASTER_TABLE;
|
||||
if (!Select->add_table_to_list(YYTHD, $3, NULL, 1))
|
||||
if (!Select->add_table_to_list(YYTHD, $3, NULL, TL_OPTION_UPDATING))
|
||||
YYABORT;
|
||||
|
||||
}
|
||||
|
@ -91,6 +91,7 @@ struct st_table {
|
||||
my_bool copy_blobs; /* copy_blobs when storing */
|
||||
my_bool null_row; /* All columns are null */
|
||||
my_bool maybe_null,outer_join; /* Used with OUTER JOIN */
|
||||
my_bool force_index;
|
||||
my_bool distinct,const_table,no_rows;
|
||||
my_bool key_read, bulk_insert;
|
||||
my_bool crypted;
|
||||
@ -168,6 +169,7 @@ typedef struct st_table_list
|
||||
bool straight; /* optimize with prev table */
|
||||
bool updating; /* for replicate-do/ignore table */
|
||||
bool do_redirect; /* To get the struct in UNION's */
|
||||
bool force_index; /* Prefer index over table scan */
|
||||
} TABLE_LIST;
|
||||
|
||||
typedef struct st_changed_table_list
|
||||
|
Loading…
x
Reference in New Issue
Block a user