diff options
author | unknown <Sinisa@sinisa.nasamreza.org> | 2003-01-21 15:54:36 +0200 |
---|---|---|
committer | unknown <Sinisa@sinisa.nasamreza.org> | 2003-01-21 15:54:36 +0200 |
commit | 30a35bcfe456cc118381e5475c90dda32e414d72 (patch) | |
tree | 12b636bd4e539bd743ac707375d81f309509f79c | |
parent | 81ef01f99261ad2b19adcb1376313d0108fcdfa2 (diff) | |
parent | d5833961ced5efb64c62d17dd7e632eefefede3d (diff) | |
download | mariadb-git-30a35bcfe456cc118381e5475c90dda32e414d72.tar.gz |
Merge sinisa@work.mysql.com:/home/bk/mysql-4.0
into sinisa.nasamreza.org:/mnt/work/mysql-4.0
scripts/mysqld_safe.sh:
Auto merged
sql/net_pkg.cc:
Auto merged
sql/sql_acl.cc:
Auto merged
43 files changed, 280 insertions, 117 deletions
diff --git a/.bzrignore b/.bzrignore index 70ecba34c3a..1f577634845 100644 --- a/.bzrignore +++ b/.bzrignore @@ -522,3 +522,4 @@ vio/test-ssl vio/test-sslclient vio/test-sslserver vio/viotest-ssl +extra/mysql_waitpid diff --git a/Makefile.am b/Makefile.am index 87d1c7b5b71..7949e7be776 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,10 +21,10 @@ AUTOMAKE_OPTIONS = foreign # These are built from source in the Docs directory EXTRA_DIST = INSTALL-SOURCE README \ COPYING COPYING.LIB -SUBDIRS = include @docs_dirs@ @readline_dir@ \ +SUBDIRS = . include @docs_dirs@ @readline_dir@ \ @thread_dirs@ pstack @sql_client_dirs@ \ - @sql_server_dirs@ @libmysqld_dirs@ scripts man \ - tests BUILD os2 \ + @sql_server_dirs@ scripts man tests \ + BUILD os2 libmysql_r @libmysqld_dirs@ \ @bench_dirs@ support-files @fs_dirs@ @tools_dirs@ # Relink after clean diff --git a/bdb/dist/aclocal/mutex.m4 b/bdb/dist/aclocal/mutex.m4 index 5c9218da163..2010670599f 100644 --- a/bdb/dist/aclocal/mutex.m4 +++ b/bdb/dist/aclocal/mutex.m4 @@ -279,7 +279,7 @@ fi dnl Sparc/gcc: SunOS, Solaris 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. -if test "$db_cv_mutex" = DOESNT_WORK; then +if test "$db_cv_mutex" = no; then AC_TRY_RUN([main(){ #if defined(__sparc__) #if defined(__GNUC__) diff --git a/bdb/include/mutex.h b/bdb/include/mutex.h index 4c1b265355d..9f341695cbf 100644 --- a/bdb/include/mutex.h +++ b/bdb/include/mutex.h @@ -327,7 +327,7 @@ typedef unsigned char tsl_t; */ #define MUTEX_SET(tsl) ({ \ register tsl_t *__l = (tsl); \ - int __r; \ + unsigned char __r; \ asm volatile("tas %1; \n \ seq %0" \ : "=dm" (__r), "=m" (*__l) \ diff --git a/client/mysqltest.c b/client/mysqltest.c index fe99dda1ac3..9e411e5f28f 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -42,7 +42,7 @@ **********************************************************************/ -#define MTEST_VERSION "1.26" +#define MTEST_VERSION "1.27" #include <my_global.h> #include <mysql_embed.h> @@ -677,7 +677,7 @@ int open_file(const char* name) if (*cur_file && cur_file == file_stack_end) 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); cur_file++; *++lineno=1; @@ -1912,7 +1912,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), argument= buff; } 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); break; } diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c index de3fe6e196e..5c5ed934a9b 100644 --- a/innobase/btr/btr0sea.c +++ b/innobase/btr/btr0sea.c @@ -508,6 +508,14 @@ btr_search_check_guess( /*===================*/ /* out: TRUE if success */ 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 */ ulint mode, /* in: PAGE_CUR_L, PAGE_CUR_LE, PAGE_CUR_G, or PAGE_CUR_GE */ @@ -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; bytes = 0; @@ -670,6 +685,7 @@ btr_search_guess_on_hash( ulint fold; ulint tuple_n_fields; dulint tree_id; + ibool can_only_compare_to_cursor_rec = TRUE; #ifdef notdefined btr_cur_t cursor2; btr_pcur_t pcur; @@ -744,6 +760,8 @@ btr_search_guess_on_hash( goto failure; } + can_only_compare_to_cursor_rec = FALSE; + buf_page_dbg_add_level(page, SYNC_TREE_NODE_FROM_HASH); } @@ -775,7 +793,15 @@ btr_search_guess_on_hash( fold); */ } 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) { diff --git a/innobase/include/btr0sea.h b/innobase/include/btr0sea.h index 14feca5d5c5..ee762a12221 100644 --- a/innobase/include/btr0sea.h +++ b/innobase/include/btr0sea.h @@ -234,10 +234,16 @@ struct btr_search_sys_struct{ extern btr_search_sys_t* btr_search_sys; /* 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. -NOTE: It does not protect values of non-ordering fields within a record from -being updated in-place! We can use fact (1) to perform unique searches to -indexes. */ +(1) hash index; +(2) columns of a record to which we have a pointer in the hash index; + +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; diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c index bb49e9080ce..1ea6e3e3018 100644 --- a/innobase/page/page0cur.c +++ b/innobase/page/page0cur.c @@ -253,7 +253,8 @@ page_cur_search_with_match( 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_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; @@ -308,7 +309,8 @@ page_cur_search_with_match( up_matched_fields = cur_matched_fields; 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_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared index e308baa7bd0..2bcf95f467d 100644 --- a/libmysql/Makefile.shared +++ b/libmysql/Makefile.shared @@ -84,6 +84,8 @@ clean-local: rm -f `echo $(mystringsobjects) | sed "s;\.lo;.c;g"` \ `echo $(dbugobjects) | 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) \ ctype_extra_sources.c net.c ../linked_client_sources @@ -3009,6 +3009,16 @@ hardcode_action=$hardcode_action # This must work even if \$libdir does not exist. 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. hardcode_libdir_separator=$hardcode_libdir_separator diff --git a/man/isamchk.1 b/man/isamchk.1 index 2552d9f80cd..bfc4ccd9c08 100644 --- a/man/isamchk.1 +++ b/man/isamchk.1 @@ -1,4 +1,4 @@ -.TH ISAMCHK 1 "19 December 2000" +.TH isamchk 1 "19 December 2000" "MySQL 3.23" "MySQL database" .SH NAME .BR isamchk \- Description, check and repair of ISAM tables. diff --git a/man/isamlog.1 b/man/isamlog.1 index ef6ceaff8da..a386f11c010 100644 --- a/man/isamlog.1 +++ b/man/isamlog.1 @@ -1,4 +1,4 @@ -.TH ISAMLOG 1 "20 December 2000" +.TH isamlog 1 "19 December 2000" "MySQL 3.23" "MySQL database" .SH NAME isamlog - Write info about whats in a nisam log file. .SH USAGE diff --git a/man/mysql.1 b/man/mysql.1 index e10fd589092..6664581072f 100644 --- a/man/mysql.1 +++ b/man/mysql.1 @@ -1,4 +1,4 @@ -.TH MYSQL 1 "13 June 1997" +.TH mysql 1 "19 December 2000" "MySQL 3.23" "MySQL database" .SH NAME mysql \- text-based client for mysqld, a SQL-based relational database daemon .SH SYNOPSIS diff --git a/man/mysql_zap.1 b/man/mysql_zap.1 index e57eb7a4d07..144fc212372 100644 --- a/man/mysql_zap.1 +++ b/man/mysql_zap.1 @@ -1,4 +1,4 @@ -.TH ZAP 1 "20 December 2000" +.TH zap 1 "19 December 2000" "MySQL 3.23" "MySQL database" .SH NAME zap - a perl script used to kill processes .SH USAGE diff --git a/man/mysqlaccess.1 b/man/mysqlaccess.1 index 0ae06dca137..c1c61d4a8a7 100644 --- a/man/mysqlaccess.1 +++ b/man/mysqlaccess.1 @@ -1,4 +1,4 @@ -.TH MYSQLACCESS 1 "19 December 2000" +.TH mysqlaccess 1 "19 December 2000" "MySQL 3.23" "MySQL database" .SH NAME .BR mysqlaccess \- Create new users to mysql. diff --git a/man/mysqladmin.1 b/man/mysqladmin.1 index 1e435006bb2..9d7d73aad21 100644 --- a/man/mysqladmin.1 +++ b/man/mysqladmin.1 @@ -1,4 +1,4 @@ -.TH MYSQLADMIN 1 "18 December 2000" +.TH mysqladmin 1 "19 December 2000" "MySQL 3.23" "MySQL database" .SH NAME mysqladmin [OPTIONS] command command.... \- A utility for performing administrative operations .SH OPTION SYNOPSIS diff --git a/man/mysqld.1 b/man/mysqld.1 index 1f87eb9cf32..0a6fcccbef2 100644 --- a/man/mysqld.1 +++ b/man/mysqld.1 @@ -1,4 +1,4 @@ -.TH MYSQLD 1 "19 December 2000" +.TH mysqld 1 "19 December 2000" "MySQL 3.23" "MySQL database" .SH NAME .BR mysqld \- Starts the MySQL server demon diff --git a/man/mysqld_multi.1 b/man/mysqld_multi.1 index b7aa77f656d..68b9d1e876f 100644 --- a/man/mysqld_multi.1 +++ b/man/mysqld_multi.1 @@ -1,4 +1,4 @@ -.TH MYSQLD_MULTI 1 "20 December 2000" +.TH mysqld_multi 1 "19 December 2000" "MySQL 3.23" "MySQL database" .SH NAME mysqld_multi - is meant for managing several mysqld processes running in different UNIX sockets and TCP/IP ports. .SH USAGE diff --git a/man/mysqld_safe.1 b/man/mysqld_safe.1 index c900d193929..b8271c848cc 100644 --- a/man/mysqld_safe.1 +++ b/man/mysqld_safe.1 @@ -1,4 +1,4 @@ -.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 mysqld_safe \- start the mysqld daemon on Unix. .SH SYNOPSIS diff --git a/man/mysqldump.1 b/man/mysqldump.1 index b9e5aa33791..b4aba2ade13 100644 --- a/man/mysqldump.1 +++ b/man/mysqldump.1 @@ -1,4 +1,4 @@ -.TH MYSQLDUMP 1 "19 December 2000" +.TH mysqldump 1 "19 December 2000" "MySQL 3.23" "MySQL database" .SH NAME mysqldump \- text-based client for dumping or backing up mysql databases , tables and or data. @@ -123,7 +123,7 @@ Connect to host. Lock all tables for read. .TP .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 be added otherwise, if .BR \-\-databases @@ -270,4 +270,4 @@ Manual page by L. (Kill-9) Pedersen (kill-9@kill-9.dk), Mercurmedia Data Model Architect / system developer (http://www.mercurmedia.com) -.\" end of man page
\ No newline at end of file +.\" end of man page diff --git a/man/mysqlshow.1 b/man/mysqlshow.1 index 661b2cd02c8..b6aceec82e3 100644 --- a/man/mysqlshow.1 +++ b/man/mysqlshow.1 @@ -1,4 +1,4 @@ -.TH MYSQLSHOW 1 "19 December 2000" +.TH mysqlshow 1 "19 December 2000" "MySQL 3.23" "MySQL database" .SH NAME .BR mysqlshow \- Shows the structure of a mysql database (databases,tables and columns) diff --git a/man/perror.1 b/man/perror.1 index 7adf99ea772..38a51593ba1 100644 --- a/man/perror.1 +++ b/man/perror.1 @@ -1,4 +1,4 @@ -.TH PERROR 1 "19 December 2000" +.TH perror 1 "19 December 2000" "MySQL 3.23" "MySQL database" .SH NAME .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. diff --git a/man/replace.1 b/man/replace.1 index 38ffe998027..7c3b79f605b 100644 --- a/man/replace.1 +++ b/man/replace.1 @@ -1,4 +1,4 @@ -.TH REPLACE 1 "20 December 2000" +.TH replace 1 "19 December 2000" "MySQL 3.23" "MySQL database" .SH NAME .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. diff --git a/myisam/mi_create.c b/myisam/mi_create.c index 8aa2dd53027..039066c5b37 100644 --- a/myisam/mi_create.c +++ b/myisam/mi_create.c @@ -228,7 +228,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, if (uniques) { 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++) diff --git a/myisam/mi_unique.c b/myisam/mi_unique.c index b373693e6e0..ddba40214e7 100644 --- a/myisam/mi_unique.c +++ b/myisam/mi_unique.c @@ -24,7 +24,7 @@ my_bool mi_check_unique(MI_INFO *info, MI_UNIQUEDEF *def, byte *record, { my_off_t lastpos=info->lastpos; 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"); mi_unique_store(record+key->seg->start, unique_hash); @@ -80,7 +80,16 @@ ha_checksum mi_unique_hash(MI_UNIQUEDEF *def, const byte *record) if (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; + } } pos= record+keyseg->start; if (keyseg->flag & HA_VAR_LENGTH) diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result index 876846a5236..fa15165722d 100644 --- a/mysql-test/r/explain.result +++ b/mysql-test/r/explain.result @@ -1,5 +1,8 @@ drop table if exists t1; 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"); select * from t1 where str is null; id str diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index ddddb3fa07d..02773f2eb44 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -467,3 +467,17 @@ NOT NULL); max(value) 4 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; diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index 96113dcdc8b..ff608825b9c 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -14,8 +14,7 @@ insert into t1 values (101); insert into t1 values (105); insert into t1 values (106); insert into t1 values (107); -insert into t2 values (107); -insert into t2 values (75); +insert into t2 values (107),(75),(1000); select t1.id, t2.id from t1, t2 where t2.id = t1.id; id id 107 107 @@ -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) 75 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; CREATE TABLE t1 ( id int(11) NOT NULL auto_increment, diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test index 31a01ae1360..8a41ebe5b4f 100644 --- a/mysql-test/t/explain.test +++ b/mysql-test/t/explain.test @@ -3,6 +3,7 @@ drop table if exists t1; 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"); select * from t1 where str is null; select * from t1 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"; #The following should give errors -!$1072 explain select * from t1 use key (str,str,foo) where str="foo"; -!$1072 explain select * from t1 ignore key (str,str,foo) where str="foo"; +--error 1072 +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; explain select 1; diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index 328b696ac05..bc01577c249 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -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 NOT NULL); 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; diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test index 18006e8fd22..f58281af003 100644 --- a/mysql-test/t/join.test +++ b/mysql-test/t/join.test @@ -19,13 +19,18 @@ insert into t1 values (105); insert into t1 values (106); insert into t1 values (107); -insert into t2 values (107); -insert into t2 values (75); +insert into t2 values (107),(75),(1000); 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 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; # diff --git a/scripts/mysql_fix_privilege_tables.sh b/scripts/mysql_fix_privilege_tables.sh index 247e3399b8b..09259779855 100644 --- a/scripts/mysql_fix_privilege_tables.sh +++ b/scripts/mysql_fix_privilege_tables.sh @@ -1,19 +1,27 @@ #!/bin/sh 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 "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 "If you get Access denied errors, you should run this script again" -echo "and give the MySQL root user password as a argument!" +echo "If you get 'Access denied' errors, you should run this script again" +echo "and give the MySQL root user password as an argument!" root_password="$1" 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" -@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 db type=MyISAM; ALTER TABLE host type=MyISAM; @@ -28,7 +36,7 @@ echo "" 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!" -@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 add File_priv enum('N','Y') NOT NULL; CREATE TABLE if not exists func ( @@ -45,7 +53,7 @@ echo "" echo "Creating Grant Alter and Index privileges if they don't exists" 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 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; @@ -59,7 +67,7 @@ echo "" if test $res = 0 then 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 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; @@ -72,7 +80,7 @@ fi echo "Adding columns needed by GRANT .. REQUIRE (openssl)" 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 ADD ssl_type enum('','ANY','X509', 'SPECIFIED') NOT NULL, ADD ssl_cipher BLOB NOT NULL, @@ -88,7 +96,7 @@ echo "" 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 ( Host char(60) DEFAULT '' NOT NULL, Db char(60) DEFAULT '' NOT NULL, @@ -119,7 +127,7 @@ END_OF_DATA echo "Changing name of columns_priv.Type -> columns_priv.Column_priv" 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; END_OF_DATA echo "" @@ -131,7 +139,7 @@ echo "" echo "Fixing the func table" 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; EOF echo "" @@ -143,7 +151,7 @@ echo "" echo "Adding new fields used by MySQL 4.0.2 to the privilege tables" 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 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, @@ -159,7 +167,7 @@ then # Convert privileges so that users have similar privileges as before echo "" 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<>""; END_OF_DATA echo "" @@ -168,7 +176,7 @@ fi # Add fields that can be used to limit number of questions and connections # for some users. -@bindir@/mysql -f --user=root --password="$root_password" --host="$host" mysql <<END_OF_DATA +$cmd <<END_OF_DATA alter table user add max_questions int(11) NOT NULL AFTER x509_subject, add max_updates int(11) unsigned NOT NULL AFTER max_questions, @@ -179,7 +187,7 @@ END_OF_DATA # 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 add Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, add Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL; diff --git a/scripts/mysqlaccess.sh b/scripts/mysqlaccess.sh index 355eb53d2b5..824dba7b65a 100644 --- a/scripts/mysqlaccess.sh +++ b/scripts/mysqlaccess.sh @@ -13,7 +13,7 @@ BEGIN { $script = $1; $script = 'MySQLAccess' unless $script; $script_conf = "$script.conf"; - $script_log = "~/$script.log"; + $script_log = $ENV{'HOME'}."/$script.log"; # **************************** # information on MySQL diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 211cc8ceced..b68c6f56015 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -12,6 +12,8 @@ trap '' 1 2 3 15 # we shouldn't let anyone kill us +umask 007 + defaults= case "$1" in --no-defaults|--defaults-file=*|--defaults-extra-file=*) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index b4fe6130e9b..b1cb45be6b3 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -4166,6 +4166,16 @@ ha_innobase::store_lock( 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; } diff --git a/sql/log_event.cc b/sql/log_event.cc index 45f54e420de..e243a953c63 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -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)) { - thd->query = (char*)query; thd->set_time((time_t)when); thd->current_tablenr = 0; + thd->query_length= q_len; VOID(pthread_mutex_lock(&LOCK_thread_count)); + thd->query = (char*)query; thd->query_id = query_id++; VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->query_error = 0; // clear error @@ -1760,7 +1761,9 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) else { // master could be inconsistent, abort and tell DBA to check/fix it + VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->db = thd->query = 0; + VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->variables.convert_set = 0; close_thread_tables(thd); free_root(&thd->mem_root,0); @@ -1768,7 +1771,9 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) } } thd->db= 0; // prevent db from being freed + VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query= 0; // just to be sure + VOID(pthread_mutex_unlock(&LOCK_thread_count)); // assume no convert for next query unless set explictly thd->variables.convert_set = 0; close_thread_tables(thd); @@ -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); 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; if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) diff --git a/sql/slave.cc b/sql/slave.cc index b8689a28a54..30c345f8030 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -867,6 +867,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, const char* table_name) { ulong packet_len = my_net_read(net); // read create table statement + char *query; Vio* save_vio; HA_CHECK_OPT check_opt; TABLE_LIST tables; @@ -886,15 +887,23 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, return 1; } thd->command = COM_TABLE_DUMP; - thd->query = sql_alloc(packet_len + 1); - if (!thd->query) + /* Note that we should not set thd->query until the area is initalized */ + if (!(query = sql_alloc(packet_len + 1))) { sql_print_error("create_table_from_dump: out of memory"); net_printf(&thd->net, ER_GET_ERRNO, "Out of memory"); return 1; } - memcpy(thd->query, net->read_pos, packet_len); - thd->query[packet_len] = 0; + memcpy(query, net->read_pos, packet_len); + 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->query_error = 0; thd->net.no_send_ok = 1; @@ -2049,7 +2058,9 @@ err: // print the current replication position 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)); + VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query = thd->db = 0; // extra safety + VOID(pthread_mutex_unlock(&LOCK_thread_count)); if (mysql) { mc_mysql_close(mysql); @@ -2183,7 +2194,9 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ RPL_LOG_NAME, llstr(rli->master_log_pos,llbuff)); err: + VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query = thd->db = 0; // extra safety + VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->proc_info = "Waiting for slave mutex on exit"; pthread_mutex_lock(&rli->run_lock); DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index a9bb22fb8f7..9091784bbf3 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2322,6 +2322,7 @@ my_bool grant_init(THD *org_thd) if (t_table->file->index_first(t_table->record[0])) { t_table->file->index_end(); + return_val= 0; goto end_unlock; } grant_option= TRUE; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index e805cf74f19..4cb46c00bed 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -78,9 +78,9 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent) if (!thd->query) { /* The client used the old obsolete mysql_create_db() call */ - thd->query = path; - thd->query_length = (uint) (strxmov(path,"create database `", db, "`", - NullS) - path); + thd->query_length= (uint) (strxmov(path,"create database `", db, "`", + NullS) - path); + thd->query= path; } { 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) } if (thd->query == path) { - thd->query = 0; // just in case - thd->query_length = 0; + VOID(pthread_mutex_lock(&LOCK_thread_count)); + thd->query= 0; + VOID(pthread_mutex_unlock(&LOCK_thread_count)); } send_ok(&thd->net, result); } @@ -167,9 +168,10 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) { if (!thd->query) { - thd->query = path; - thd->query_length = (uint) (strxmov(path,"drop database ", db, NullS)- - path); + thd->query_length= (uint) (strxmov(path,"drop database `", db, "`", + NullS)- + path); + thd->query= path; } mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) @@ -179,8 +181,9 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) } if (thd->query == path) { - thd->query = 0; // just in case - thd->query_length = 0; + VOID(pthread_mutex_lock(&LOCK_thread_count)); + thd->query= 0; + VOID(pthread_mutex_unlock(&LOCK_thread_count)); } send_ok(&thd->net,(ulong) deleted); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5bf3a1c0bcd..0b6170f1e37 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -852,7 +852,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) goto err; } 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)); err: @@ -958,7 +958,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, tbl_name[tbl_len] = 0; if (mysql_table_dump(thd, db, tbl_name, -1)) send_error(&thd->net); // dump to NET - break; } case COM_CHANGE_USER: diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 237197ba6be..e811c55ed1b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1,4 +1,4 @@ -/* 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 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, table_map found_const_table_map,all_table_map; TABLE **table_vector; JOIN_TAB *stat,*stat_end,*s,**stat_ref; - SQL_SELECT *select; KEYUSE *keyuse,*start_keyuse; table_map outer_join=0; JOIN_TAB *stat_vector[MAX_TABLES+1]; @@ -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)); if (!stat || !stat_ref || !table_vector) DBUG_RETURN(1); // Eom /* purecov: inspected */ - select=0; join->best_ref=stat_vector; @@ -1205,7 +1203,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, { // Found everything for ref. int tmp; ref_changed = 1; - s->type=JT_CONST; + s->type= JT_CONST; join->const_table_map|=table->map; set_position(join,const_count++,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, if (s->const_keys) { ha_rows records; - if (!select) - select=make_select(s->table, found_const_table_map, - found_const_table_map, - and_conds(conds,s->on_expr),&error); - records=get_quick_record_count(select,s->table, s->const_keys, - join->row_limit); + SQL_SELECT *select; + select= make_select(s->table, found_const_table_map, + found_const_table_map, + s->on_expr ? s->on_expr : conds, + &error); + records= get_quick_record_count(select,s->table, s->const_keys, + join->row_limit); s->quick=select->quick; s->needed_reg=select->needed_reg; 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) { s->found_records=records; s->read_time= (ha_rows) (s->quick ? s->quick->read_time : 0.0); } + delete select; } } - delete select; /* Find best combination and return it */ join->join_tab=stat; @@ -2367,7 +2386,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, keyparts != keyinfo->key_parts) j->type=JT_REF; /* Must read with repeat */ 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 of an LEFT JOIN. @@ -7333,36 +7352,39 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, if (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)", - tab->keys); - buff_ptr=strend(buff_ptr); + if (tab->use_quick == 2) + { + 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 - buff_ptr=strmov(buff_ptr,"; Using where"); - } - if (key_read) - buff_ptr= strmov(buff_ptr,"; Using index"); - if (table->reginfo.not_exists_optimize) - buff_ptr= strmov(buff_ptr,"; Not exists"); - if (need_tmp_table) - { - need_tmp_table=0; - buff_ptr= strmov(buff_ptr,"; Using temporary"); - } - if (need_order) - { - need_order=0; - buff_ptr= strmov(buff_ptr,"; Using filesort"); + if (key_read) + buff_ptr= strmov(buff_ptr,"; Using index"); + if (table->reginfo.not_exists_optimize) + buff_ptr= strmov(buff_ptr,"; Not exists"); + if (need_tmp_table) + { + need_tmp_table=0; + buff_ptr= strmov(buff_ptr,"; Using temporary"); + } + if (need_order) + { + need_order=0; + buff_ptr= strmov(buff_ptr,"; Using filesort"); + } + 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)); } - 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 used_tables|=table->map; if (result->send_data(item_list)) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 266bf8aefa9..c04b4871b4d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1771,12 +1771,9 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, /* We changed a temporary table */ if (error) { - /* - * The following function call will also free a - * new_table pointer. - * 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. + /* + The following function call will free the new_table pointer, + in close_temporary_table(), so we can safely directly jump to err */ close_temporary_table(thd,new_db,tmp_name); goto err; diff --git a/strings/Makefile.am b/strings/Makefile.am index c5f3d4e4b2a..89b5d8c03e9 100644 --- a/strings/Makefile.am +++ b/strings/Makefile.am @@ -40,6 +40,7 @@ endif libmystrings_a_SOURCES = $(ASRCS) $(CSRCS) noinst_PROGRAMS = conf_to_src +DISTCLEANFILES = ctype_autoconf.c # Default charset definitions EXTRA_DIST = ctype-big5.c ctype-czech.c ctype-euc_kr.c \ ctype-gb2312.c ctype-gbk.c ctype-sjis.c \ |