Commit 74f478f9 authored by Sinisa@sinisa.nasamreza.org's avatar Sinisa@sinisa.nasamreza.org

Merge sinisa@work.mysql.com:/home/bk/mysql-4.0

into sinisa.nasamreza.org:/mnt/work/mysql-4.0
parents fe5e05cd ff4ef4c4
...@@ -522,3 +522,4 @@ vio/test-ssl ...@@ -522,3 +522,4 @@ vio/test-ssl
vio/test-sslclient vio/test-sslclient
vio/test-sslserver vio/test-sslserver
vio/viotest-ssl vio/viotest-ssl
extra/mysql_waitpid
...@@ -21,10 +21,10 @@ AUTOMAKE_OPTIONS = foreign ...@@ -21,10 +21,10 @@ AUTOMAKE_OPTIONS = foreign
# These are built from source in the Docs directory # These are built from source in the Docs directory
EXTRA_DIST = INSTALL-SOURCE README \ EXTRA_DIST = INSTALL-SOURCE README \
COPYING COPYING.LIB COPYING COPYING.LIB
SUBDIRS = include @docs_dirs@ @readline_dir@ \ SUBDIRS = . include @docs_dirs@ @readline_dir@ \
@thread_dirs@ pstack @sql_client_dirs@ \ @thread_dirs@ pstack @sql_client_dirs@ \
@sql_server_dirs@ @libmysqld_dirs@ scripts man \ @sql_server_dirs@ scripts man tests \
tests BUILD os2 \ BUILD os2 libmysql_r @libmysqld_dirs@ \
@bench_dirs@ support-files @fs_dirs@ @tools_dirs@ @bench_dirs@ support-files @fs_dirs@ @tools_dirs@
# Relink after clean # Relink after clean
......
...@@ -279,7 +279,7 @@ fi ...@@ -279,7 +279,7 @@ fi
dnl Sparc/gcc: SunOS, Solaris dnl Sparc/gcc: SunOS, Solaris
dnl The sparc/gcc code doesn't always work, specifically, I've seen assembler dnl The sparc/gcc code doesn't always work, specifically, I've seen assembler
dnl failures from the stbar instruction on SunOS 4.1.4/sun4c and gcc 2.7.2.2. dnl failures from the stbar instruction on SunOS 4.1.4/sun4c and gcc 2.7.2.2.
if test "$db_cv_mutex" = DOESNT_WORK; then if test "$db_cv_mutex" = no; then
AC_TRY_RUN([main(){ AC_TRY_RUN([main(){
#if defined(__sparc__) #if defined(__sparc__)
#if defined(__GNUC__) #if defined(__GNUC__)
......
...@@ -327,7 +327,7 @@ typedef unsigned char tsl_t; ...@@ -327,7 +327,7 @@ typedef unsigned char tsl_t;
*/ */
#define MUTEX_SET(tsl) ({ \ #define MUTEX_SET(tsl) ({ \
register tsl_t *__l = (tsl); \ register tsl_t *__l = (tsl); \
int __r; \ unsigned char __r; \
asm volatile("tas %1; \n \ asm volatile("tas %1; \n \
seq %0" \ seq %0" \
: "=dm" (__r), "=m" (*__l) \ : "=dm" (__r), "=m" (*__l) \
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
**********************************************************************/ **********************************************************************/
#define MTEST_VERSION "1.26" #define MTEST_VERSION "1.27"
#include <my_global.h> #include <my_global.h>
#include <mysql_embed.h> #include <mysql_embed.h>
...@@ -677,7 +677,7 @@ int open_file(const char* name) ...@@ -677,7 +677,7 @@ int open_file(const char* name)
if (*cur_file && cur_file == file_stack_end) if (*cur_file && cur_file == file_stack_end)
die("Source directives are nesting too deep"); die("Source directives are nesting too deep");
if (!(*(cur_file+1) = my_fopen(buff, O_RDONLY, MYF(MY_WME)))) if (!(*(cur_file+1) = my_fopen(buff, O_RDONLY | O_BINARY, MYF(MY_WME))))
die(NullS); die(NullS);
cur_file++; cur_file++;
*++lineno=1; *++lineno=1;
...@@ -1912,7 +1912,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), ...@@ -1912,7 +1912,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
argument= buff; argument= buff;
} }
fn_format(buff, argument, "", "", 4); fn_format(buff, argument, "", "", 4);
if (!(*++cur_file = my_fopen(buff, O_RDONLY, MYF(MY_WME)))) if (!(*++cur_file = my_fopen(buff, O_RDONLY | O_BINARY, MYF(MY_WME))))
die("Could not open %s: errno = %d", argument, errno); die("Could not open %s: errno = %d", argument, errno);
break; break;
} }
......
...@@ -508,6 +508,14 @@ btr_search_check_guess( ...@@ -508,6 +508,14 @@ btr_search_check_guess(
/*===================*/ /*===================*/
/* out: TRUE if success */ /* out: TRUE if success */
btr_cur_t* cursor, /* in: guessed cursor position */ btr_cur_t* cursor, /* in: guessed cursor position */
ibool can_only_compare_to_cursor_rec,
/* in: if we do not have a latch on the page
of cursor, but only a latch on
btr_search_latch, then ONLY the columns
of the record UNDER the cursor are
protected, not the next or previous record
in the chain: we cannot look at the next or
previous record to check our guess! */
dtuple_t* tuple, /* in: data tuple */ dtuple_t* tuple, /* in: data tuple */
ulint mode, /* in: PAGE_CUR_L, PAGE_CUR_LE, PAGE_CUR_G, ulint mode, /* in: PAGE_CUR_L, PAGE_CUR_LE, PAGE_CUR_G,
or PAGE_CUR_GE */ or PAGE_CUR_GE */
...@@ -566,6 +574,13 @@ btr_search_check_guess( ...@@ -566,6 +574,13 @@ btr_search_check_guess(
} }
} }
if (can_only_compare_to_cursor_rec) {
/* Since we could not determine if our guess is right just by
looking at the record under the cursor, return FALSE */
return(FALSE);
}
match = 0; match = 0;
bytes = 0; bytes = 0;
...@@ -670,6 +685,7 @@ btr_search_guess_on_hash( ...@@ -670,6 +685,7 @@ btr_search_guess_on_hash(
ulint fold; ulint fold;
ulint tuple_n_fields; ulint tuple_n_fields;
dulint tree_id; dulint tree_id;
ibool can_only_compare_to_cursor_rec = TRUE;
#ifdef notdefined #ifdef notdefined
btr_cur_t cursor2; btr_cur_t cursor2;
btr_pcur_t pcur; btr_pcur_t pcur;
...@@ -744,6 +760,8 @@ btr_search_guess_on_hash( ...@@ -744,6 +760,8 @@ btr_search_guess_on_hash(
goto failure; goto failure;
} }
can_only_compare_to_cursor_rec = FALSE;
buf_page_dbg_add_level(page, SYNC_TREE_NODE_FROM_HASH); buf_page_dbg_add_level(page, SYNC_TREE_NODE_FROM_HASH);
} }
...@@ -775,7 +793,15 @@ btr_search_guess_on_hash( ...@@ -775,7 +793,15 @@ btr_search_guess_on_hash(
fold); fold);
*/ */
} else { } else {
success = btr_search_check_guess(cursor, tuple, mode, mtr); /* If we only have the latch on btr_search_latch, not on the
page, it only protects the columns of the record the cursor
is positioned on. We cannot look at the next of the previous
record to determine if our guess for the cursor position is
right. */
success = btr_search_check_guess(cursor,
can_only_compare_to_cursor_rec,
tuple, mode, mtr);
} }
if (!success) { if (!success) {
......
...@@ -234,10 +234,16 @@ struct btr_search_sys_struct{ ...@@ -234,10 +234,16 @@ struct btr_search_sys_struct{
extern btr_search_sys_t* btr_search_sys; extern btr_search_sys_t* btr_search_sys;
/* The latch protecting the adaptive search system: this latch protects the /* The latch protecting the adaptive search system: this latch protects the
(1) positions of records on those pages where a hash index has been built. (1) hash index;
NOTE: It does not protect values of non-ordering fields within a record from (2) columns of a record to which we have a pointer in the hash index;
being updated in-place! We can use fact (1) to perform unique searches to
indexes. */ but does NOT protect:
(3) next record offset field in a record;
(4) next or previous records on the same page.
Bear in mind (3) and (4) when using the hash index.
*/
extern rw_lock_t* btr_search_latch_temp; extern rw_lock_t* btr_search_latch_temp;
......
...@@ -253,7 +253,8 @@ page_cur_search_with_match( ...@@ -253,7 +253,8 @@ page_cur_search_with_match(
up_matched_bytes = cur_matched_bytes; up_matched_bytes = cur_matched_bytes;
} }
} else if ((mode == PAGE_CUR_G) || (mode == PAGE_CUR_LE)) { } else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE
|| mode == PAGE_CUR_LE_OR_EXTENDS) {
low = mid; low = mid;
low_matched_fields = cur_matched_fields; low_matched_fields = cur_matched_fields;
low_matched_bytes = cur_matched_bytes; low_matched_bytes = cur_matched_bytes;
...@@ -308,7 +309,8 @@ page_cur_search_with_match( ...@@ -308,7 +309,8 @@ page_cur_search_with_match(
up_matched_fields = cur_matched_fields; up_matched_fields = cur_matched_fields;
up_matched_bytes = cur_matched_bytes; up_matched_bytes = cur_matched_bytes;
} }
} else if ((mode == PAGE_CUR_G) || (mode == PAGE_CUR_LE)) { } else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE
|| mode == PAGE_CUR_LE_OR_EXTENDS) {
low_rec = mid_rec; low_rec = mid_rec;
low_matched_fields = cur_matched_fields; low_matched_fields = cur_matched_fields;
low_matched_bytes = cur_matched_bytes; low_matched_bytes = cur_matched_bytes;
......
...@@ -84,6 +84,8 @@ clean-local: ...@@ -84,6 +84,8 @@ clean-local:
rm -f `echo $(mystringsobjects) | sed "s;\.lo;.c;g"` \ rm -f `echo $(mystringsobjects) | sed "s;\.lo;.c;g"` \
`echo $(dbugobjects) | sed "s;\.lo;.c;g"` \ `echo $(dbugobjects) | sed "s;\.lo;.c;g"` \
`echo $(mysysobjects) | sed "s;\.lo;.c;g"` \ `echo $(mysysobjects) | sed "s;\.lo;.c;g"` \
`echo $(vio_objects) | sed "s;\.lo;.c;g"` \
$(CHARSET_SRCS) $(CHARSET_OBJS) \
$(mystringsextra) $(mystringsgen) $(mysysheaders) \ $(mystringsextra) $(mystringsgen) $(mysysheaders) \
ctype_extra_sources.c net.c ../linked_client_sources ctype_extra_sources.c net.c ../linked_client_sources
......
...@@ -3009,6 +3009,16 @@ hardcode_action=$hardcode_action ...@@ -3009,6 +3009,16 @@ hardcode_action=$hardcode_action
# This must work even if \$libdir does not exist. # This must work even if \$libdir does not exist.
hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec
# Check if debuild is being run by the current shell. If it is then,
# the DEB_BUILD_ARCH variable should be of non-zero length, indicating
# that we are in the middle of a Debian package build (assuming the
# user isn't doing anything strange with environment variables).
if test -n "`dpkg-architecture -qDEB_BUILD_ARCH`" && ps | grep debuild | grep -v grep > /dev/null; then
# Debian policy mandates that rpaths should not be encoded into a binary
# so it is overridden.
hardcode_libdir_flag_spec=" -D_DEBIAN_PATCHED_LIBTOOL_ "
fi
# Whether we need a single -rpath flag with a separated argument. # Whether we need a single -rpath flag with a separated argument.
hardcode_libdir_separator=$hardcode_libdir_separator hardcode_libdir_separator=$hardcode_libdir_separator
......
.TH ISAMCHK 1 "19 December 2000" .TH isamchk 1 "19 December 2000" "MySQL 3.23" "MySQL database"
.SH NAME .SH NAME
.BR isamchk .BR isamchk
\- Description, check and repair of ISAM tables. \- Description, check and repair of ISAM tables.
......
.TH ISAMLOG 1 "20 December 2000" .TH isamlog 1 "19 December 2000" "MySQL 3.23" "MySQL database"
.SH NAME .SH NAME
isamlog - Write info about whats in a nisam log file. isamlog - Write info about whats in a nisam log file.
.SH USAGE .SH USAGE
......
.TH MYSQL 1 "13 June 1997" .TH mysql 1 "19 December 2000" "MySQL 3.23" "MySQL database"
.SH NAME .SH NAME
mysql \- text-based client for mysqld, a SQL-based relational database daemon mysql \- text-based client for mysqld, a SQL-based relational database daemon
.SH SYNOPSIS .SH SYNOPSIS
......
.TH ZAP 1 "20 December 2000" .TH zap 1 "19 December 2000" "MySQL 3.23" "MySQL database"
.SH NAME .SH NAME
zap - a perl script used to kill processes zap - a perl script used to kill processes
.SH USAGE .SH USAGE
......
.TH MYSQLACCESS 1 "19 December 2000" .TH mysqlaccess 1 "19 December 2000" "MySQL 3.23" "MySQL database"
.SH NAME .SH NAME
.BR mysqlaccess .BR mysqlaccess
\- Create new users to mysql. \- Create new users to mysql.
......
.TH MYSQLADMIN 1 "18 December 2000" .TH mysqladmin 1 "19 December 2000" "MySQL 3.23" "MySQL database"
.SH NAME .SH NAME
mysqladmin [OPTIONS] command command.... \- A utility for performing administrative operations mysqladmin [OPTIONS] command command.... \- A utility for performing administrative operations
.SH OPTION SYNOPSIS .SH OPTION SYNOPSIS
......
.TH MYSQLD 1 "19 December 2000" .TH mysqld 1 "19 December 2000" "MySQL 3.23" "MySQL database"
.SH NAME .SH NAME
.BR mysqld .BR mysqld
\- Starts the MySQL server demon \- Starts the MySQL server demon
......
.TH MYSQLD_MULTI 1 "20 December 2000" .TH mysqld_multi 1 "19 December 2000" "MySQL 3.23" "MySQL database"
.SH NAME .SH NAME
mysqld_multi - is meant for managing several mysqld processes running in different UNIX sockets and TCP/IP ports. mysqld_multi - is meant for managing several mysqld processes running in different UNIX sockets and TCP/IP ports.
.SH USAGE .SH USAGE
......
.TH SAFE_MYSQLD 1 "19 December 2000" "safe_mysqld (mysql)" mysql.com .TH safe_mysqld 1 "19 December 2000" "MySQL 3.23" "MySQL database"
.SH NAME .SH NAME
mysqld_safe \- start the mysqld daemon on Unix. mysqld_safe \- start the mysqld daemon on Unix.
.SH SYNOPSIS .SH SYNOPSIS
......
.TH MYSQLDUMP 1 "19 December 2000" .TH mysqldump 1 "19 December 2000" "MySQL 3.23" "MySQL database"
.SH NAME .SH NAME
mysqldump \- text-based client for dumping or backing up mysql databases , tables and or data. mysqldump \- text-based client for dumping or backing up mysql databases , tables and or data.
...@@ -123,7 +123,7 @@ Connect to host. ...@@ -123,7 +123,7 @@ Connect to host.
Lock all tables for read. Lock all tables for read.
.TP .TP
.BR \-n | \-\-no\-create\-db .BR \-n | \-\-no\-create\-db
'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;' \&'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;'
will not be put in the output. The above line will will not be put in the output. The above line will
be added otherwise, if be added otherwise, if
.BR \-\-databases .BR \-\-databases
...@@ -270,4 +270,4 @@ Manual page by L. (Kill-9) Pedersen ...@@ -270,4 +270,4 @@ Manual page by L. (Kill-9) Pedersen
(kill-9@kill-9.dk), Mercurmedia Data Model Architect / (kill-9@kill-9.dk), Mercurmedia Data Model Architect /
system developer (http://www.mercurmedia.com) system developer (http://www.mercurmedia.com)
.\" end of man page .\" end of man page
\ No newline at end of file
.TH MYSQLSHOW 1 "19 December 2000" .TH mysqlshow 1 "19 December 2000" "MySQL 3.23" "MySQL database"
.SH NAME .SH NAME
.BR mysqlshow .BR mysqlshow
\- Shows the structure of a mysql database (databases,tables and columns) \- Shows the structure of a mysql database (databases,tables and columns)
......
.TH PERROR 1 "19 December 2000" .TH perror 1 "19 December 2000" "MySQL 3.23" "MySQL database"
.SH NAME .SH NAME
.BR perror .BR perror
can be used to display a description for a system error code, or an MyISAM/ISAM table handler error code. The error messages are mostly system dependent. can be used to display a description for a system error code, or an MyISAM/ISAM table handler error code. The error messages are mostly system dependent.
......
.TH REPLACE 1 "20 December 2000" .TH replace 1 "19 December 2000" "MySQL 3.23" "MySQL database"
.SH NAME .SH NAME
.TP .TP
replace - A utility program that is used by msql2mysql, but that has more general applicability as well. replace changes strings in place in files or on the standard input. Uses a finite state machine to match longer strings first. Can be used to swap strings. replace - A utility program that is used by msql2mysql, but that has more general applicability as well. replace changes strings in place in files or on the standard input. Uses a finite state machine to match longer strings first. Can be used to swap strings.
......
...@@ -228,7 +228,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -228,7 +228,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
if (uniques) if (uniques)
{ {
max_key_block_length= myisam_block_size; max_key_block_length= myisam_block_size;
max_key_length= MI_UNIQUE_HASH_LENGTH; max_key_length= MI_UNIQUE_HASH_LENGTH + pointer;
} }
for (i=0, keydef=keydefs ; i < keys ; i++ , keydef++) for (i=0, keydef=keydefs ; i < keys ; i++ , keydef++)
......
...@@ -24,7 +24,7 @@ my_bool mi_check_unique(MI_INFO *info, MI_UNIQUEDEF *def, byte *record, ...@@ -24,7 +24,7 @@ my_bool mi_check_unique(MI_INFO *info, MI_UNIQUEDEF *def, byte *record,
{ {
my_off_t lastpos=info->lastpos; my_off_t lastpos=info->lastpos;
MI_KEYDEF *key= &info->s->keyinfo[def->key]; MI_KEYDEF *key= &info->s->keyinfo[def->key];
uchar *key_buff=info->lastkey+info->s->base.max_key_length; uchar *key_buff=info->lastkey2;
DBUG_ENTER("mi_check_unique"); DBUG_ENTER("mi_check_unique");
mi_unique_store(record+key->seg->start, unique_hash); mi_unique_store(record+key->seg->start, unique_hash);
...@@ -80,7 +80,16 @@ ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const byte *record) ...@@ -80,7 +80,16 @@ ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const byte *record)
if (keyseg->null_bit) if (keyseg->null_bit)
{ {
if (record[keyseg->null_pos] & keyseg->null_bit) if (record[keyseg->null_pos] & keyseg->null_bit)
{
/*
Change crc in a way different from an empty string or 0.
(This is an optimisation; The code will work even if this isn't
done)
*/
crc=((crc << 8) + 511+
(crc >> (8*sizeof(ha_checksum)-8)));
continue; continue;
}
} }
pos= record+keyseg->start; pos= record+keyseg->start;
if (keyseg->flag & HA_VAR_LENGTH) if (keyseg->flag & HA_VAR_LENGTH)
......
drop table if exists t1; drop table if exists t1;
create table t1 (id int not null, str char(10), unique(str)); create table t1 (id int not null, str char(10), unique(str));
explain select * from t1;
table type possible_keys key key_len ref rows Extra
t1 system NULL NULL NULL NULL 0 const row not found
insert into t1 values (1, null),(2, null),(3, "foo"),(4, "bar"); insert into t1 values (1, null),(2, null),(3, "foo"),(4, "bar");
select * from t1 where str is null; select * from t1 where str is null;
id str id str
......
...@@ -467,3 +467,17 @@ NOT NULL); ...@@ -467,3 +467,17 @@ NOT NULL);
max(value) max(value)
4 4
drop table t1,t2,t3; drop table t1,t2,t3;
create table t1 (a blob null);
insert into t1 values (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(""),(""),(""),("b");
select a,count(*) from t1 group by a;
a count(*)
NULL 9
3
b 1
set option sql_big_tables=1;
select a,count(*) from t1 group by a;
a count(*)
NULL 9
3
b 1
drop table t1;
...@@ -14,8 +14,7 @@ insert into t1 values (101); ...@@ -14,8 +14,7 @@ insert into t1 values (101);
insert into t1 values (105); insert into t1 values (105);
insert into t1 values (106); insert into t1 values (106);
insert into t1 values (107); insert into t1 values (107);
insert into t2 values (107); insert into t2 values (107),(75),(1000);
insert into t2 values (75);
select t1.id, t2.id from t1, t2 where t2.id = t1.id; select t1.id, t2.id from t1, t2 where t2.id = t1.id;
id id id id
107 107 107 107
...@@ -28,6 +27,16 @@ select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t2.id; ...@@ -28,6 +27,16 @@ select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t2.id;
id count(t2.id) id count(t2.id)
75 1 75 1
107 1 107 1
select t1.id,t2.id from t2 left join t1 on t1.id>=74 and t1.id<=0 where t2.id=75 and t1.id is null;
id id
NULL 75
explain select t1.id,t2.id from t2 left join t1 on t1.id>=74 and t1.id<=0 where t2.id=75 and t1.id is null;
table type possible_keys key key_len ref rows Extra
t1 const PRIMARY NULL NULL NULL 1 Impossible ON condition
t2 ALL NULL NULL NULL NULL 3 Using where
explain select t1.id, t2.id from t1, t2 where t2.id = t1.id and t1.id <0 and t1.id > 0;
Comment
Impossible WHERE noticed after reading const tables
drop table t1,t2; drop table t1,t2;
CREATE TABLE t1 ( CREATE TABLE t1 (
id int(11) NOT NULL auto_increment, id int(11) NOT NULL auto_increment,
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
drop table if exists t1; drop table if exists t1;
create table t1 (id int not null, str char(10), unique(str)); create table t1 (id int not null, str char(10), unique(str));
explain select * from t1;
insert into t1 values (1, null),(2, null),(3, "foo"),(4, "bar"); insert into t1 values (1, null),(2, null),(3, "foo"),(4, "bar");
select * from t1 where str is null; select * from t1 where str is null;
select * from t1 where str="foo"; select * from t1 where str="foo";
...@@ -12,8 +13,10 @@ explain select * from t1 ignore key (str) where str="foo"; ...@@ -12,8 +13,10 @@ explain select * from t1 ignore key (str) where str="foo";
explain select * from t1 use key (str,str) where str="foo"; explain select * from t1 use key (str,str) where str="foo";
#The following should give errors #The following should give errors
!$1072 explain select * from t1 use key (str,str,foo) where str="foo"; --error 1072
!$1072 explain select * from t1 ignore key (str,str,foo) where str="foo"; explain select * from t1 use key (str,str,foo) where str="foo";
--error 1072
explain select * from t1 ignore key (str,str,foo) where str="foo";
drop table t1; drop table t1;
explain select 1; explain select 1;
...@@ -354,3 +354,14 @@ m.c1id = c1.id AND c1.active = 'Yes' LEFT JOIN t3 AS c2 ON m.c2id = ...@@ -354,3 +354,14 @@ m.c1id = c1.id AND c1.active = 'Yes' LEFT JOIN t3 AS c2 ON m.c2id =
c2.id AND c2.active = 'Yes' WHERE m.pid=1 AND (c1.id IS NOT NULL OR c2.id IS c2.id AND c2.active = 'Yes' WHERE m.pid=1 AND (c1.id IS NOT NULL OR c2.id IS
NOT NULL); NOT NULL);
drop table t1,t2,t3; drop table t1,t2,t3;
#
# Test bug in GROUP BY on BLOB that is NULL or empty
#
create table t1 (a blob null);
insert into t1 values (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(""),(""),(""),("b");
select a,count(*) from t1 group by a;
set option sql_big_tables=1;
select a,count(*) from t1 group by a;
drop table t1;
...@@ -19,13 +19,18 @@ insert into t1 values (105); ...@@ -19,13 +19,18 @@ insert into t1 values (105);
insert into t1 values (106); insert into t1 values (106);
insert into t1 values (107); insert into t1 values (107);
insert into t2 values (107); insert into t2 values (107),(75),(1000);
insert into t2 values (75);
select t1.id, t2.id from t1, t2 where t2.id = t1.id; select t1.id, t2.id from t1, t2 where t2.id = t1.id;
select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t1.id; select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t1.id;
select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t2.id; select t1.id, count(t2.id) from t1,t2 where t2.id = t1.id group by t2.id;
#
# Test problems with impossible ON or WHERE
#
select t1.id,t2.id from t2 left join t1 on t1.id>=74 and t1.id<=0 where t2.id=75 and t1.id is null;
explain select t1.id,t2.id from t2 left join t1 on t1.id>=74 and t1.id<=0 where t2.id=75 and t1.id is null;
explain select t1.id, t2.id from t1, t2 where t2.id = t1.id and t1.id <0 and t1.id > 0;
drop table t1,t2; drop table t1,t2;
# #
......
#!/bin/sh #!/bin/sh
echo "This scripts updates the mysql.user, mysql.db, mysql.host and the" echo "This scripts updates the mysql.user, mysql.db, mysql.host and the"
echo "mysql.func table to MySQL 3.22.14 and above." echo "mysql.func tables to MySQL 3.22.14 and above."
echo "" echo ""
echo "This is needed if you want to use the new GRANT functions," echo "This is needed if you want to use the new GRANT functions,"
echo "CREATE AGGREAGATE FUNCTION or want to use the more secure passwords in 3.23" echo "CREATE AGGREGATE FUNCTION or want to use the more secure passwords in 3.23"
echo "" echo ""
echo "If you get Access denied errors, you should run this script again" echo "If you get 'Access denied' errors, you should run this script again"
echo "and give the MySQL root user password as a argument!" echo "and give the MySQL root user password as an argument!"
root_password="$1" root_password="$1"
host="localhost" host="localhost"
user="root"
if test -z $1 ; then
cmd="@bindir@/mysql -f --user=$user --host=$host mysql"
else
root_password="$1"
cmd="@bindir@/mysql -f --user=$user --password=$root_password --host=$host mysql"
fi
echo "Converting all privilege tables to MyISAM format" echo "Converting all privilege tables to MyISAM format"
@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA $cmd <<END_OF_DATA
ALTER TABLE user type=MyISAM; ALTER TABLE user type=MyISAM;
ALTER TABLE db type=MyISAM; ALTER TABLE db type=MyISAM;
ALTER TABLE host type=MyISAM; ALTER TABLE host type=MyISAM;
...@@ -28,7 +36,7 @@ echo "" ...@@ -28,7 +36,7 @@ echo ""
echo "If your tables are already up to date or partially up to date you will" echo "If your tables are already up to date or partially up to date you will"
echo "get some warnings about 'Duplicated column name'. You can safely ignore these!" echo "get some warnings about 'Duplicated column name'. You can safely ignore these!"
@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA $cmd <<END_OF_DATA
alter table user change password password char(16) NOT NULL; alter table user change password password char(16) NOT NULL;
alter table user add File_priv enum('N','Y') NOT NULL; alter table user add File_priv enum('N','Y') NOT NULL;
CREATE TABLE if not exists func ( CREATE TABLE if not exists func (
...@@ -45,7 +53,7 @@ echo "" ...@@ -45,7 +53,7 @@ echo ""
echo "Creating Grant Alter and Index privileges if they don't exists" echo "Creating Grant Alter and Index privileges if they don't exists"
echo "You can ignore any Duplicate column errors" echo "You can ignore any Duplicate column errors"
@bindir@/mysql --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA $cmd <<END_OF_DATA
alter table user add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') NOT NULL,add Index_priv enum('N','Y') NOT NULL,add Alter_priv enum('N','Y') NOT NULL; alter table user add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') NOT NULL,add Index_priv enum('N','Y') NOT NULL,add Alter_priv enum('N','Y') NOT NULL;
alter table host add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') NOT NULL,add Index_priv enum('N','Y') NOT NULL,add Alter_priv enum('N','Y') NOT NULL; alter table host add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') NOT NULL,add Index_priv enum('N','Y') NOT NULL,add Alter_priv enum('N','Y') NOT NULL;
alter table db add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') NOT NULL,add Index_priv enum('N','Y') NOT NULL,add Alter_priv enum('N','Y') NOT NULL; alter table db add Grant_priv enum('N','Y') NOT NULL,add References_priv enum('N','Y') NOT NULL,add Index_priv enum('N','Y') NOT NULL,add Alter_priv enum('N','Y') NOT NULL;
...@@ -59,7 +67,7 @@ echo "" ...@@ -59,7 +67,7 @@ echo ""
if test $res = 0 if test $res = 0
then then
echo "Setting default privileges for the new grant, index and alter privileges" echo "Setting default privileges for the new grant, index and alter privileges"
@bindir@/mysql --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA $cmd <<END_OF_DATA
UPDATE user SET Grant_priv=File_priv,References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv; UPDATE user SET Grant_priv=File_priv,References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv;
UPDATE db SET References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv; UPDATE db SET References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv;
UPDATE host SET References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv; UPDATE host SET References_priv=Create_priv,Index_priv=Create_priv,Alter_priv=Create_priv;
...@@ -72,7 +80,7 @@ fi ...@@ -72,7 +80,7 @@ fi
echo "Adding columns needed by GRANT .. REQUIRE (openssl)" echo "Adding columns needed by GRANT .. REQUIRE (openssl)"
echo "You can ignore any Duplicate column errors" echo "You can ignore any Duplicate column errors"
@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA $cmd <<END_OF_DATA
ALTER TABLE user ALTER TABLE user
ADD ssl_type enum('','ANY','X509', 'SPECIFIED') NOT NULL, ADD ssl_type enum('','ANY','X509', 'SPECIFIED') NOT NULL,
ADD ssl_cipher BLOB NOT NULL, ADD ssl_cipher BLOB NOT NULL,
...@@ -88,7 +96,7 @@ echo "" ...@@ -88,7 +96,7 @@ echo ""
echo "Creating the new table and column privilege tables" echo "Creating the new table and column privilege tables"
@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA $cmd <<END_OF_DATA
CREATE TABLE IF NOT EXISTS tables_priv ( CREATE TABLE IF NOT EXISTS tables_priv (
Host char(60) DEFAULT '' NOT NULL, Host char(60) DEFAULT '' NOT NULL,
Db char(60) DEFAULT '' NOT NULL, Db char(60) DEFAULT '' NOT NULL,
...@@ -119,7 +127,7 @@ END_OF_DATA ...@@ -119,7 +127,7 @@ END_OF_DATA
echo "Changing name of columns_priv.Type -> columns_priv.Column_priv" echo "Changing name of columns_priv.Type -> columns_priv.Column_priv"
echo "You can ignore any Unknown column errors from this" echo "You can ignore any Unknown column errors from this"
@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA $cmd <<END_OF_DATA
ALTER TABLE columns_priv change Type Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL; ALTER TABLE columns_priv change Type Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL;
END_OF_DATA END_OF_DATA
echo "" echo ""
...@@ -131,7 +139,7 @@ echo "" ...@@ -131,7 +139,7 @@ echo ""
echo "Fixing the func table" echo "Fixing the func table"
echo "You can ignore any Duplicate column errors" echo "You can ignore any Duplicate column errors"
@bindir@/mysql --user=root --password=$root_password mysql <<EOF $cmd <<EOF
alter table func add type enum ('function','aggregate') NOT NULL; alter table func add type enum ('function','aggregate') NOT NULL;
EOF EOF
echo "" echo ""
...@@ -143,7 +151,7 @@ echo "" ...@@ -143,7 +151,7 @@ echo ""
echo "Adding new fields used by MySQL 4.0.2 to the privilege tables" echo "Adding new fields used by MySQL 4.0.2 to the privilege tables"
echo "You can ignore any Duplicate column errors" echo "You can ignore any Duplicate column errors"
@bindir@/mysql --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA $cmd <<END_OF_DATA
alter table user alter table user
add Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER alter_priv, add Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER alter_priv,
add Super_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Show_db_priv, add Super_priv enum('N','Y') DEFAULT 'N' NOT NULL AFTER Show_db_priv,
...@@ -159,7 +167,7 @@ then ...@@ -159,7 +167,7 @@ then
# Convert privileges so that users have similar privileges as before # Convert privileges so that users have similar privileges as before
echo "" echo ""
echo "Updating new privileges in MySQL 4.0.2 from old ones" echo "Updating new privileges in MySQL 4.0.2 from old ones"
@bindir@/mysql --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA $cmd <<END_OF_DATA
update user set show_db_priv= select_priv, super_priv=process_priv, execute_priv=process_priv, create_tmp_table_priv='Y', Lock_tables_priv='Y', Repl_slave_priv=file_priv, Repl_client_priv=file_priv where user<>""; update user set show_db_priv= select_priv, super_priv=process_priv, execute_priv=process_priv, create_tmp_table_priv='Y', Lock_tables_priv='Y', Repl_slave_priv=file_priv, Repl_client_priv=file_priv where user<>"";
END_OF_DATA END_OF_DATA
echo "" echo ""
...@@ -168,7 +176,7 @@ fi ...@@ -168,7 +176,7 @@ fi
# Add fields that can be used to limit number of questions and connections # Add fields that can be used to limit number of questions and connections
# for some users. # for some users.
@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA $cmd <<END_OF_DATA
alter table user alter table user
add max_questions int(11) NOT NULL AFTER x509_subject, add max_questions int(11) NOT NULL AFTER x509_subject,
add max_updates int(11) unsigned NOT NULL AFTER max_questions, add max_updates int(11) unsigned NOT NULL AFTER max_questions,
...@@ -179,7 +187,7 @@ END_OF_DATA ...@@ -179,7 +187,7 @@ END_OF_DATA
# Add Create_tmp_table_priv and Lock_tables_priv to db and host # Add Create_tmp_table_priv and Lock_tables_priv to db and host
# #
@bindir@/mysql --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA $cmd <<END_OF_DATA
alter table db alter table db
add Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, add Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL,
add Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL; add Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL;
......
...@@ -13,7 +13,7 @@ BEGIN { ...@@ -13,7 +13,7 @@ BEGIN {
$script = $1; $script = $1;
$script = 'MySQLAccess' unless $script; $script = 'MySQLAccess' unless $script;
$script_conf = "$script.conf"; $script_conf = "$script.conf";
$script_log = "~/$script.log"; $script_log = $ENV{'HOME'}."/$script.log";
# **************************** # ****************************
# information on MySQL # information on MySQL
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
trap '' 1 2 3 15 # we shouldn't let anyone kill us trap '' 1 2 3 15 # we shouldn't let anyone kill us
umask 007
defaults= defaults=
case "$1" in case "$1" in
--no-defaults|--defaults-file=*|--defaults-extra-file=*) --no-defaults|--defaults-file=*|--defaults-extra-file=*)
......
...@@ -4166,6 +4166,16 @@ ha_innobase::store_lock( ...@@ -4166,6 +4166,16 @@ ha_innobase::store_lock(
lock_type = TL_WRITE_ALLOW_WRITE; lock_type = TL_WRITE_ALLOW_WRITE;
} }
/* In queries of type INSERT INTO t1 SELECT ... FROM t2 ...
MySQL would use the lock TL_READ_NO_INSERT on t2, and that
would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts
to t2. Convert the lock to a normal read lock to allow
concurrent inserts to t2. */
if (lock_type == TL_READ_NO_INSERT && !thd->in_lock_tables) {
lock_type = TL_READ;
}
lock.type=lock_type; lock.type=lock_type;
} }
......
...@@ -1702,10 +1702,11 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) ...@@ -1702,10 +1702,11 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) if (db_ok(thd->db, replicate_do_db, replicate_ignore_db))
{ {
thd->query = (char*)query;
thd->set_time((time_t)when); thd->set_time((time_t)when);
thd->current_tablenr = 0; thd->current_tablenr = 0;
thd->query_length= q_len;
VOID(pthread_mutex_lock(&LOCK_thread_count)); VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query = (char*)query;
thd->query_id = query_id++; thd->query_id = query_id++;
VOID(pthread_mutex_unlock(&LOCK_thread_count)); VOID(pthread_mutex_unlock(&LOCK_thread_count));
thd->query_error = 0; // clear error thd->query_error = 0; // clear error
...@@ -1760,7 +1761,9 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) ...@@ -1760,7 +1761,9 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
else else
{ {
// master could be inconsistent, abort and tell DBA to check/fix it // master could be inconsistent, abort and tell DBA to check/fix it
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->db = thd->query = 0; thd->db = thd->query = 0;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
thd->variables.convert_set = 0; thd->variables.convert_set = 0;
close_thread_tables(thd); close_thread_tables(thd);
free_root(&thd->mem_root,0); free_root(&thd->mem_root,0);
...@@ -1768,7 +1771,9 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) ...@@ -1768,7 +1771,9 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
} }
} }
thd->db= 0; // prevent db from being freed thd->db= 0; // prevent db from being freed
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query= 0; // just to be sure thd->query= 0; // just to be sure
VOID(pthread_mutex_unlock(&LOCK_thread_count));
// assume no convert for next query unless set explictly // assume no convert for next query unless set explictly
thd->variables.convert_set = 0; thd->variables.convert_set = 0;
close_thread_tables(thd); close_thread_tables(thd);
...@@ -1816,7 +1821,8 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, ...@@ -1816,7 +1821,8 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
{ {
init_sql_alloc(&thd->mem_root, 8192,0); init_sql_alloc(&thd->mem_root, 8192,0);
thd->db = rewrite_db((char*)db); thd->db = rewrite_db((char*)db);
thd->query = 0; DBUG_ASSERT(thd->query == 0);
thd->query = 0; // Should not be needed
thd->query_error = 0; thd->query_error = 0;
if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) if (db_ok(thd->db, replicate_do_db, replicate_ignore_db))
......
...@@ -867,6 +867,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, ...@@ -867,6 +867,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
const char* table_name) const char* table_name)
{ {
ulong packet_len = my_net_read(net); // read create table statement ulong packet_len = my_net_read(net); // read create table statement
char *query;
Vio* save_vio; Vio* save_vio;
HA_CHECK_OPT check_opt; HA_CHECK_OPT check_opt;
TABLE_LIST tables; TABLE_LIST tables;
...@@ -886,15 +887,23 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, ...@@ -886,15 +887,23 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
return 1; return 1;
} }
thd->command = COM_TABLE_DUMP; thd->command = COM_TABLE_DUMP;
thd->query = sql_alloc(packet_len + 1); /* Note that we should not set thd->query until the area is initalized */
if (!thd->query) if (!(query = sql_alloc(packet_len + 1)))
{ {
sql_print_error("create_table_from_dump: out of memory"); sql_print_error("create_table_from_dump: out of memory");
net_printf(&thd->net, ER_GET_ERRNO, "Out of memory"); net_printf(&thd->net, ER_GET_ERRNO, "Out of memory");
return 1; return 1;
} }
memcpy(thd->query, net->read_pos, packet_len); memcpy(query, net->read_pos, packet_len);
thd->query[packet_len] = 0; query[packet_len]= 0;
thd->query_length= packet_len;
/*
We make the following lock in an attempt to ensure that the compiler will
not rearrange the code so that thd->query is set too soon
*/
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query= query;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
thd->current_tablenr = 0; thd->current_tablenr = 0;
thd->query_error = 0; thd->query_error = 0;
thd->net.no_send_ok = 1; thd->net.no_send_ok = 1;
...@@ -2049,7 +2058,9 @@ log space"); ...@@ -2049,7 +2058,9 @@ log space");
// print the current replication position // print the current replication position
sql_print_error("Slave I/O thread exiting, read up to log '%s', position %s", sql_print_error("Slave I/O thread exiting, read up to log '%s', position %s",
IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff)); IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff));
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query = thd->db = 0; // extra safety thd->query = thd->db = 0; // extra safety
VOID(pthread_mutex_unlock(&LOCK_thread_count));
if (mysql) if (mysql)
{ {
mc_mysql_close(mysql); mc_mysql_close(mysql);
...@@ -2183,7 +2194,9 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ ...@@ -2183,7 +2194,9 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
RPL_LOG_NAME, llstr(rli->master_log_pos,llbuff)); RPL_LOG_NAME, llstr(rli->master_log_pos,llbuff));
err: err:
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query = thd->db = 0; // extra safety thd->query = thd->db = 0; // extra safety
VOID(pthread_mutex_unlock(&LOCK_thread_count));
thd->proc_info = "Waiting for slave mutex on exit"; thd->proc_info = "Waiting for slave mutex on exit";
pthread_mutex_lock(&rli->run_lock); pthread_mutex_lock(&rli->run_lock);
DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun
......
...@@ -2322,6 +2322,7 @@ my_bool grant_init(THD *org_thd) ...@@ -2322,6 +2322,7 @@ my_bool grant_init(THD *org_thd)
if (t_table->file->index_first(t_table->record[0])) if (t_table->file->index_first(t_table->record[0]))
{ {
t_table->file->index_end(); t_table->file->index_end();
return_val= 0;
goto end_unlock; goto end_unlock;
} }
grant_option= TRUE; grant_option= TRUE;
......
...@@ -78,9 +78,9 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent) ...@@ -78,9 +78,9 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent)
if (!thd->query) if (!thd->query)
{ {
/* The client used the old obsolete mysql_create_db() call */ /* The client used the old obsolete mysql_create_db() call */
thd->query = path; thd->query_length= (uint) (strxmov(path,"create database `", db, "`",
thd->query_length = (uint) (strxmov(path,"create database `", db, "`", NullS) - path);
NullS) - path); thd->query= path;
} }
{ {
mysql_update_log.write(thd,thd->query, thd->query_length); mysql_update_log.write(thd,thd->query, thd->query_length);
...@@ -92,8 +92,9 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent) ...@@ -92,8 +92,9 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent)
} }
if (thd->query == path) if (thd->query == path)
{ {
thd->query = 0; // just in case VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_length = 0; thd->query= 0;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
} }
send_ok(&thd->net, result); send_ok(&thd->net, result);
} }
...@@ -167,9 +168,10 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) ...@@ -167,9 +168,10 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
{ {
if (!thd->query) if (!thd->query)
{ {
thd->query = path; thd->query_length= (uint) (strxmov(path,"drop database `", db, "`",
thd->query_length = (uint) (strxmov(path,"drop database ", db, NullS)- NullS)-
path); path);
thd->query= path;
} }
mysql_update_log.write(thd, thd->query, thd->query_length); mysql_update_log.write(thd, thd->query, thd->query_length);
if (mysql_bin_log.is_open()) if (mysql_bin_log.is_open())
...@@ -179,8 +181,9 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) ...@@ -179,8 +181,9 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
} }
if (thd->query == path) if (thd->query == path)
{ {
thd->query = 0; // just in case VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_length = 0; thd->query= 0;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
} }
send_ok(&thd->net,(ulong) deleted); send_ok(&thd->net,(ulong) deleted);
} }
......
...@@ -852,7 +852,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) ...@@ -852,7 +852,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
goto err; goto err;
} }
net_flush(&thd->net); net_flush(&thd->net);
if ((error = table->file->dump(thd,fd))) if ((error= table->file->dump(thd,fd)))
my_error(ER_GET_ERRNO, MYF(0)); my_error(ER_GET_ERRNO, MYF(0));
err: err:
...@@ -958,7 +958,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -958,7 +958,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
tbl_name[tbl_len] = 0; tbl_name[tbl_len] = 0;
if (mysql_table_dump(thd, db, tbl_name, -1)) if (mysql_table_dump(thd, db, tbl_name, -1))
send_error(&thd->net); // dump to NET send_error(&thd->net); // dump to NET
break; break;
} }
case COM_CHANGE_USER: case COM_CHANGE_USER:
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB /* Copyright (C) 2000-2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -1009,7 +1009,6 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, ...@@ -1009,7 +1009,6 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
table_map found_const_table_map,all_table_map; table_map found_const_table_map,all_table_map;
TABLE **table_vector; TABLE **table_vector;
JOIN_TAB *stat,*stat_end,*s,**stat_ref; JOIN_TAB *stat,*stat_end,*s,**stat_ref;
SQL_SELECT *select;
KEYUSE *keyuse,*start_keyuse; KEYUSE *keyuse,*start_keyuse;
table_map outer_join=0; table_map outer_join=0;
JOIN_TAB *stat_vector[MAX_TABLES+1]; JOIN_TAB *stat_vector[MAX_TABLES+1];
...@@ -1021,7 +1020,6 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, ...@@ -1021,7 +1020,6 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
table_vector=(TABLE**) join->thd->alloc(sizeof(TABLE*)*(table_count*2)); table_vector=(TABLE**) join->thd->alloc(sizeof(TABLE*)*(table_count*2));
if (!stat || !stat_ref || !table_vector) if (!stat || !stat_ref || !table_vector)
DBUG_RETURN(1); // Eom /* purecov: inspected */ DBUG_RETURN(1); // Eom /* purecov: inspected */
select=0;
join->best_ref=stat_vector; join->best_ref=stat_vector;
...@@ -1205,7 +1203,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, ...@@ -1205,7 +1203,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
{ // Found everything for ref. { // Found everything for ref.
int tmp; int tmp;
ref_changed = 1; ref_changed = 1;
s->type=JT_CONST; s->type= JT_CONST;
join->const_table_map|=table->map; join->const_table_map|=table->map;
set_position(join,const_count++,s,start_keyuse); set_position(join,const_count++,s,start_keyuse);
if (create_ref_for_key(join, s, start_keyuse, if (create_ref_for_key(join, s, start_keyuse,
...@@ -1256,23 +1254,44 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, ...@@ -1256,23 +1254,44 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
if (s->const_keys) if (s->const_keys)
{ {
ha_rows records; ha_rows records;
if (!select) SQL_SELECT *select;
select=make_select(s->table, found_const_table_map, select= make_select(s->table, found_const_table_map,
found_const_table_map, found_const_table_map,
and_conds(conds,s->on_expr),&error); s->on_expr ? s->on_expr : conds,
records=get_quick_record_count(select,s->table, s->const_keys, &error);
join->row_limit); records= get_quick_record_count(select,s->table, s->const_keys,
join->row_limit);
s->quick=select->quick; s->quick=select->quick;
s->needed_reg=select->needed_reg; s->needed_reg=select->needed_reg;
select->quick=0; select->quick=0;
if (records == 0 && s->table->reginfo.impossible_range)
{
/*
Impossible WHERE or ON expression
In case of ON, we mark that the we match one empty NULL row.
In case of WHERE, don't set found_const_table_map to get the
caller to abort with a zero row result.
*/
join->const_table_map|= s->table->map;
set_position(join,const_count++,s,(KEYUSE*) 0);
s->type= JT_CONST;
if (s->on_expr)
{
/* Generate empty row */
s->info= "Impossible ON condition";
found_const_table_map|= s->table->map;
s->type= JT_CONST;
mark_as_null_row(s->table); // All fields are NULL
}
}
if (records != HA_POS_ERROR) if (records != HA_POS_ERROR)
{ {
s->found_records=records; s->found_records=records;
s->read_time= (ha_rows) (s->quick ? s->quick->read_time : 0.0); s->read_time= (ha_rows) (s->quick ? s->quick->read_time : 0.0);
} }
delete select;
} }
} }
delete select;
/* Find best combination and return it */ /* Find best combination and return it */
join->join_tab=stat; join->join_tab=stat;
...@@ -2367,7 +2386,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, ...@@ -2367,7 +2386,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
keyparts != keyinfo->key_parts) keyparts != keyinfo->key_parts)
j->type=JT_REF; /* Must read with repeat */ j->type=JT_REF; /* Must read with repeat */
else if (ref_key == j->ref.key_copy) else if (ref_key == j->ref.key_copy)
{ /* Should never be reached */ {
/* /*
This happen if we are using a constant expression in the ON part This happen if we are using a constant expression in the ON part
of an LEFT JOIN. of an LEFT JOIN.
...@@ -7333,36 +7352,39 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, ...@@ -7333,36 +7352,39 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
if (tab->info) if (tab->info)
item_list.push_back(new Item_string(tab->info,strlen(tab->info))); item_list.push_back(new Item_string(tab->info,strlen(tab->info)));
else if (tab->select) else
{ {
if (tab->use_quick == 2) if (tab->select)
{ {
sprintf(buff_ptr,"; Range checked for each record (index map: %u)", if (tab->use_quick == 2)
tab->keys); {
buff_ptr=strend(buff_ptr); sprintf(buff_ptr,"; Range checked for each record (index map: %u)",
tab->keys);
buff_ptr=strend(buff_ptr);
}
else
buff_ptr=strmov(buff_ptr,"; Using where");
} }
else if (key_read)
buff_ptr=strmov(buff_ptr,"; Using where"); buff_ptr= strmov(buff_ptr,"; Using index");
} if (table->reginfo.not_exists_optimize)
if (key_read) buff_ptr= strmov(buff_ptr,"; Not exists");
buff_ptr= strmov(buff_ptr,"; Using index"); if (need_tmp_table)
if (table->reginfo.not_exists_optimize) {
buff_ptr= strmov(buff_ptr,"; Not exists"); need_tmp_table=0;
if (need_tmp_table) buff_ptr= strmov(buff_ptr,"; Using temporary");
{ }
need_tmp_table=0; if (need_order)
buff_ptr= strmov(buff_ptr,"; Using temporary"); {
} need_order=0;
if (need_order) buff_ptr= strmov(buff_ptr,"; Using filesort");
{ }
need_order=0; if (distinct && test_all_bits(used_tables,thd->used_tables))
buff_ptr= strmov(buff_ptr,"; Using filesort"); buff_ptr= strmov(buff_ptr,"; Distinct");
if (buff_ptr == buff)
buff_ptr+= 2;
item_list.push_back(new Item_string(buff+2,(uint) (buff_ptr - buff)-2));
} }
if (distinct && test_all_bits(used_tables,thd->used_tables))
buff_ptr= strmov(buff_ptr,"; Distinct");
if (buff_ptr == buff)
buff_ptr+= 2;
item_list.push_back(new Item_string(buff+2,(uint) (buff_ptr - buff)-2));
// For next iteration // For next iteration
used_tables|=table->map; used_tables|=table->map;
if (result->send_data(item_list)) if (result->send_data(item_list))
......
...@@ -1771,12 +1771,9 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -1771,12 +1771,9 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
/* We changed a temporary table */ /* We changed a temporary table */
if (error) if (error)
{ {
/* /*
* The following function call will also free a The following function call will free the new_table pointer,
* new_table pointer. in close_temporary_table(), so we can safely directly jump to err
* Therefore, here new_table pointer is not free'd as it is
* free'd in close_temporary() which is called by by the
* close_temporary_table() function.
*/ */
close_temporary_table(thd,new_db,tmp_name); close_temporary_table(thd,new_db,tmp_name);
goto err; goto err;
......
...@@ -40,6 +40,7 @@ endif ...@@ -40,6 +40,7 @@ endif
libmystrings_a_SOURCES = $(ASRCS) $(CSRCS) libmystrings_a_SOURCES = $(ASRCS) $(CSRCS)
noinst_PROGRAMS = conf_to_src noinst_PROGRAMS = conf_to_src
DISTCLEANFILES = ctype_autoconf.c
# Default charset definitions # Default charset definitions
EXTRA_DIST = ctype-big5.c ctype-czech.c ctype-euc_kr.c \ EXTRA_DIST = ctype-big5.c ctype-czech.c ctype-euc_kr.c \
ctype-gb2312.c ctype-gbk.c ctype-sjis.c \ ctype-gb2312.c ctype-gbk.c ctype-sjis.c \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment