Merge bk-internal.mysql.com:/home/bk/mysql-5.0

into neptunus.(none):/home/msvensson/mysql/mysql-5.0


sql/ha_ndbcluster.cc:
  Auto merged
sql/handler.cc:
  Auto merged
sql/share/errmsg.txt:
  Auto merged
This commit is contained in:
unknown 2005-04-07 20:19:25 +02:00
commit 5fa93a136d
57 changed files with 618 additions and 180 deletions

View file

@ -27,6 +27,7 @@ then
fi
CHANGESET=`bk -R prs -r+ -h -d':P:::I:' ChangeSet`
CSETKEY=`bk -R prs -r+ -h -d':KEY:' ChangeSet`
BUG=`bk -R prs -r+ -h -d':C:' ChangeSet | sed -ne 's/^.*[Bb][Uu][Gg] *# *\([0-9][0-9]*\).*$/\1/p'`
WL=`bk -R prs -r+ -h -d':C:' ChangeSet | sed -ne 's/^.*[Ww][Ll] *# *\([0-9][0-9]*\).*$/ WL#\1/p'`
@ -52,6 +53,7 @@ List-ID: <bk.mysql-$VERSION>
From: $FROM
To: $TO
Subject: bk commit - $VERSION tree ($CHANGESET)${BS}${WL}
X-CSetKey: <$CSETKEY>
$BH
EOF
bk changes -v -r+
@ -68,6 +70,7 @@ List-ID: <bk.mysql-$VERSION>
From: $FROM
To: $INTERNALS
Subject: bk commit into $VERSION tree ($CHANGESET)$BS
X-CSetKey: <$CSETKEY>
$BH
Below is the list of changes that have just been committed into a local
$VERSION repository of $USER. When $USER does a push these changes will

View file

@ -566,6 +566,7 @@ static void print_result()
my_bool found_error=0;
res = mysql_use_result(sock);
prev[0] = '\0';
for (i = 0; (row = mysql_fetch_row(res)); i++)
{
@ -595,7 +596,7 @@ static void print_result()
putchar('\n');
}
if (found_error && opt_auto_repair && what_to_do != DO_REPAIR &&
(!opt_fast || strcmp(row[3],"OK")))
!opt_fast)
insert_dynamic(&tables4repair, prev);
mysql_free_result(res);
}

View file

@ -351,6 +351,15 @@ then
if echo $CXX | grep gcc > /dev/null 2>&1
then
GCC_VERSION=`gcc -v 2>&1 | grep version | sed -e 's/[[^0-9. ]]//g; s/^ *//g; s/ .*//g'`
case $SYSTEM_TYPE in
*freebsd*)
# The libsupc++ library on freebsd with gcc 3.4.2 is dependent on
# libstdc++, disable it since other solution works fine
GCC_VERSION="NOSUPCPP_$GCC_VERSION"
;;
*)
;;
esac
echo "Using gcc version '$GCC_VERSION'"
case "$GCC_VERSION" in
3.4.*|3.5.*)

View file

@ -149,7 +149,8 @@ typedef struct my_charset_handler_st
uint (*numchars)(struct charset_info_st *, const char *b, const char *e);
uint (*charpos)(struct charset_info_st *, const char *b, const char *e, uint pos);
uint (*well_formed_len)(struct charset_info_st *,
const char *b,const char *e, uint nchars);
const char *b,const char *e,
uint nchars, int *error);
uint (*lengthsp)(struct charset_info_st *, const char *ptr, uint length);
uint (*numcells)(struct charset_info_st *, const char *b, const char *e);
@ -349,7 +350,8 @@ int my_wildcmp_8bit(CHARSET_INFO *,
uint my_numchars_8bit(CHARSET_INFO *, const char *b, const char *e);
uint my_numcells_8bit(CHARSET_INFO *, const char *b, const char *e);
uint my_charpos_8bit(CHARSET_INFO *, const char *b, const char *e, uint pos);
uint my_well_formed_len_8bit(CHARSET_INFO *, const char *b, const char *e, uint pos);
uint my_well_formed_len_8bit(CHARSET_INFO *, const char *b, const char *e,
uint pos, int *error);
int my_mbcharlen_8bit(CHARSET_INFO *, uint c);
@ -367,7 +369,8 @@ int my_wildcmp_mb(CHARSET_INFO *,
uint my_numchars_mb(CHARSET_INFO *, const char *b, const char *e);
uint my_numcells_mb(CHARSET_INFO *, const char *b, const char *e);
uint my_charpos_mb(CHARSET_INFO *, const char *b, const char *e, uint pos);
uint my_well_formed_len_mb(CHARSET_INFO *, const char *b, const char *e, uint pos);
uint my_well_formed_len_mb(CHARSET_INFO *, const char *b, const char *e,
uint pos, int *error);
uint my_instr_mb(struct charset_info_st *,
const char *b, uint b_length,
const char *s, uint s_length,

View file

@ -14,6 +14,7 @@ Created 2/23/1996 Heikki Tuuri
#include "ut0byte.h"
#include "rem0cmp.h"
#include "trx0trx.h"
/******************************************************************
Allocates memory for a persistent cursor object and initializes the cursor. */
@ -206,7 +207,14 @@ btr_pcur_restore_position(
ut_a(cursor->pos_state == BTR_PCUR_WAS_POSITIONED
|| cursor->pos_state == BTR_PCUR_IS_POSITIONED);
ut_a(cursor->old_stored == BTR_PCUR_OLD_STORED);
if (cursor->old_stored != BTR_PCUR_OLD_STORED) {
ut_print_buf(stderr, (const byte*)cursor, sizeof(btr_pcur_t));
if (cursor->trx_if_known) {
trx_print(stderr, cursor->trx_if_known);
}
ut_a(0);
}
if (cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE
|| cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE) {

View file

@ -3333,6 +3333,9 @@ try_find_index:
"Cannot find an index in the referenced table where the\n"
"referenced columns appear as the first columns, or column types\n"
"in the table and the referenced table do not match for constraint.\n"
"Note that the internal storage type of ENUM and SET changed in\n"
"tables created with >= InnoDB-4.1.12, and such columns in old tables\n"
"cannot be referenced by such columns in new tables.\n"
"See http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n"
"for correct foreign key definition.\n",
start_of_latest_foreign);

View file

@ -478,6 +478,10 @@ struct btr_pcur_struct{
BTR_PCUR_WAS_POSITIONED,
BTR_PCUR_NOT_POSITIONED */
ulint search_mode; /* PAGE_CUR_G, ... */
trx_t* trx_if_known; /* the transaction, if we know it;
otherwise this field is not defined;
can ONLY BE USED in error prints in
fatal assertion failures! */
/*-----------------------------*/
/* NOTE that the following fields may possess dynamically allocated
memory which should be freed if not needed anymore! */

View file

@ -493,6 +493,8 @@ btr_pcur_open(
btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode,
btr_cursor, 0, mtr);
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
cursor->trx_if_known = NULL;
}
/******************************************************************
@ -535,6 +537,8 @@ btr_pcur_open_with_no_init(
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
cursor->trx_if_known = NULL;
}
/*********************************************************************
@ -568,6 +572,8 @@ btr_pcur_open_at_index_side(
pcur->pos_state = BTR_PCUR_IS_POSITIONED;
pcur->old_stored = BTR_PCUR_OLD_NOT_STORED;
pcur->trx_if_known = NULL;
}
/**************************************************************************
@ -592,6 +598,8 @@ btr_pcur_open_at_rnd_pos(
btr_pcur_get_btr_cur(cursor), mtr);
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
cursor->trx_if_known = NULL;
}
/******************************************************************
@ -617,4 +625,6 @@ btr_pcur_close(
cursor->latch_mode = BTR_NO_LATCHES;
cursor->pos_state = BTR_PCUR_NOT_POSITIONED;
cursor->trx_if_known = NULL;
}

View file

@ -68,6 +68,8 @@ log. */
#define OS_FILE_OVERWRITE 53
#define OS_FILE_OPEN_RAW 54
#define OS_FILE_CREATE_PATH 55
#define OS_FILE_OPEN_RETRY 56 /* for os_file_create() on
the first ibdata file */
#define OS_FILE_READ_ONLY 333
#define OS_FILE_READ_WRITE 444

View file

@ -413,8 +413,6 @@ os_file_lock(
"InnoDB: using the same InnoDB data or log files.\n");
}
close(fd);
return(-1);
}
@ -989,6 +987,7 @@ try_again:
} else if (access_type == OS_FILE_READ_WRITE
&& os_file_lock(file, name)) {
*success = FALSE;
close(file);
file = -1;
#endif
} else {
@ -1101,6 +1100,7 @@ os_file_create_simple_no_error_handling(
} else if (access_type == OS_FILE_READ_WRITE
&& os_file_lock(file, name)) {
*success = FALSE;
close(file);
file = -1;
#endif
} else {
@ -1152,7 +1152,8 @@ try_again:
if (create_mode == OS_FILE_OPEN_RAW) {
create_flag = OPEN_EXISTING;
share_mode = FILE_SHARE_WRITE;
} else if (create_mode == OS_FILE_OPEN) {
} else if (create_mode == OS_FILE_OPEN
|| create_mode == OS_FILE_OPEN_RETRY) {
create_flag = OPEN_EXISTING;
} else if (create_mode == OS_FILE_CREATE) {
create_flag = CREATE_NEW;
@ -1243,7 +1244,8 @@ try_again:
try_again:
ut_a(name);
if (create_mode == OS_FILE_OPEN || create_mode == OS_FILE_OPEN_RAW) {
if (create_mode == OS_FILE_OPEN || create_mode == OS_FILE_OPEN_RAW
|| create_mode == OS_FILE_OPEN_RETRY) {
mode_str = "OPEN";
create_flag = O_RDWR;
} else if (create_mode == OS_FILE_CREATE) {
@ -1316,6 +1318,23 @@ try_again:
} else if (create_mode != OS_FILE_OPEN_RAW
&& os_file_lock(file, name)) {
*success = FALSE;
if (create_mode == OS_FILE_OPEN_RETRY) {
int i;
ut_print_timestamp(stderr);
fputs(" InnoDB: Retrying to lock the first data file\n",
stderr);
for (i = 0; i < 100; i++) {
os_thread_sleep(1000000);
if (!os_file_lock(file, name)) {
*success = TRUE;
return(file);
}
}
ut_print_timestamp(stderr);
fputs(" InnoDB: Unable to open the first data file\n",
stderr);
}
close(file);
file = -1;
#endif
} else {

View file

@ -2644,6 +2644,8 @@ row_sel_get_clust_rec_for_mysql(
clust_rec = btr_pcur_get_rec(prebuilt->clust_pcur);
prebuilt->clust_pcur->trx_if_known = trx;
/* Note: only if the search ends up on a non-infimum record is the
low_match value the real match to the search tuple */
@ -3406,6 +3408,8 @@ shortcut_fails_too_big_rec:
btr_pcur_open_with_no_init(index, search_tuple, mode,
BTR_SEARCH_LEAF,
pcur, 0, &mtr);
pcur->trx_if_known = trx;
} else {
if (mode == PAGE_CUR_G) {
btr_pcur_open_at_index_side(TRUE, index,

View file

@ -789,6 +789,11 @@ open_or_create_data_files(
files[i] = os_file_create(
name, OS_FILE_OPEN_RAW, OS_FILE_NORMAL,
OS_DATA_FILE, &ret);
} else if (i == 0) {
files[i] = os_file_create(
name, OS_FILE_OPEN_RETRY,
OS_FILE_NORMAL,
OS_DATA_FILE, &ret);
} else {
files[i] = os_file_create(
name, OS_FILE_OPEN, OS_FILE_NORMAL,

View file

@ -32,21 +32,21 @@ endif
benchdir_root= $(prefix)
testdir = $(benchdir_root)/mysql-test
EXTRA_SCRIPTS = mysql-test-run.sh install_test_db.sh
EXTRA_SCRIPTS = mysql-test-run.sh mysql-test-run.pl install_test_db.sh valgrind.supp
EXTRA_DIST = $(EXTRA_SCRIPTS)
test_SCRIPTS = mysql-test-run install_test_db
test_DATA = std_data/client-key.pem std_data/client-cert.pem std_data/cacert.pem
CLEANFILES = $(test_SCRIPTS) $(test_DATA)
INCLUDES = -I$(srcdir)/../include -I../include -I..
EXTRA_PROGRAMS = mysql_test_run_new
INCLUDES = -I$(srcdir)/../include -I../include -I..
EXTRA_PROGRAMS = mysql_test_run_new
noinst_HEADERS = my_manage.h
mysql_test_run_new_SOURCES= mysql_test_run_new.c my_manage.c my_create_tables.c
dist-hook:
mkdir -p $(distdir)/t $(distdir)/r $(distdir)/include \
$(distdir)/std_data
$(distdir)/std_data $(distdir)/lib
$(INSTALL_DATA) $(srcdir)/t/*.test $(distdir)/t
-$(INSTALL_DATA) $(srcdir)/t/*.disabled $(distdir)/t
$(INSTALL_DATA) $(srcdir)/t/*.opt $(srcdir)/t/*.sh $(srcdir)/t/*.slave-mi $(distdir)/t
@ -57,13 +57,16 @@ dist-hook:
$(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(distdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.pem $(distdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.frm $(distdir)/std_data
$(INSTALL_DATA) $(srcdir)/lib/init_db.sql $(distdir)/lib
$(INSTALL_DATA) $(srcdir)/lib/*.pl $(distdir)/lib
install-data-local:
$(mkinstalldirs) \
$(DESTDIR)$(testdir)/t \
$(DESTDIR)$(testdir)/r \
$(DESTDIR)$(testdir)/include \
$(DESTDIR)$(testdir)/std_data
$(DESTDIR)$(testdir)/std_data \
$(DESTDIR)$(testdir)/lib
$(INSTALL_DATA) $(srcdir)/README $(DESTDIR)$(testdir)
$(INSTALL_DATA) $(srcdir)/t/*.test $(DESTDIR)$(testdir)/t
-$(INSTALL_DATA) $(srcdir)/t/*.disabled $(DESTDIR)$(testdir)/t
@ -79,6 +82,8 @@ install-data-local:
$(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.pem $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.frm $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/lib/init_db.sql $(DESTDIR)$(testdir)/lib
$(INSTALL_DATA) $(srcdir)/lib/*.pl $(DESTDIR)$(testdir)/lib
std_data/%.pem:
@CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data

View file

@ -635,7 +635,6 @@ sub command_line_setup () {
{
mtr_error("Can't use --extern with --embedded-server");
}
$opt_result_ext= ".es";
}
# FIXME don't understand what this is

View file

@ -416,7 +416,7 @@ while test $# -gt 0; do
fi
# >=2.1.2 requires the --tool option, some versions write to stdout, some to stderr
valgrind --help 2>&1 | grep "\-\-tool" > /dev/null && VALGRIND="$VALGRIND --tool=memcheck"
VALGRIND="$VALGRIND --alignment=8 --leak-check=yes --num-callers=16"
VALGRIND="$VALGRIND --alignment=8 --leak-check=yes --num-callers=16 --suppressions=$CWD/valgrind.supp"
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-safemalloc --skip-bdb"
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-safemalloc --skip-bdb"
SLEEP_TIME_AFTER_RESTART=10

View file

@ -30,13 +30,13 @@ table7, table8, table9, table10, table11, table12, table13,
table14, table15, table16, table17, table18, table19, table20,
table21, table22, table23, table24, table25, table26, table27,
table28;
ERROR 42S02: Unknown table 'table1,table2,table3,table4,table5,table6,table7,table8,table9,table10,table11,table12,table13,table14,table15,table16,table17,table18,table19,table20,table21,table22,table23,table'
ERROR 42S02: Unknown table 'table1,table2,table3,table4,table5,table6,table7,table8,table9,table10,table11,table12,table13,table'
drop table table1, table2, table3, table4, table5, table6,
table7, table8, table9, table10, table11, table12, table13,
table14, table15, table16, table17, table18, table19, table20,
table21, table22, table23, table24, table25, table26, table27,
table28, table29, table30;
ERROR 42S02: Unknown table 'table1,table2,table3,table4,table5,table6,table7,table8,table9,table10,table11,table12,table13,table14,table15,table16,table17,table18,table19,table20,table21,table22,table23,table'
ERROR 42S02: Unknown table 'table1,table2,table3,table4,table5,table6,table7,table8,table9,table10,table11,table12,table13,table'
use test;
drop database mysqltest;
flush tables with read lock;

View file

@ -667,14 +667,7 @@ drop table t1;
set storage_engine=MyISAM;
create table t1 (a bigint unsigned auto_increment primary key, b int,
key (b, a)) engine=heap;
insert t1 (b) values (1);
insert t1 (b) values (1);
insert t1 (b) values (1);
insert t1 (b) values (1);
insert t1 (b) values (1);
insert t1 (b) values (1);
insert t1 (b) values (1);
insert t1 (b) values (1);
insert t1 (b) values (1),(1),(1),(1),(1),(1),(1),(1);
select * from t1;
a b
1 1
@ -688,14 +681,7 @@ a b
drop table t1;
create table t1 (a int not null, b int not null auto_increment,
primary key(a, b), key(b)) engine=heap;
insert t1 (a) values (1);
insert t1 (a) values (1);
insert t1 (a) values (1);
insert t1 (a) values (1);
insert t1 (a) values (1);
insert t1 (a) values (1);
insert t1 (a) values (1);
insert t1 (a) values (1);
insert t1 (a) values (1),(1),(1),(1),(1),(1),(1),(1);
select * from t1;
a b
1 1
@ -707,3 +693,6 @@ a b
1 7
1 8
drop table t1;
create table t1 (a int not null, b int not null auto_increment,
primary key(a, b)) engine=heap;
ERROR 42000: Incorrect table definition; there can be only one auto column and it must be defined as a key

View file

@ -6,7 +6,7 @@ select ((@id := kill_id) - kill_id) from t1;
0
kill @id;
select 1;
ERROR HY000: MySQL server has gone away
Got one of the listed errors
select ((@id := kill_id) - kill_id) from t1;
((@id := kill_id) - kill_id)
0

View file

@ -89,4 +89,5 @@ a b
2 row 2
3 row 3
0
drop database rewrite;
drop table t1;

View file

@ -503,4 +503,14 @@ ERROR 0A000: LOCK is not allowed in stored procedures
create procedure bug6600()
unlock table t1|
ERROR 0A000: UNLOCK is not allowed in stored procedures
drop procedure if exists bug9566|
create procedure bug9566()
begin
select * from t1;
end|
lock table t1 read|
call bug9566()|
ERROR HY000: Table 'proc' was not locked with LOCK TABLES
unlock tables|
drop procedure bug9566|
drop table t1|

View file

@ -179,3 +179,6 @@ set @v1=null, @v2=1, @v3=1.1, @v4=now();
select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4);
coercibility(@v1) coercibility(@v2) coercibility(@v3) coercibility(@v4)
2 2 2 2
set session @honk=99;
set one_shot @honk=99;
ERROR HY000: The 'SET ONE_SHOT' syntax is reserved for purposes internal to the MySQL server

View file

@ -413,25 +413,16 @@ eval set storage_engine=$default;
create table t1 (a bigint unsigned auto_increment primary key, b int,
key (b, a)) engine=heap;
insert t1 (b) values (1);
insert t1 (b) values (1);
insert t1 (b) values (1);
insert t1 (b) values (1);
insert t1 (b) values (1);
insert t1 (b) values (1);
insert t1 (b) values (1);
insert t1 (b) values (1);
select * from t1;
insert t1 (b) values (1),(1),(1),(1),(1),(1),(1),(1);
select * from t1;
drop table t1;
create table t1 (a int not null, b int not null auto_increment,
primary key(a, b), key(b)) engine=heap;
insert t1 (a) values (1);
insert t1 (a) values (1);
insert t1 (a) values (1);
insert t1 (a) values (1);
insert t1 (a) values (1);
insert t1 (a) values (1);
insert t1 (a) values (1);
insert t1 (a) values (1);
select * from t1;
insert t1 (a) values (1),(1),(1),(1),(1),(1),(1),(1);
select * from t1;
drop table t1;
--error 1075
create table t1 (a int not null, b int not null auto_increment,
primary key(a, b)) engine=heap;

View file

@ -27,7 +27,7 @@ connection con1;
--disable_reconnect
# this statement should fail
--error 2006
--error 2006,2013
select 1;
--enable_reconnect
# this should work, and we should have a new connection_id()

View file

@ -73,5 +73,8 @@ connection slave;
# The empty line last comes from the end line field in the file
select * from rewrite.t1;
drop database rewrite;
connection master;
drop table t1;

View file

@ -696,6 +696,29 @@ create procedure bug6600()
create procedure bug6600()
unlock table t1|
#
# BUG#9566: explicit LOCK TABLE and store procedures result in illegal state
#
# We should not think that mysql.proc table does not exist if we are unable
# to open it under LOCK TABLE or in prelocked mode. Probably this test
# should be removed when Monty will allow access to mysql.proc without
# locking it.
#
--disable_warnings
drop procedure if exists bug9566|
--enable_warnings
create procedure bug9566()
begin
select * from t1;
end|
lock table t1 read|
# This should fail because we forgot to lock mysql.proc table explicitly
--error 1100
call bug9566()|
unlock tables|
# This should succeed
drop procedure bug9566|
#
# BUG#NNNN: New bug synopsis

View file

@ -112,3 +112,10 @@ select FIELD( @var,'1it','Hit') as my_column;
select @v, coercibility(@v);
set @v1=null, @v2=1, @v3=1.1, @v4=now();
select coercibility(@v1),coercibility(@v2),coercibility(@v3),coercibility(@v4);
#
# Bug #9286 SESSION/GLOBAL should be disallowed for user variables
#
set session @honk=99;
--error 1382
set one_shot @honk=99;

94
mysql-test/valgrind.supp Normal file
View file

@ -0,0 +1,94 @@
#
# Suppress some common (not fatal) errors in system libraries found by valgrind
#
#
# Pthread doesn't free all thread specific memory before program exists
#
{
pthread allocate_tls memory loss
Memcheck:Leak
fun:calloc
fun:_dl_allocate_tls
fun:allocate_stack
fun:pthread_create@@GLIBC_2.1
}
{
pthread allocate_dtv memory loss
Memcheck:Leak
fun:calloc
fun:allocate_dtv
fun:_dl_allocate_tls_storage
fun:__GI__dl_allocate_tls
fun:pthread_create
}
{
pthread memalign memory loss
Memcheck:Leak
fun:memalign
fun:_dl_allocate_tls_storage
fun:__GI__dl_allocate_tls
fun:pthread_create
}
{
pthread errno
Memcheck:Leak
fun:calloc
fun:_dlerror_run
fun:dlsym
fun:__errno_location
}
#
# Warnings in libz becasue it works with aligned memory(?)
#
{
libz tr_flush_block
Memcheck:Cond
fun:_tr_flush_block
fun:deflate_slow
fun:deflate
fun:do_flush
fun:gzclose
}
{
libz tr_flush_block2
Memcheck:Cond
fun:_tr_flush_block
fun:deflate_slow
fun:deflate
fun:compress2
}
{
libz longest_match
Memcheck:Cond
fun:longest_match
fun:deflate_slow
fun:deflate
fun:do_flush
}
{
libz longest_match2
Memcheck:Cond
fun:longest_match
fun:deflate_slow
fun:deflate
fun:compress2
}
{
libz deflate
Memcheck:Cond
obj:/usr/lib/libz.so.*
obj:/usr/lib/libz.so.*
fun:deflate
fun:compress2
}

View file

@ -477,13 +477,13 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
if ((stat_info.st_mode & S_IWOTH) &&
(stat_info.st_mode & S_IFMT) == S_IFREG)
{
fprintf(stderr, "warning: World-writable config file %s is ignored\n",
fprintf(stderr, "Warning: World-writable config file '%s' is ignored\n",
name);
return 0;
}
}
#endif
if (!(fp= my_fopen(fn_format(name, name, "", "", 4), O_RDONLY, MYF(0))))
if (!(fp= my_fopen(name, O_RDONLY, MYF(0))))
return 0; /* Ignore wrong files */
while (fgets(buff, sizeof(buff) - 1, fp))

View file

@ -65,7 +65,7 @@ int my_sync(File fd, myf my_flags)
int er= errno;
if (!(my_errno= er))
my_errno= -1; /* Unknown error */
if (my_flags & MY_IGNORE_BADFD &&
if ((my_flags & MY_IGNORE_BADFD) &&
(er == EBADF || er == EINVAL || er == EROFS))
res= 0;
else if (my_flags & MY_WME)

View file

@ -658,6 +658,7 @@ private:
// Release all cursor operations in connection
void releaseOps(NdbOperation*);
void releaseScanOperations(NdbIndexScanOperation*);
void releaseExecutedScanOperation(NdbIndexScanOperation*);
// Set the transaction identity of the transaction
void setTransactionId(Uint64 aTransactionId);

View file

@ -813,6 +813,7 @@ Dbtup::updateFixedSizeTHManyWordNotNULL(Uint32* inBuffer,
ndbrequire(i < regTabPtr->noOfCharsets);
// not const in MySQL
CHARSET_INFO* cs = regTabPtr->charsetArray[i];
int not_used;
const char* ssrc = (const char*)&inBuffer[tInBufIndex + 1];
Uint32 lb, len;
if (! NdbSqlUtil::get_var_length(typeId, ssrc, bytes, lb, len)) {
@ -822,7 +823,7 @@ Dbtup::updateFixedSizeTHManyWordNotNULL(Uint32* inBuffer,
}
// fast fix bug#7340
if (typeId != NDB_TYPE_TEXT &&
(*cs->cset->well_formed_len)(cs, ssrc + lb, ssrc + lb + len, ZNIL) != len) {
(*cs->cset->well_formed_len)(cs, ssrc + lb, ssrc + lb + len, ZNIL, &not_used) != len) {
ljam();
terrorCode = ZINVALID_CHAR_FORMAT;
return false;

View file

@ -948,6 +948,37 @@ NdbTransaction::releaseScanOperations(NdbIndexScanOperation* cursorOp)
}
}//NdbTransaction::releaseScanOperations()
/*****************************************************************************
void releaseExecutedScanOperation();
Remark: Release scan op when hupp'ed trans closed (save memory)
******************************************************************************/
void
NdbConnection::releaseExecutedScanOperation(NdbIndexScanOperation* cursorOp)
{
DBUG_ENTER("NdbConnection::releaseExecutedScanOperation");
DBUG_PRINT("enter", ("this=0x%x op=0x%x", (UintPtr)this, (UintPtr)cursorOp))
// here is one reason to make op lists doubly linked
if (m_firstExecutedScanOp == cursorOp) {
m_firstExecutedScanOp = (NdbIndexScanOperation*)cursorOp->theNext;
cursorOp->release();
theNdb->releaseScanOperation(cursorOp);
} else if (m_firstExecutedScanOp != NULL) {
NdbIndexScanOperation* tOp = m_firstExecutedScanOp;
while (tOp->theNext != NULL) {
if (tOp->theNext == cursorOp) {
tOp->theNext = cursorOp->theNext;
cursorOp->release();
theNdb->releaseScanOperation(cursorOp);
break;
}
tOp = (NdbIndexScanOperation*)tOp->theNext;
}
}
DBUG_VOID_RETURN;
}//NdbConnection::releaseExecutedScanOperation()
/*****************************************************************************
NdbOperation* getNdbOperation(const char* aTableName);

View file

@ -208,6 +208,7 @@ rm -f $MYSQL_SHARE/Makefile* $MYSQL_SHARE/*/*.OLD
for i in mysql-test/mysql-test-run mysql-test/install_test_db \
mysql-test/mysql-test-run.pl mysql-test/README \
mysql-test/valgrind.supp \
netware/mysql_test_run.nlm netware/install_test_db.ncf
do
if [ -f $i ]

View file

@ -5777,7 +5777,7 @@ void Field_datetime::sql_type(String &res) const
int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
{
int error= 0;
int error= 0, well_formed_error;
uint32 not_used;
char buff[STRING_BUFFER_USUAL_SIZE];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
@ -5802,9 +5802,10 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
as well as don't copy a malformed data.
*/
copy_length= field_charset->cset->well_formed_len(field_charset,
from,from+length,
field_length/
field_charset->mbmaxlen);
from,from+length,
field_length/
field_charset->mbmaxlen,
&well_formed_error);
memcpy(ptr,from,copy_length);
if (copy_length < field_length) // Append spaces if shorter
field_charset->cset->fill(field_charset,ptr+copy_length,
@ -6152,7 +6153,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
uint32 not_used, copy_length;
char buff[STRING_BUFFER_USUAL_SIZE];
String tmpstr(buff,sizeof(buff), &my_charset_bin);
int error_code= 0;
int error_code= 0, well_formed_error;
enum MYSQL_ERROR::enum_warning_level level= MYSQL_ERROR::WARN_LEVEL_WARN;
/* Convert character set if necessary */
@ -6172,7 +6173,8 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
copy_length= field_charset->cset->well_formed_len(field_charset,
from,from+length,
field_length/
field_charset->mbmaxlen);
field_charset->mbmaxlen,
&well_formed_error);
memcpy(ptr + length_bytes, from, copy_length);
if (length_bytes == 1)
*ptr= (uchar) copy_length;
@ -6746,7 +6748,7 @@ void Field_blob::put_length(char *pos, uint32 length)
int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
{
int error= 0;
int error= 0, well_formed_error;
if (!length)
{
bzero(ptr,Field_blob::pack_length());
@ -6778,9 +6780,10 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
the 'min()' call below.
*/
copy_length= field_charset->cset->well_formed_len(field_charset,
from,from +
min(length, copy_length),
copy_length);
from,from +
min(length, copy_length),
copy_length,
&well_formed_error);
if (copy_length < length)
error= 1;
Field_blob::store_length(copy_length);

View file

@ -548,12 +548,12 @@ error:
static int parse_url(FEDERATED_SHARE *share, TABLE *table,
uint table_create_flag)
{
uint error_num= (table_create_flag ? ER_CANT_CREATE_TABLE :
ER_CONNECT_TO_MASTER);
DBUG_ENTER("ha_federated::parse_url");
share->port= 0;
uint error_num= (table_create_flag ? ER_CANT_CREATE_TABLE :
ER_CONNECT_TO_MASTER);
share->socket= 0;
share->scheme= my_strdup(table->s->comment, MYF(0));
if ((share->username= strstr(share->scheme, "://")))

View file

@ -548,6 +548,7 @@ int ha_heap::create(const char *name, TABLE *table_arg,
hp_create_info.auto_increment= (create_info->auto_increment_value ?
create_info->auto_increment_value - 1 : 0);
hp_create_info.max_table_size=current_thd->variables.max_heap_table_size;
hp_create_info.with_auto_increment= found_real_auto_increment;
max_rows = (ha_rows) (hp_create_info.max_table_size / mem_per_row);
error= heap_create(fn_format(buff,name,"","",4+2),
keys, keydef, share->reclength,

View file

@ -5822,6 +5822,7 @@ extern "C" pthread_handler_decl(ndb_util_thread_func,
{
thd->cleanup();
delete thd;
delete ndb;
DBUG_RETURN(NULL);
}
@ -5940,6 +5941,7 @@ extern "C" pthread_handler_decl(ndb_util_thread_func,
thd->cleanup();
delete thd;
delete ndb;
DBUG_PRINT("exit", ("ndb_util_thread"));
my_thread_end();
pthread_exit(0);

View file

@ -506,10 +506,16 @@ void ha_close_connection(THD* thd)
"beginning of transaction" and "beginning of statement").
Only storage engines registered for the transaction/statement
will know when to commit/rollback it.
NOTE
trans_register_ha is idempotent - storage engine may register many
times per transaction.
*/
void trans_register_ha(THD *thd, bool all, handlerton *ht_arg)
{
THD_TRANS *trans;
handlerton **ht;
DBUG_ENTER("trans_register_ha");
DBUG_PRINT("enter",("%s", all ? "all" : "stmt"));
@ -521,15 +527,12 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht_arg)
else
trans= &thd->transaction.stmt;
handlerton **ht=trans->ht;
while (*ht)
{
for (ht=trans->ht; *ht; ht++)
if (*ht == ht_arg)
DBUG_VOID_RETURN; /* already registered, return */
ht++;
}
trans->ht[trans->nht++]=ht_arg;
DBUG_ASSERT(*ht == ht_arg);
trans->no_2pc|=(ht_arg->prepare==0);
if (thd->transaction.xid.is_null())
thd->transaction.xid.set(thd->query_id);

View file

@ -1510,6 +1510,7 @@ void end_thread(THD *thd, bool put_in_cache)
thd=thread_cache.get();
thd->real_id=pthread_self();
(void) thd->store_globals();
thd->thr_create_time= time(NULL);
threads.append(thd);
pthread_mutex_unlock(&LOCK_thread_count);
DBUG_VOID_RETURN;
@ -5170,7 +5171,7 @@ log and this option does nothing anymore.",
(gptr*) &dflt_key_cache_var.param_buff_size,
(gptr*) 0,
0, (GET_ULL | GET_ASK_ADDR),
REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, UINT_MAX32, MALLOC_OVERHEAD,
REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, ~(ulong) 0, MALLOC_OVERHEAD,
IO_SIZE, 0},
{"key_cache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD,
"This characterizes the number of hits a hot block has to be untouched until it is considered aged enough to be downgraded to a warm block. This specifies the percentage ratio of that number of hits to the total number of blocks in key cache",

View file

@ -131,7 +131,7 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
/* Condition pushdown to storage engine */
if (thd->variables.engine_condition_pushdown &&
select && select->cond &&
select->cond->used_tables() & table->map &&
(select->cond->used_tables() & table->map) &&
!table->file->pushed_cond)
table->file->cond_push(select->cond);

View file

@ -1214,30 +1214,30 @@ ER_TABLE_EXISTS_ERROR 42S01
swe "Tabellen '%-.64s' finns redan"
ukr "ôÁÂÌÉÃÑ '%-.64s' ×ÖÅ ¦ÓÎÕ¤"
ER_BAD_TABLE_ERROR 42S02
cze "Nezn-Bámá tabulka '%-.180s'"
dan "Ukendt tabel '%-.180s'"
nla "Onbekende tabel '%-.180s'"
eng "Unknown table '%-.180s'"
jps "table '%-.180s' ‚Í‚ ‚è‚Ü‚¹‚ñ.",
est "Tundmatu tabel '%-.180s'"
fre "Table '%-.180s' inconnue"
ger "Unbekannte Tabelle '%-.180s'"
greek "Áãíùóôïò ðßíáêáò '%-.180s'"
hun "Ervenytelen tabla: '%-.180s'"
ita "Tabella '%-.180s' sconosciuta"
jpn "table '%-.180s' ¤Ï¤¢¤ê¤Þ¤»¤ó."
kor "Å×À̺í '%-.180s'´Â ¾Ë¼ö ¾øÀ½"
nor "Ukjent tabell '%-.180s'"
norwegian-ny "Ukjent tabell '%-.180s'"
pol "Nieznana tabela '%-.180s'"
por "Tabela '%-.180s' desconhecida"
rum "Tabela '%-.180s' este invalida"
rus "îÅÉÚ×ÅÓÔÎÁÑ ÔÁÂÌÉÃÁ '%-.180s'"
serbian "Nepoznata tabela '%-.180s'"
slo "Neznáma tabuµka '%-.180s'"
spa "Tabla '%-.180s' desconocida"
swe "Okänd tabell '%-.180s'"
ukr "îÅצÄÏÍÁ ÔÁÂÌÉÃÑ '%-.180s'"
cze "Nezn-Bámá tabulka '%-.100s'"
dan "Ukendt tabel '%-.100s'"
nla "Onbekende tabel '%-.100s'"
eng "Unknown table '%-.100s'"
jps "table '%-.100s' ‚Í‚ ‚è‚Ü‚¹‚ñ.",
est "Tundmatu tabel '%-.100s'"
fre "Table '%-.100s' inconnue"
ger "Unbekannte Tabelle '%-.100s'"
greek "Áãíùóôïò ðßíáêáò '%-.100s'"
hun "Ervenytelen tabla: '%-.100s'"
ita "Tabella '%-.100s' sconosciuta"
jpn "table '%-.100s' ¤Ï¤¢¤ê¤Þ¤»¤ó."
kor "Å×À̺í '%-.100s'´Â ¾Ë¼ö ¾øÀ½"
nor "Ukjent tabell '%-.100s'"
norwegian-ny "Ukjent tabell '%-.100s'"
pol "Nieznana tabela '%-.100s'"
por "Tabela '%-.100s' desconhecida"
rum "Tabela '%-.100s' este invalida"
rus "îÅÉÚ×ÅÓÔÎÁÑ ÔÁÂÌÉÃÁ '%-.100s'"
serbian "Nepoznata tabela '%-.100s'"
slo "Neznáma tabuµka '%-.100s'"
spa "Tabla '%-.100s' desconocida"
swe "Okänd tabell '%-.100s'"
ukr "îÅצÄÏÍÁ ÔÁÂÌÉÃÑ '%-.100s'"
ER_NON_UNIQ_ERROR 23000
cze "Sloupec '%-.64s' v %s nen-Bí zcela jasný"
dan "Felt: '%-.64s' i tabel %s er ikke entydigt"

View file

@ -70,9 +70,8 @@ db_find_routine_aux(THD *thd, int type, sp_name *name,
type, name->m_name.length, name->m_name.str));
/*
Speed up things if mysql.proc doesn't exists
mysql_proc_table_exists is set when on creates a stored procedure
or on flush privileges
Speed up things if mysql.proc doesn't exists. mysql_proc_table_exists
is set when we create or read stored procedure or on flush privileges.
*/
if (!mysql_proc_table_exists && ltype == TL_READ)
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
@ -98,7 +97,13 @@ db_find_routine_aux(THD *thd, int type, sp_name *name,
if (! (table= open_ltable(thd, &tables, ltype)))
{
*tablep= NULL;
mysql_proc_table_exists= 0;
/*
Under explicit LOCK TABLES or in prelocked mode we should not
say that mysql.proc table does not exist if we are unable to
open it since this condition may be transient.
*/
if (!(thd->locked_tables || thd->prelocked_mode))
mysql_proc_table_exists= 0;
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
}
*opened= TRUE;

View file

@ -343,8 +343,9 @@ void THD::change_user(void)
void THD::cleanup(void)
{
DBUG_ENTER("THD::cleanup");
/* TODO uncomment the line below when binlog will be able to prepare */
// if (transaction.xa_state != XA_PREPARED)
#ifdef ENABLE_WHEN_BINLOG_WILL_BE_ABLE_TO_PREPARE
if (transaction.xa_state != XA_PREPARED)
#endif
ha_rollback(this);
if (locked_tables)
{

View file

@ -1103,7 +1103,8 @@ pthread_handler_decl(handle_one_connection,arg)
thd->proc_info=0;
thd->set_time();
thd->init_for_queries();
while (!net->error && net->vio != 0 && !(thd->killed == THD::KILL_CONNECTION))
while (!net->error && net->vio != 0 &&
!(thd->killed == THD::KILL_CONNECTION))
{
net->no_send_error= 0;
if (do_command(thd))

View file

@ -111,6 +111,7 @@ static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
static bool open_tmp_table(TABLE *table);
static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
ulong options);
static Next_select_func setup_end_select_func(JOIN *join);
static int do_select(JOIN *join,List<Item> *fields,TABLE *tmp_table,
Procedure *proc);
static int sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records);
@ -1638,6 +1639,8 @@ JOIN::exec()
{
thd->proc_info="Sending data";
DBUG_PRINT("info", ("%s", thd->proc_info));
result->send_fields(*curr_fields_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
error= do_select(curr_join, curr_fields_list, NULL, procedure);
thd->limit_found_rows= curr_join->send_records;
thd->examined_row_count= curr_join->examined_rows;
@ -1776,12 +1779,8 @@ Cursor::open(JOIN *join_arg)
thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
/* Prepare JOIN for reading rows. */
Next_select_func end_select= join->sort_and_group || join->procedure &&
join->procedure->flags & PROC_GROUP ?
end_send_group : end_send;
join->join_tab[join->tables-1].next_select= end_select;
join->tmp_table= 0;
join->join_tab[join->tables-1].next_select= setup_end_select_func(join);
join->send_records= 0;
join->fetch_limit= join->unit->offset_limit_cnt;
@ -1802,6 +1801,11 @@ Cursor::open(JOIN *join_arg)
*/
DBUG_ASSERT(join_tab->table->null_row == 0);
/*
There is always at least one record in the table, as otherwise we
wouldn't have opened the cursor. Therefore a failure is the only
reason read_first_record can return not 0.
*/
DBUG_RETURN(join_tab->read_first_record(join_tab));
}
@ -2231,6 +2235,8 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
if (s->dependent & table->map)
s->dependent |= table->reginfo.join_tab->dependent;
}
if (s->dependent)
s->table->maybe_null= 1;
}
/* Catch illegal cross references for outer joins */
for (i= 0, s= stat ; i < table_count ; i++, s++)
@ -2480,6 +2486,11 @@ typedef struct key_field_t { // Used when finding key fields
uint level;
uint optimize;
bool eq_func;
/*
If true, the condition this struct represents will not be satisfied
when val IS NULL.
*/
bool null_rejecting;
} KEY_FIELD;
/* Values in optimize */
@ -2496,6 +2507,12 @@ typedef struct key_field_t { // Used when finding key fields
that are internally transformed to something like:
SELECT * FROM t1 WHERE t1.key=outer_ref_field or t1.key IS NULL
KEY_FIELD::null_rejecting is processed as follows:
result has null_rejecting=true if it is set for both ORed references.
for example:
(t2.key = t1.field OR t2.key = t1.field) -> null_rejecting=true
(t2.key = t1.field OR t2.key <=> t1.field) -> null_rejecting=false
*/
static KEY_FIELD *
@ -2529,6 +2546,8 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
KEY_OPTIMIZE_EXISTS) |
((old->optimize | new_fields->optimize) &
KEY_OPTIMIZE_REF_OR_NULL));
old->null_rejecting= old->null_rejecting &&
new_fields->null_rejecting;
}
}
else if (old->eq_func && new_fields->eq_func &&
@ -2540,6 +2559,8 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
KEY_OPTIMIZE_EXISTS) |
((old->optimize | new_fields->optimize) &
KEY_OPTIMIZE_REF_OR_NULL));
old->null_rejecting= old->null_rejecting &&
new_fields->null_rejecting;
}
else if (old->eq_func && new_fields->eq_func &&
(old->val->is_null() || new_fields->val->is_null()))
@ -2550,6 +2571,8 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
/* Remember the NOT NULL value */
if (old->val->is_null())
old->val= new_fields->val;
/* The referred expression can be NULL: */
old->null_rejecting= false;
}
else
{
@ -2605,7 +2628,7 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
*/
static void
add_key_field(KEY_FIELD **key_fields, uint and_level, COND *cond,
add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
Field *field, bool eq_func, Item **value, uint num_values,
table_map usable_tables)
{
@ -2707,10 +2730,17 @@ add_key_field(KEY_FIELD **key_fields, uint and_level, COND *cond,
(*key_fields)->val= *value;
(*key_fields)->level= and_level;
(*key_fields)->optimize= exists_optimize;
/*
If the condition has form "tbl.keypart = othertbl.field" and
othertbl.field can be NULL, there will be no matches if othertbl.field
has NULL value.
*/
(*key_fields)->null_rejecting= (cond->functype() == Item_func::EQ_FUNC) &&
((*value)->type() == Item::FIELD_ITEM) &&
((Item_field*)*value)->field->maybe_null();
(*key_fields)++;
}
/*
Add possible keys to array of possible keys originated from a simple predicate
@ -2735,7 +2765,7 @@ add_key_field(KEY_FIELD **key_fields, uint and_level, COND *cond,
static void
add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
COND *cond, Item_field *field_item,
Item_func *cond, Item_field *field_item,
bool eq_func, Item **val,
uint num_values, table_map usable_tables)
{
@ -2763,7 +2793,7 @@ add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
}
static void
add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
add_key_fields(KEY_FIELD **key_fields,uint *and_level,
COND *cond, table_map usable_tables)
{
if (cond->type() == Item_func::COND_ITEM)
@ -2775,20 +2805,20 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
{
Item *item;
while ((item=li++))
add_key_fields(stat,key_fields,and_level,item,usable_tables);
add_key_fields(key_fields,and_level,item,usable_tables);
for (; org_key_fields != *key_fields ; org_key_fields++)
org_key_fields->level= *and_level;
}
else
{
(*and_level)++;
add_key_fields(stat,key_fields,and_level,li++,usable_tables);
add_key_fields(key_fields,and_level,li++,usable_tables);
Item *item;
while ((item=li++))
{
KEY_FIELD *start_key_fields= *key_fields;
(*and_level)++;
add_key_fields(stat,key_fields,and_level,item,usable_tables);
add_key_fields(key_fields,and_level,item,usable_tables);
*key_fields=merge_key_fields(org_key_fields,start_key_fields,
*key_fields,++(*and_level));
}
@ -2876,7 +2906,7 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
*/
while ((item= it++))
{
add_key_field(key_fields, *and_level, cond, item->field,
add_key_field(key_fields, *and_level, cond_func, item->field,
TRUE, &const_item, 1, usable_tables);
}
}
@ -2896,7 +2926,7 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level,
{
if (!field->eq(item->field))
{
add_key_field(key_fields, *and_level, cond, field,
add_key_field(key_fields, *and_level, cond_func, field,
TRUE, (Item **) &item, 1, usable_tables);
}
}
@ -2948,6 +2978,7 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
keyuse.keypart_map= (key_part_map) 1 << part;
keyuse.used_tables=key_field->val->used_tables();
keyuse.optimize= key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL;
keyuse.null_rejecting= key_field->null_rejecting;
VOID(insert_dynamic(keyuse_array,(gptr) &keyuse));
}
}
@ -3041,8 +3072,22 @@ sort_keyuse(KEYUSE *a,KEYUSE *b)
/*
Update keyuse array with all possible keys we can use to fetch rows
join_tab is a array in tablenr_order
stat is a reference array in 'prefered' order.
SYNOPSIS
update_ref_and_keys()
thd
keyuse OUT Put here ordered array of KEYUSE structures
join_tab Array in tablenr_order
tables Number of tables in join
cond WHERE condition (note that the function analyzes
join_tab[i]->on_expr too)
normal_tables tables not inner w.r.t some outer join (ones for which
we can make ref access based the WHERE clause)
select_lex current SELECT
RETURN
0 - OK
1 - Out of memory.
*/
static bool
@ -3067,7 +3112,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
return TRUE;
if (cond)
{
add_key_fields(join_tab,&end,&and_level,cond,normal_tables);
add_key_fields(&end,&and_level,cond,normal_tables);
for (; field != end ; field++)
{
add_key_part(keyuse,field);
@ -3090,7 +3135,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
*/
if (*join_tab[i].on_expr_ref)
{
add_key_fields(join_tab,&end,&and_level,*join_tab[i].on_expr_ref,
add_key_fields(&end,&and_level,*join_tab[i].on_expr_ref,
join_tab[i].table->map);
}
else
@ -3101,7 +3146,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
{
NESTED_JOIN *nested_join= embedding->nested_join;
if (nested_join->join_list.head() == tab)
add_key_fields(join_tab, &end, &and_level, embedding->on_expr,
add_key_fields(&end, &and_level, embedding->on_expr,
nested_join->used_tables);
}
}
@ -4875,6 +4920,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
}
j->ref.key_buff2=j->ref.key_buff+ALIGN_SIZE(length);
j->ref.key_err=1;
j->ref.null_rejecting= 0;
keyuse=org_keyuse;
store_key **ref_key= j->ref.key_copy;
@ -4899,6 +4945,8 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
uint maybe_null= test(keyinfo->key_part[i].null_bit);
j->ref.items[i]=keyuse->val; // Save for cond removal
if (keyuse->null_rejecting)
j->ref.null_rejecting |= 1 << i;
keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables;
if (!keyuse->used_tables &&
!(join->select_options & SELECT_DESCRIBE))
@ -5057,6 +5105,91 @@ make_simple_join(JOIN *join,TABLE *tmp_table)
}
inline void add_cond_and_fix(Item **e1, Item *e2)
{
if (*e1)
{
Item *res;
if ((res= new Item_cond_and(*e1, e2)))
{
*e1= res;
res->quick_fix_field();
}
}
else
*e1= e2;
}
/*
Add to join_tab->select_cond[i] "table.field IS NOT NULL" conditions we've
inferred from ref/eq_ref access performed.
SYNOPSIS
add_not_null_conds()
join Join to process
NOTES
This function is a part of "Early NULL-values filtering for ref access"
optimization.
Example of this optimization:
For query SELECT * FROM t1,t2 WHERE t2.key=t1.field
and plan " any-access(t1), ref(t2.key=t1.field) "
add "t1.field IS NOT NULL" to t1's table condition.
Description of the optimization:
We look through equalities choosen to perform ref/eq_ref access,
pick equalities that have form "tbl.part_of_key = othertbl.field"
(where othertbl is a non-const table and othertbl.field may be NULL)
and add them to conditions on correspoding tables (othertbl in this
example).
This optimization doesn't affect the choices that ref, range, or join
optimizer make. This was intentional because this was added after 4.1
was GA.
Implementation overview
1. update_ref_and_keys() accumulates info about null-rejecting
predicates in in KEY_FIELD::null_rejecting
1.1 add_key_part saves these to KEYUSE.
2. create_ref_for_key copies them to TABLE_REF.
3. add_not_null_conds adds "x IS NOT NULL" to join_tab->select_cond of
appropiate JOIN_TAB members.
*/
static void add_not_null_conds(JOIN *join)
{
DBUG_ENTER("add_not_null_conds");
for (uint i=join->const_tables ; i < join->tables ; i++)
{
JOIN_TAB *tab=join->join_tab+i;
if ((tab->type == JT_REF || tab->type == JT_REF_OR_NULL) &&
!tab->table->maybe_null)
{
for (uint keypart= 0; keypart < tab->ref.key_parts; keypart++)
{
if (tab->ref.null_rejecting & (1 << keypart))
{
Item *item= tab->ref.items[keypart];
DBUG_ASSERT(item->type() == Item::FIELD_ITEM);
Item_field *not_null_item= (Item_field*)item;
JOIN_TAB *referred_tab= not_null_item->field->table->reginfo.join_tab;
Item_func_isnotnull *notnull;
if (!(notnull= new Item_func_isnotnull(not_null_item)))
DBUG_VOID_RETURN;
notnull->quick_fix_field();
DBUG_EXECUTE("where",print_where(notnull,
referred_tab->table->alias););
add_cond_and_fix(&referred_tab->select_cond, notnull);
}
}
}
}
DBUG_VOID_RETURN;
}
/*
Build a predicate guarded by match variables for embedding outer joins
@ -5194,6 +5327,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
DBUG_ENTER("make_join_select");
if (select)
{
add_not_null_conds(join);
table_map used_tables;
if (cond) /* Because of QUICK_GROUP_MIN_MAX_SELECT */
{ /* there may be a select without a cond. */
@ -5327,6 +5461,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
tab->select_cond= sel->cond= NULL;
sel->head=tab->table;
DBUG_EXECUTE("where",print_where(tmp,tab->table->alias););
if (tab->quick)
{
/* Use quick key read if it's a constant and it's not used
@ -8733,36 +8868,24 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
}
/****************************************************************************
Make a join of all tables and write it on socket or to table
Return: 0 if ok
1 if error is sent
-1 if error should be sent
****************************************************************************/
/*
SYNOPSIS
setup_end_select_func()
join join to setup the function for.
static int
do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
DESCRIPTION
Rows produced by a join sweep may end up in a temporary table or be sent
to a client. Setup the function of the nested loop join algorithm which
handles final fully constructed and matched records.
RETURN
end_select function to use. This function can't fail.
*/
static Next_select_func setup_end_select_func(JOIN *join)
{
int error= 0;
JOIN_TAB *join_tab;
TABLE *table= join->tmp_table;
Next_select_func end_select;
DBUG_ENTER("do_select");
join->procedure=procedure;
/*
Tell the client how many fields there are in a row
*/
if (!table)
join->result->send_fields(*fields,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
else
{
VOID(table->file->extra(HA_EXTRA_WRITE_CACHE));
empty_record(table);
}
join->tmp_table= table; /* Save for easy recursion */
join->fields= fields;
/* Set up select_end */
if (table)
{
@ -8772,8 +8895,6 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
{
DBUG_PRINT("info",("Using end_update"));
end_select=end_update;
if (!table->file->inited)
table->file->ha_index_init(0);
}
else
{
@ -8807,7 +8928,38 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
else
end_select= end_send;
}
join->join_tab[join->tables-1].next_select=end_select;
return end_select;
}
/****************************************************************************
Make a join of all tables and write it on socket or to table
Return: 0 if ok
1 if error is sent
-1 if error should be sent
****************************************************************************/
static int
do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
{
int error= 0;
JOIN_TAB *join_tab;
DBUG_ENTER("do_select");
join->procedure=procedure;
join->tmp_table= table; /* Save for easy recursion */
join->fields= fields;
if (table)
{
VOID(table->file->extra(HA_EXTRA_WRITE_CACHE));
empty_record(table);
if (table->group && join->tmp_table_param.sum_func_count &&
table->s->keys && !table->file->inited)
table->file->ha_index_init(0);
}
/* Set up select_end */
join->join_tab[join->tables-1].next_select= setup_end_select_func(join);
join_tab=join->join_tab+join->const_tables;
join->send_records=0;
@ -8819,6 +8971,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
*/
if (!join->conds || join->conds->val_int())
{
Next_select_func end_select= join->join_tab[join->tables-1].next_select;
if (!(error=(*end_select)(join,join_tab,0)) || error == -3)
error=(*end_select)(join,join_tab,1);
}

View file

@ -31,6 +31,11 @@ typedef struct keyuse_t {
uint key, keypart, optimize;
key_part_map keypart_map;
ha_rows ref_table_rows;
/*
If true, the comparison this value was created from will not be
satisfied if val has NULL 'value'.
*/
bool null_rejecting;
} KEYUSE;
class store_key;
@ -45,6 +50,11 @@ typedef struct st_table_ref
byte *key_buff2; // key_buff+key_length
store_key **key_copy; //
Item **items; // val()'s for each keypart
/*
(null_rejecting & (1<<i)) means the condition is '=' and no matching
rows will be produced if items[i] IS NULL (see add_not_null_conds())
*/
key_part_map null_rejecting;
table_map depend_map; // Table depends on these tables.
byte *null_ref_key; // null byte position in the key_buf.
// used for REF_OR_NULL optimization.

View file

@ -2312,7 +2312,7 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables,
}
}
#else
end=strmov(end,"");
*end= 0;
#endif
table->field[17]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs);

View file

@ -7020,9 +7020,10 @@ IDENT_sys:
if (thd->charset_is_system_charset)
{
CHARSET_INFO *cs= system_charset_info;
int dummy_error;
uint wlen= cs->cset->well_formed_len(cs, $1.str,
$1.str+$1.length,
$1.length);
$1.length, &dummy_error);
if (wlen < $1.length)
{
my_error(ER_INVALID_CHARACTER_STRING, MYF(0),

View file

@ -6294,10 +6294,13 @@ my_mb_wc_big5(CHARSET_INFO *cs __attribute__((unused)),
*/
static
uint my_well_formed_len_big5(CHARSET_INFO *cs __attribute__((unused)),
const char *b, const char *e, uint pos)
const char *b, const char *e,
uint pos, int *error)
{
const char *b0= b;
const char *emb= e - 1; /* Last possible end of an MB character */
*error= 0;
while (pos && b < e)
{
if ((uchar) b[0] < 128)
@ -6313,6 +6316,7 @@ uint my_well_formed_len_big5(CHARSET_INFO *cs __attribute__((unused)),
else
{
/* Wrong byte sequence */
*error= 1;
break;
}
}

View file

@ -5413,9 +5413,10 @@ uint my_numcells_cp932(CHARSET_INFO *cs __attribute__((unused)),
*/
static
uint my_well_formed_len_cp932(CHARSET_INFO *cs __attribute__((unused)),
const char *b, const char *e, uint pos)
const char *b, const char *e, uint pos, int *error)
{
const char *b0= b;
*error= 0;
while (pos && b < e)
{
/*
@ -5441,6 +5442,7 @@ uint my_well_formed_len_cp932(CHARSET_INFO *cs __attribute__((unused)),
else
{
/* Wrong byte sequence */
*error= 1;
break;
}
}

View file

@ -8380,17 +8380,18 @@ my_jisx0212_uni_onechar(int code){
/*
EUC-JP encoding subcomponents:
[x00-x7F] # ASCII/JIS-Roman (one-byte/character)
[x8E][xA0-xDF] # half-width katakana (two bytes/char)
[x8F][xA1-xFE][xA1-xFE] # JIS X 0212-1990 (three bytes/char)
[x00-x7F] # ASCII/JIS-Roman (one-byte/character)
[x8E][xA0-xDF] # half-width katakana (two bytes/char)
[x8F][xA1-xFE][xA1-xFE] # JIS X 0212-1990 (three bytes/char)
[xA1-xFE][xA1-xFE] # JIS X 0208:1997 (two bytes/char)
*/
static
uint my_well_formed_len_eucjpms(CHARSET_INFO *cs __attribute__((unused)),
const char *beg, const char *end, uint pos)
const char *beg, const char *end, uint pos, int *error)
{
const uchar *b= (uchar *) beg;
*error=0;
for ( ; pos && b < (uchar*) end; pos--, b++)
{
@ -8408,6 +8409,7 @@ uint my_well_formed_len_eucjpms(CHARSET_INFO *cs __attribute__((unused)),
{
if (*b >= 0xA0 && *b <= 0xDF)
continue;
*error=1;
return chbeg - beg; /* invalid sequence */
}
@ -8415,12 +8417,16 @@ uint my_well_formed_len_eucjpms(CHARSET_INFO *cs __attribute__((unused)),
{
ch= *b++;
if (b >= (uchar*) end)
{
*error= 1;
return chbeg - beg; /* unexpected EOL */
}
}
if (ch >= 0xA1 && ch <= 0xFE &&
*b >= 0xA1 && *b <= 0xFE) /* [xA1-xFE][xA1-xFE] */
continue;
*error=1;
return chbeg - beg; /* invalid sequence */
}
return b - (uchar *) beg;

View file

@ -264,18 +264,21 @@ uint my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)),
}
uint my_well_formed_len_mb(CHARSET_INFO *cs,
const char *b, const char *e, uint pos)
uint my_well_formed_len_mb(CHARSET_INFO *cs, const char *b, const char *e,
uint pos, int *error)
{
const char *b_start= b;
*error= 0;
while (pos)
{
my_wc_t wc;
int mblen;
if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <= 0)
{
*error= b < e ? 1 : 0;
break;
}
b+= mblen;
pos--;
}

View file

@ -1122,11 +1122,11 @@ uint my_charpos_8bit(CHARSET_INFO *cs __attribute__((unused)),
uint my_well_formed_len_8bit(CHARSET_INFO *cs __attribute__((unused)),
const char *start,
const char *end,
uint nchars)
const char *start, const char *end,
uint nchars, int *error)
{
uint nbytes= (uint) (end-start);
*error= 0;
return min(nbytes, nchars);
}

View file

@ -4586,9 +4586,11 @@ uint my_numcells_sjis(CHARSET_INFO *cs __attribute__((unused)),
*/
static
uint my_well_formed_len_sjis(CHARSET_INFO *cs __attribute__((unused)),
const char *b, const char *e, uint pos)
const char *b, const char *e,
uint pos, int *error)
{
const char *b0= b;
*error= 0;
while (pos && b < e)
{
if ((uchar) b[0] < 128)
@ -4609,6 +4611,7 @@ uint my_well_formed_len_sjis(CHARSET_INFO *cs __attribute__((unused)),
else
{
/* Wrong byte sequence */
*error= 1;
break;
}
}

View file

@ -1273,11 +1273,11 @@ uint my_charpos_ucs2(CHARSET_INFO *cs __attribute__((unused)),
static
uint my_well_formed_len_ucs2(CHARSET_INFO *cs __attribute__((unused)),
const char *b,
const char *e,
uint nchars)
const char *b, const char *e,
uint nchars, int *error)
{
uint nbytes= (e-b) & ~ (uint)1;
*error= 0;
nchars*= 2;
return min(nbytes, nchars);
}

View file

@ -8253,11 +8253,12 @@ my_jisx0212_uni_onechar(int code){
static
uint my_well_formed_len_ujis(CHARSET_INFO *cs __attribute__((unused)),
const char *beg, const char *end, uint pos)
const char *beg, const char *end,
uint pos, int *error)
{
const uchar *b= (uchar *) beg;
for ( ; pos && b < (uchar*) end; pos--, b++)
for ( *error= 0 ; pos && b < (uchar*) end; pos--, b++)
{
char *chbeg;
uint ch= *b;
@ -8267,12 +8268,16 @@ uint my_well_formed_len_ujis(CHARSET_INFO *cs __attribute__((unused)),
chbeg= (char *) b++;
if (b >= (uchar *) end) /* need more bytes */
{
*error= 1;
return chbeg - beg; /* unexpected EOL */
}
if (ch == 0x8E) /* [x8E][xA0-xDF] */
{
if (*b >= 0xA0 && *b <= 0xDF)
continue;
*error= 1;
return chbeg - beg; /* invalid sequence */
}
@ -8280,12 +8285,16 @@ uint my_well_formed_len_ujis(CHARSET_INFO *cs __attribute__((unused)),
{
ch= *b++;
if (b >= (uchar*) end)
{
*error= 1;
return chbeg - beg; /* unexpected EOL */
}
}
if (ch >= 0xA1 && ch <= 0xFE &&
*b >= 0xA1 && *b <= 0xFE) /* [xA1-xFE][xA1-xFE] */
continue;
*error= 1;
return chbeg - beg; /* invalid sequence */
}
return b - (uchar *) beg;

View file

@ -806,7 +806,7 @@ internal_str2dec(const char *from, decimal_t *to, char **end, my_bool fixed)
if (s < end_of_string && *s=='.')
{
endp= s+1;
while (s < end_of_string && my_isdigit(&my_charset_latin1, *endp))
while (endp < end_of_string && my_isdigit(&my_charset_latin1, *endp))
endp++;
frac= endp - s - 1;
}