From 3ff74fe4a07b407166fb1b35ba48db0949e7d175 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 1 Nov 2004 12:08:44 +0200 Subject: [PATCH 01/21] mysqld.cc: Describe innodb_max_purge_lag Improve description of innodb_table_locks sql/mysqld.cc: Describe innodb_max_purge_lag Improve description of innodb_table_locks --- sql/mysqld.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d36b441ac9a..768acd77c27 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3702,12 +3702,12 @@ struct my_option my_long_options[] = "Percentage of dirty pages allowed in bufferpool", (gptr*) &srv_max_buf_pool_modified_pct, (gptr*) &srv_max_buf_pool_modified_pct, 0, GET_ULONG, REQUIRED_ARG, 90, 0, 100, 0, 0, 0}, {"innodb_max_purge_lag", OPT_INNODB_MAX_PURGE_LAG, - "", + "Desired maximum length of the purge queue (0 = no limit)", (gptr*) &srv_max_purge_lag, (gptr*) &srv_max_purge_lag, 0, GET_LONG, REQUIRED_ARG, 0, 0, ~0L, 0, 1L, 0}, {"innodb_table_locks", OPT_INNODB_TABLE_LOCKS, - "If Innodb should enforce LOCK TABLE", + "Enable InnoDB locking in LOCK TABLES", (gptr*) &global_system_variables.innodb_table_locks, (gptr*) &global_system_variables.innodb_table_locks, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, From e823c99731d37a682030c02d06dc47a178717d5b Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 1 Nov 2004 18:15:45 +0100 Subject: [PATCH 02/21] Ensure that a source distribution contains 'libmysql/libmysql.def' which is needed for Netware ports. --- libmysql/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am index fefed7f079c..3c4e98e5053 100644 --- a/libmysql/Makefile.am +++ b/libmysql/Makefile.am @@ -31,7 +31,7 @@ include $(srcdir)/Makefile.shared libmysqlclient_la_SOURCES = $(target_sources) libmysqlclient_la_LIBADD = $(target_libadd) libmysqlclient_la_LDFLAGS = $(target_ldflags) -EXTRA_DIST = Makefile.shared +EXTRA_DIST = Makefile.shared libmysql.def # This is called from the toplevel makefile link_sources: From 9c06c80dff5744ac0b1d214404c9d16f752e41bb Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 Nov 2004 13:21:11 +0200 Subject: [PATCH 03/21] ha_innodb.cc: Backport Jan's fix of the LOAD DATA INFILE REPLACE duplicate key error bug (Bug #5835) to 4.0 sql/ha_innodb.cc: Backport Jan's fix of the LOAD DATA INFILE REPLACE duplicate key error bug (Bug #5835) to 4.0 --- sql/ha_innodb.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index e747ff3210c..d57a9f73c91 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2285,7 +2285,9 @@ ha_innobase::write_row( if (error == DB_DUPLICATE_KEY && (user_thd->lex.sql_command == SQLCOM_REPLACE || user_thd->lex.sql_command - == SQLCOM_REPLACE_SELECT)) { + == SQLCOM_REPLACE_SELECT + || (user_thd->lex.sql_command == SQLCOM_LOAD + && user_thd->lex.duplicates == DUP_REPLACE))) { skip_auto_inc_decr= TRUE; } From 1d3f4a1a490656378131d66cb507145e5141fbdd Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 Nov 2004 17:53:25 -0700 Subject: [PATCH 04/21] Portability fixes to mysqld_safe for non-Linux systems. Fix FIND_PROC for Solaris test, and fix if @IS_LINUX@ test in mysqld_safe itself. configure.in: Portability fix for FIND_PROC setting; on Solaris (and probably others), 'ps -p $$' inside a shell script just returns 'sh' for command line, even though $0 contains the filename. So, use 'ps -fp $$' in the test (it shows the full command line, e.g., 'sh configure'). Leave the actual FIND_PROC command as-is, since mysqld itself is not a shell script. scripts/mysqld_safe.sh: Portability fix for mysqld_safe on non-Linux systems. A bogus use of 'if' and 'test' caused non-bash shells to enter a section meant to be run only on Linux systems. BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + configure.in | 2 +- scripts/mysqld_safe.sh | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 060586b6874..a716afb2392 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -139,6 +139,7 @@ tim@bitch.mysql.fi tim@black.box tim@hundin.mysql.fi tim@sand.box +tim@siva.hindu.god tim@threads.polyesthetic.msg tim@white.box tim@work.mysql.com diff --git a/configure.in b/configure.in index d4ede468435..97a59258ba8 100644 --- a/configure.in +++ b/configure.in @@ -444,7 +444,7 @@ if $PS p $$ 2> /dev/null | grep $0 > /dev/null then FIND_PROC="$PS p \$\$PID | grep mysqld > /dev/null" # Solaris -elif $PS -p $$ 2> /dev/null | grep $0 > /dev/null +elif $PS -fp $$ 2> /dev/null | grep $0 > /dev/null then FIND_PROC="$PS -p \$\$PID | grep mysqld > /dev/null" # BSD style diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index b9e7ce21f79..da7e06f6c05 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -315,7 +315,7 @@ do break fi - if test @IS_LINUX@ -a $KILL_MYSQLD -eq 1 + if @IS_LINUX@ && test $KILL_MYSQLD -eq 1 then # Test if one process was hanging. # This is only a fix for Linux (running as base 3 mysqld processes) From 0aa8d14149e6cd22f91dd60db99d56fb93b11b9c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 3 Nov 2004 14:56:48 +0200 Subject: [PATCH 05/21] InnoDB: fix bugs in the FOREIGN KEY parser (Bug #6340) innobase/dict/dict0dict.c: dict_scan_to(): skip quoted strings while scanning for the keyword dict_create_foreign_constraints_low(): allow quote immediately after CONSTRAINT --- innobase/dict/dict0dict.c | 55 +++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 5ca31ecd422..aa5bab210ef 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -604,7 +604,7 @@ dict_table_get_on_id( } /************************************************************************ -Looks for column n postion in the clustered index. */ +Looks for column n position in the clustered index. */ ulint dict_table_get_nth_col_pos( @@ -2140,8 +2140,8 @@ dict_foreign_add_to_cache( /************************************************************************* Scans from pointer onwards. Stops if is at the start of a copy of -'string' where characters are compared without case sensitivity. Stops -also at '\0'. */ +'string' where characters are compared without case sensitivity, and +only outside `` or "" quotes. Stops also at '\0'. */ static const char* dict_scan_to( @@ -2150,31 +2150,34 @@ dict_scan_to( const char* ptr, /* in: scan from */ const char* string) /* in: look for this */ { - ibool success; - ulint i; -loop: - if (*ptr == '\0') { - return(ptr); - } - - success = TRUE; - - for (i = 0; i < ut_strlen(string); i++) { - if (toupper((ulint)(ptr[i])) != toupper((ulint)(string[i]))) { - success = FALSE; + char quote = '\0'; + for (; *ptr; ptr++) { + if (*ptr == quote) { + /* Closing quote character: do not look for + starting quote or the keyword. */ + quote = '\0'; + } else if (quote) { + /* Within quotes: do nothing. */ + } else if (*ptr == '`' || *ptr == '"') { + /* Starting quote: remember the quote character. */ + quote = *ptr; + } else { + /* Outside quotes: look for the keyword. */ + ulint i; + for (i = 0; string[i]; i++) { + if (toupper((ulint)(ptr[i])) + != toupper((ulint)(string[i]))) { + goto nomatch; + } + } break; + nomatch: + ; } } - if (success) { - - return(ptr); - } - - ptr++; - - goto loop; + return(ptr); } /************************************************************************* @@ -2762,13 +2765,13 @@ loop: ut_a(success); - if (!isspace(*ptr)) { + if (!isspace(*ptr) && *ptr != '"' && *ptr != '`') { goto loop; } - do { + while (isspace(*ptr)) { ptr++; - } while (isspace(*ptr)); + } /* read constraint name unless got "CONSTRAINT FOREIGN" */ if (ptr != ptr2) { From d259ba4006a683e953486191d2851ee6c63f66b7 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 3 Nov 2004 17:59:03 +0000 Subject: [PATCH 06/21] Fix for bug #6387 "Queried timestamp values do not match the inserted value if server runs in time zone with leap seconds". Now in my_gmt_sec() function we take into account difference between our target and estimation in seconds part. mysql-test/Makefile.am: Added mysql-test/std_data/Moscow_leap reuired by new timezone3.test to source distribution. sql/time.cc: my_gmt_sec(): When comparing our target broken-down datetime t value and proper representation of our estimation *l_time we should take into account that they could differ in second part if we have time zone leap seconds. Also added comments about some assumptions used in this function. --- mysql-test/Makefile.am | 2 + .../r/have_moscow_leap_timezone.require | 2 + mysql-test/r/timezone3.result | 41 ++++++++++++ mysql-test/std_data/Moscow_leap | Bin 0 -> 991 bytes mysql-test/t/timezone3-master.opt | 1 + mysql-test/t/timezone3.test | 59 ++++++++++++++++++ sql/time.cc | 23 +++++-- 7 files changed, 123 insertions(+), 5 deletions(-) create mode 100644 mysql-test/r/have_moscow_leap_timezone.require create mode 100644 mysql-test/r/timezone3.result create mode 100644 mysql-test/std_data/Moscow_leap create mode 100644 mysql-test/t/timezone3-master.opt create mode 100644 mysql-test/t/timezone3.test diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index ba96c5947ba..8b0c096120a 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -32,6 +32,7 @@ dist-hook: $(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.require $(distdir)/r $(INSTALL_DATA) $(srcdir)/std_data/*.dat $(srcdir)/std_data/*.001 $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(distdir)/std_data + $(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(distdir)/std_data install-data-local: $(mkinstalldirs) \ @@ -50,6 +51,7 @@ install-data-local: $(INSTALL_DATA) $(srcdir)/std_data/*.dat $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.*001 $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(DESTDIR)$(testdir)/std_data + $(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(DESTDIR)$(testdir)/std_data SUFFIXES = .sh diff --git a/mysql-test/r/have_moscow_leap_timezone.require b/mysql-test/r/have_moscow_leap_timezone.require new file mode 100644 index 00000000000..f27452d7770 --- /dev/null +++ b/mysql-test/r/have_moscow_leap_timezone.require @@ -0,0 +1,2 @@ +from_unixtime(1072904422) +2004-01-01 00:00:00 diff --git a/mysql-test/r/timezone3.result b/mysql-test/r/timezone3.result new file mode 100644 index 00000000000..2135dd33511 --- /dev/null +++ b/mysql-test/r/timezone3.result @@ -0,0 +1,41 @@ +drop table if exists t1; +create table t1 (i int, c varchar(20)); +insert into t1 values +(unix_timestamp("2004-01-01 00:00:00"), "2004-01-01 00:00:00"); +insert into t1 values +(unix_timestamp("2004-03-28 01:59:59"), "2004-03-28 01:59:59"), +(unix_timestamp("2004-03-28 02:30:00"), "2004-03-28 02:30:00"), +(unix_timestamp("2004-03-28 03:00:00"), "2004-03-28 03:00:00"); +insert into t1 values +(unix_timestamp('2004-05-01 00:00:00'),'2004-05-01 00:00:00'); +insert into t1 values +(unix_timestamp('2004-10-31 01:00:00'),'2004-10-31 01:00:00'), +(unix_timestamp('2004-10-31 02:00:00'),'2004-10-31 02:00:00'), +(unix_timestamp('2004-10-31 02:59:59'),'2004-10-31 02:59:59'), +(unix_timestamp('2004-10-31 04:00:00'),'2004-10-31 04:00:00'), +(unix_timestamp('2004-10-31 02:59:59'),'2004-10-31 02:59:59'); +insert into t1 values +(unix_timestamp('1981-07-01 03:59:59'),'1981-07-01 03:59:59'), +(unix_timestamp('1981-07-01 04:00:00'),'1981-07-01 04:00:00'); +select i, from_unixtime(i), c from t1; +i from_unixtime(i) c +1072904422 2004-01-01 00:00:00 2004-01-01 00:00:00 +1080428421 2004-03-28 01:59:59 2004-03-28 01:59:59 +1080428422 2004-03-28 03:00:00 2004-03-28 02:30:00 +1080428422 2004-03-28 03:00:00 2004-03-28 03:00:00 +1083355222 2004-05-01 00:00:00 2004-05-01 00:00:00 +1099170022 2004-10-31 01:00:00 2004-10-31 01:00:00 +1099177222 2004-10-31 02:00:00 2004-10-31 02:00:00 +1099180821 2004-10-31 02:59:59 2004-10-31 02:59:59 +1099184422 2004-10-31 04:00:00 2004-10-31 04:00:00 +1099180821 2004-10-31 02:59:59 2004-10-31 02:59:59 +362793608 1981-07-01 03:59:59 1981-07-01 03:59:59 +362793610 1981-07-01 04:00:00 1981-07-01 04:00:00 +drop table t1; +create table t1 (ts timestamp); +insert into t1 values (19730101235900), (20040101235900); +select * from t1; +ts +19730101235900 +20040101235900 +drop table t1; diff --git a/mysql-test/std_data/Moscow_leap b/mysql-test/std_data/Moscow_leap new file mode 100644 index 0000000000000000000000000000000000000000..4994c005595dc06bc6d288e9ecea38307ce11c82 GIT binary patch literal 991 zcmWHE%1mRx1Ux_?5EcXCMkrfucD&q;xptps%+q==G4H!&$NZKEi3K-uITkXAX)Lr^ z=CDK{_rMZcqYX<%Gd3)>Wj?T6&NX1`63GNn_2oCkB<^^LbKH&+|HXe=;uYU*$=l98 zQfDULk>0c5kIb5he`M!0{gvw}{wrUT@>d}z^si!!+g~Lg^MA@V8vj&uB>$<(aQ#!` z{{3H_RlQ#Qt3-pwQ}GF!75gV>UbzsUb!4-n_Le)1I!n$r=}y_#q}Q^(S-)gKvq8$l zX2aOMEJj5$Sd4AwvzP=`v6{*@vYHviu$ui%X0wp4XtTKM%4YdHs?BPzI-B)vn>L$e z&TY24<=X7pRNL%lGqgFRv9~$4$g(-PzHD<&{?F#3db-Wk`5~Jd>)JMV<-=_5?@qCK zGB0KGJhz6;>v21q_qskdpEHZweESO6{MNL#`R4_(1@xr11%~If1?70Q1)B%7h4^T< zg^C-sh3W9Ng?$%kixAafi@5f!E%GZ5Thz82ZP8cWvBk{)$`-rj0$W`Db+-5^o7fWK zcd{kco@-08pUsvWyP+*bzLqW3c2Zj!$IP~L*^;*O7u9VUf5X}`PsFxm-L+`TUSZ#s zb1alCw?nZlZ<#q;eg<<}L7OC7VW0wAQR;8DVnZgj64$$Ir260> zt>VH8w#s*V+p0Enu~na&-&QkoSzGP8#&46d#rKnxUM*#tJ2k#)%%MxX^u>}~Q*K$@8| zJ(w9tvv7N~wE$^WUTyAHAkD_lW6uVp*#+JfwF7Amp>xZCE@I#moqwtmNOOrd{Nn=B z+>%L#-9Va0R`nGqd+{pXdJ1$i1E1==xqU#IU%mb!KadvC3ivt!NDJy1X#)MhAfzW8 nGYLow8$4GL2GSzNJ3OWUX;HHt0iX}T*%U}IFfalEm;ogKHtY+x literal 0 HcmV?d00001 diff --git a/mysql-test/t/timezone3-master.opt b/mysql-test/t/timezone3-master.opt new file mode 100644 index 00000000000..6910e6e6e8d --- /dev/null +++ b/mysql-test/t/timezone3-master.opt @@ -0,0 +1 @@ +--timezone=:$MYSQL_TEST_DIR/std_data/Moscow_leap diff --git a/mysql-test/t/timezone3.test b/mysql-test/t/timezone3.test new file mode 100644 index 00000000000..8910783cd85 --- /dev/null +++ b/mysql-test/t/timezone3.test @@ -0,0 +1,59 @@ +# +# Test of handling time zone with leap seconds. +# +# This test should be run with TZ=:$MYSQL_TEST_DIR/std_data/Moscow_leap +# This implies that this test should be run only on systems that interpret +# characters after colon in TZ variable as path to zoneinfo file. +# +# Check that we have successfully set time zone with leap seconds. +--require r/have_moscow_leap_timezone.require +disable_query_log; +select from_unixtime(1072904422); +enable_query_log; + +# Initial clean-up +--disable_warnings +drop table if exists t1; +--enable_warnings + +# +# Let us check behavior of conversion from broken-down representation +# to time_t representation, for normal, non-existent and ambigious dates +# (This check is similar to the one in timezone2.test in 4.1) +# +create table t1 (i int, c varchar(20)); +# Normal value without DST +insert into t1 values + (unix_timestamp("2004-01-01 00:00:00"), "2004-01-01 00:00:00"); +# Values around and in spring time-gap +insert into t1 values + (unix_timestamp("2004-03-28 01:59:59"), "2004-03-28 01:59:59"), + (unix_timestamp("2004-03-28 02:30:00"), "2004-03-28 02:30:00"), + (unix_timestamp("2004-03-28 03:00:00"), "2004-03-28 03:00:00"); +# Normal value with DST +insert into t1 values + (unix_timestamp('2004-05-01 00:00:00'),'2004-05-01 00:00:00'); +# Ambiguos values (also check for determenism) +insert into t1 values + (unix_timestamp('2004-10-31 01:00:00'),'2004-10-31 01:00:00'), + (unix_timestamp('2004-10-31 02:00:00'),'2004-10-31 02:00:00'), + (unix_timestamp('2004-10-31 02:59:59'),'2004-10-31 02:59:59'), + (unix_timestamp('2004-10-31 04:00:00'),'2004-10-31 04:00:00'), + (unix_timestamp('2004-10-31 02:59:59'),'2004-10-31 02:59:59'); +# Test of leap +insert into t1 values + (unix_timestamp('1981-07-01 03:59:59'),'1981-07-01 03:59:59'), + (unix_timestamp('1981-07-01 04:00:00'),'1981-07-01 04:00:00'); + +select i, from_unixtime(i), c from t1; +drop table t1; + +# +# Test for bug #6387 "Queried timestamp values do not match the +# inserted". my_gmt_sec() function was not working properly if we +# had time zone with leap seconds +# +create table t1 (ts timestamp); +insert into t1 values (19730101235900), (20040101235900); +select * from t1; +drop table t1; diff --git a/sql/time.cc b/sql/time.cc index 0363d764100..38670db054f 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -81,6 +81,10 @@ long my_gmt_sec(TIME *t, long *my_timezone) I couldn't come up with a better way to get a repeatable result :( We can't use mktime() as it's buggy on many platforms and not thread safe. + + Note: this code assumes that our time_t estimation is not too far away + from real value (we assume that localtime_r(tmp) will return something + within 24 hrs from t) which is probably true for all current time zones. */ tmp=(time_t) (((calc_daynr((uint) t->year,(uint) t->month,(uint) t->day) - (long) days_at_timestart)*86400L + (long) t->hour*3600L + @@ -93,7 +97,8 @@ long my_gmt_sec(TIME *t, long *my_timezone) for (loop=0; loop < 2 && (t->hour != (uint) l_time->tm_hour || - t->minute != (uint) l_time->tm_min); + t->minute != (uint) l_time->tm_min || + t->second != (uint) l_time->tm_sec); loop++) { /* One check should be enough ? */ /* Get difference in days */ @@ -103,15 +108,22 @@ long my_gmt_sec(TIME *t, long *my_timezone) else if (days > 1) days= -1; diff=(3600L*(long) (days*24+((int) t->hour - (int) l_time->tm_hour)) + - (long) (60*((int) t->minute - (int) l_time->tm_min))); + (long) (60*((int) t->minute - (int) l_time->tm_min)) + + (long) ((int) t->second - (int) l_time->tm_sec)); current_timezone+= diff+3600; // Compensate for -3600 above tmp+= (time_t) diff; localtime_r(&tmp,&tm_tmp); l_time=&tm_tmp; } /* - Fix that if we are in the not existing daylight saving time hour - we move the start of the next real hour + Fix that if we are in the non existing daylight saving time hour + we move the start of the next real hour. + + This code doesn't handle such exotical thing as time-gaps whose length + is more than one hour or non-integer (latter can theoretically happen + if one of seconds will be removed due leap correction, or because of + general time correction like it happened for Africa/Monrovia time zone + in year 1972). */ if (loop == 2 && t->hour != (uint) l_time->tm_hour) { @@ -121,7 +133,8 @@ long my_gmt_sec(TIME *t, long *my_timezone) else if (days > 1) days= -1; diff=(3600L*(long) (days*24+((int) t->hour - (int) l_time->tm_hour))+ - (long) (60*((int) t->minute - (int) l_time->tm_min))); + (long) (60*((int) t->minute - (int) l_time->tm_min)) + + (long) ((int) t->second - (int) l_time->tm_sec)); if (diff == 3600) tmp+=3600 - t->minute*60 - t->second; // Move to next hour else if (diff == -3600) From 0dd1ab1abbf81fef1ab9ebf43a06a1b0d0129487 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Nov 2004 11:18:12 +0100 Subject: [PATCH 07/21] The files stored in "Docs/Images" within the "mysqldocs" BK tree must be included in the source tar-ball for distribution. This is done by using the "DISTFILES" macro in a new "Docs/Images/Makefile". As the source BK tree does not contain these files, they are copied from the "mysqldocs" tree at release build time. This changeset relies on "bk commit - mysqldoc tree (joerg:1.2276)" of today. Build-tools/Bootstrap: Copy the relevant files with "Docs/Images" from the "mysqldocs" BK tree into the build tree, ensuring that the "Makefile*" from the source BK tree are removed before. Docs/Images/Makefile.am: This dummy file is only needed to satisfy the Makefile hierarchy, at release build time it will be replaced by its counterpart from the "mysqldocs" BK tree. Docs/Makefile.am: Include the new "Docs/Images/Makefile" in the Makefile hierarchy. configure.in: Ensure that the autotools will handle the new "Docs/Images/Makefile.am". --- Build-tools/Bootstrap | 4 ++++ Docs/Images/Makefile.am | 35 +++++++++++++++++++++++++++++++++++ Docs/Makefile.am | 2 ++ configure.in | 2 +- 4 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 Docs/Images/Makefile.am diff --git a/Build-tools/Bootstrap b/Build-tools/Bootstrap index 8cad093bc5f..e21179fe78c 100755 --- a/Build-tools/Bootstrap +++ b/Build-tools/Bootstrap @@ -288,6 +288,10 @@ unless ($opt_skip_manual) system ("bk cat $opt_docdir/Docs/$file.texi > $target_dir/Docs/$file.texi") == 0 or &abort("Could not update $file.texi in $target_dir/Docs/!"); } + system ("rm $target_dir/Docs/Images/Makefile*") == 0 + or &abort("Could not remove Makefiles in $target_dir/Docs/Images/!"); + system ("cp $opt_docdir/Docs/Images/*.* $target_dir/Docs/Images") == 0 + or &abort("Could not copy image files in $target_dir/Docs/Images/!"); } # diff --git a/Docs/Images/Makefile.am b/Docs/Images/Makefile.am new file mode 100644 index 00000000000..b57d701d8a0 --- /dev/null +++ b/Docs/Images/Makefile.am @@ -0,0 +1,35 @@ +# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free +# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +# MA 02111-1307, USA + +## Process this file with automake to create Makefile.in + +# This is a dummy file to satisfy the hierarchy of Makefiles. +# When a release is built, the true Makefile will be copied +# together with the "real" files in this directory. + +EXTRA_DIST = + +# Nothing to create in this dummy directory. +all: + : + +# Nothing to cleanup in this dummy directory. +clean: + : + +# Don't update the files from bitkeeper +%::SCCS/s.% diff --git a/Docs/Makefile.am b/Docs/Makefile.am index a4e8e14a38d..e53ea195d94 100644 --- a/Docs/Makefile.am +++ b/Docs/Makefile.am @@ -24,6 +24,8 @@ BUILT_SOURCES = $(targets) manual_toc.html include.texi EXTRA_DIST = $(noinst_SCRIPTS) $(BUILT_SOURCES) mysqld_error.txt \ INSTALL-BINARY reservedwords.texi +SUBDIRS = Images + all: $(targets) txt_files txt_files: ../INSTALL-SOURCE ../COPYING ../EXCEPTIONS-CLIENT \ diff --git a/configure.in b/configure.in index d4ede468435..0c520ca8980 100644 --- a/configure.in +++ b/configure.in @@ -2711,7 +2711,7 @@ AC_OUTPUT(Makefile extra/Makefile mysys/Makefile isam/Makefile dnl pstack/Makefile pstack/aout/Makefile sql/Makefile sql/share/Makefile dnl merge/Makefile dbug/Makefile scripts/Makefile dnl include/Makefile sql-bench/Makefile tools/Makefile dnl - tests/Makefile Docs/Makefile support-files/Makefile dnl + tests/Makefile Docs/Makefile Docs/Images/Makefile support-files/Makefile dnl support-files/MacOSX/Makefile mysql-test/Makefile dnl netware/Makefile dnl include/mysql_version.h dnl From e30bd1e48d8ef68a92dd8443611b1e3d8e356c7a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Nov 2004 19:19:23 +0100 Subject: [PATCH 08/21] Fix for BUG##5714 "Insert into MyISAM table and select ... for update]": the fact that the transaction log is empty does not mean we're not in a transaction (it could be BEGIN; SELECT * FOR UPDATE FROM ibtable: then we don't want to commit now, even if the statement is a MyISAM update). With a testcase. mysql-test/r/mix_innodb_myisam_binlog.result: result update mysql-test/t/mix_innodb_myisam_binlog.test: test update for a new bug sql/log.cc: The fact that the transaction log is empty does not mean we're not in a transaction (it could be BEGIN; SELECT * FOR UPDATE: then we don't want to commit now). --- mysql-test/r/mix_innodb_myisam_binlog.result | 21 ++++++++++++ .../t/mix_innodb_myisam_binlog-master.opt | 1 + mysql-test/t/mix_innodb_myisam_binlog.test | 32 +++++++++++++++++++ sql/log.cc | 3 +- 4 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 mysql-test/t/mix_innodb_myisam_binlog-master.opt diff --git a/mysql-test/r/mix_innodb_myisam_binlog.result b/mysql-test/r/mix_innodb_myisam_binlog.result index 7b266544c92..93a647f673c 100644 --- a/mysql-test/r/mix_innodb_myisam_binlog.result +++ b/mysql-test/r/mix_innodb_myisam_binlog.result @@ -177,4 +177,25 @@ master-bin.001 79 Query 1 79 use `test`; BEGIN master-bin.001 119 Query 1 79 use `test`; insert into t1 values(16) master-bin.001 179 Query 1 79 use `test`; insert into t1 values(18) master-bin.001 239 Query 1 239 use `test`; COMMIT +delete from t1; +delete from t2; +alter table t2 type=MyISAM; +insert into t1 values (1); +begin; +select * from t1 for update; +a +1 +select (@before:=unix_timestamp())*0; +(@before:=unix_timestamp())*0 +0 +begin; + select * from t1 for update; +insert into t2 values (20); +Lock wait timeout exceeded; Try restarting transaction +select (@after:=unix_timestamp())*0; +(@after:=unix_timestamp())*0 +0 +select (@after-@before) >= 2; +(@after-@before) >= 2 +1 drop table t1,t2; diff --git a/mysql-test/t/mix_innodb_myisam_binlog-master.opt b/mysql-test/t/mix_innodb_myisam_binlog-master.opt new file mode 100644 index 00000000000..cb48f1aaf60 --- /dev/null +++ b/mysql-test/t/mix_innodb_myisam_binlog-master.opt @@ -0,0 +1 @@ +--loose-innodb_lock_wait_timeout=2 diff --git a/mysql-test/t/mix_innodb_myisam_binlog.test b/mysql-test/t/mix_innodb_myisam_binlog.test index be45c2c3133..5f3b778c61a 100644 --- a/mysql-test/t/mix_innodb_myisam_binlog.test +++ b/mysql-test/t/mix_innodb_myisam_binlog.test @@ -175,4 +175,36 @@ select a from t1 order by a; # check that savepoints work :) show binlog events from 79; +# Test for BUG#5714, where a MyISAM update in the transaction used to +# release row-level locks in InnoDB + +connect (con3,localhost,root,,); + +connection con3; +delete from t1; +delete from t2; +--disable_warnings +alter table t2 type=MyISAM; +--enable_warnings +insert into t1 values (1); +begin; +select * from t1 for update; + +connection con2; +select (@before:=unix_timestamp())*0; # always give repeatable output +begin; +send select * from t1 for update; + +connection con3; +insert into t2 values (20); + +connection con2; +--error 1205 +reap; +select (@after:=unix_timestamp())*0; # always give repeatable output +# verify that innodb_lock_wait_timeout was exceeded. When there was +# the bug, the reap would return immediately after the insert into t2. +select (@after-@before) >= 2; + +# cleanup drop table t1,t2; diff --git a/sql/log.cc b/sql/log.cc index fee77b38f21..aa5d9d8753b 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1254,7 +1254,8 @@ bool MYSQL_LOG::write(Log_event* event_info) if (flush_io_cache(file)) goto err; - if (opt_using_transactions && !my_b_tell(&thd->transaction.trans_log)) + if (opt_using_transactions && + !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { /* LOAD DATA INFILE in AUTOCOMMIT=1 mode writes to the binlog From 1ba0ad70765e0f1f3d5ec0109f89165acb7dd262 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 5 Nov 2004 09:00:04 +0400 Subject: [PATCH 09/21] libmysql.def, libmysql.c: Clean-ups libmysql/libmysql.c: Clean-ups libmysql/libmysql.def: Clean-ups , --- libmysql/libmysql.c | 2 +- libmysql/libmysql.def | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 9257bf0efd0..2257ae739eb 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -3170,7 +3170,7 @@ void my_net_local_init(NET *net) encoded string, not including the terminating null character. */ -unsigned long +ulong STDCALL mysql_hex_string(char *to, const char *from, unsigned long length) { char *to0= to; diff --git a/libmysql/libmysql.def b/libmysql/libmysql.def index b0433a34cb3..51a4edda5aa 100644 --- a/libmysql/libmysql.def +++ b/libmysql/libmysql.def @@ -11,6 +11,7 @@ EXPORTS mysql_errno mysql_error mysql_escape_string + mysql_hex_string mysql_fetch_field mysql_fetch_field_direct mysql_fetch_fields From 2f2eceacb18d348332395f82845e50fe5db79e99 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 5 Nov 2004 09:07:07 +0400 Subject: [PATCH 10/21] libmysql.c: After-merge clean-up libmysql/libmysql.c: After-merge clean-up --- libmysql/libmysql.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 2250111f5a0..47f28e296b2 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -3173,7 +3173,8 @@ void my_net_local_init(NET *net) trailing '. The caller must supply whichever of those is desired. */ -ulong mysql_hex_string(char *to, const char *from, ulong length) +ulong STDCALL +mysql_hex_string(char *to, const char *from, ulong length) { char *to0= to; const char *end; From 7d0a67d6285e60885f58a3bf2998e9b3d84bbc94 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 5 Nov 2004 09:23:53 +0400 Subject: [PATCH 11/21] client_priv.h: Backport --hex-blob to 4.0 client/client_priv.h: Backport --hex-blob to 4.0 --- client/client_priv.h | 3 ++- client/mysqldump.c | 56 ++++++++++++++++++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/client/client_priv.h b/client/client_priv.h index 5029f219494..016c9e5ee80 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -38,4 +38,5 @@ enum options_client { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH, OPT_SSL_CIPHER, OPT_SHUTDOWN_TIMEOUT, OPT_LOCAL_INFILE, OPT_DELETE_MASTER_LOGS, - OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION, OPT_FRM }; + OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION, OPT_FRM, + OPT_HEXBLOB }; diff --git a/client/mysqldump.c b/client/mysqldump.c index 49822f0bee0..a78eee3794a 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -78,7 +78,8 @@ static my_bool verbose=0,tFlag=0,cFlag=0,dFlag=0,quick=0, extended_insert = 0, opt_alldbs=0,opt_create_db=0,opt_first_slave=0, opt_autocommit=0,opt_master_data,opt_disable_keys=0,opt_xml=0, opt_delete_master_logs=0, tty_password=0, - opt_single_transaction=0, opt_comments= 0; + opt_single_transaction=0, opt_comments= 0, + opt_hex_blob; static ulong opt_max_allowed_packet, opt_net_buffer_length; static MYSQL mysql_connection,*sock=0; static char insert_pat[12 * 1024],*opt_password=0,*current_user=0, @@ -248,6 +249,8 @@ static struct my_option my_long_options[] = {"comments", 'i', "Write additional information.", (gptr*) &opt_comments, (gptr*) &opt_comments, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, + {"hex-blob", OPT_HEXBLOB, "Dump BLOBs in HEX.", + (gptr*) &opt_hex_blob, (gptr*) &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -1104,6 +1107,7 @@ static void dumpTable(uint numFields, char *table) for (i = 0; i < mysql_num_fields(res); i++) { + int is_blob; if (!(field = mysql_fetch_field(res))) { sprintf(query,"%s: Not enough fields from table %s! Aborting.\n", @@ -1112,6 +1116,13 @@ static void dumpTable(uint numFields, char *table) error= EX_CONSCHECK; goto err; } + + is_blob= (opt_hex_blob && (field->flags & BINARY_FLAG) && + (field->type == FIELD_TYPE_STRING || + field->type == FIELD_TYPE_BLOB || + field->type == FIELD_TYPE_LONG_BLOB || + field->type == FIELD_TYPE_MEDIUM_BLOB || + field->type == FIELD_TYPE_TINY_BLOB)) ? 1 : 0; if (extended_insert) { ulong length = lengths[i]; @@ -1126,18 +1137,37 @@ static void dumpTable(uint numFields, char *table) { if (!IS_NUM_FIELD(field)) { + /* + "length * 2 + 2" is OK for both HEX and non-HEX modes: + - In HEX mode we need exactly 2 bytes per character + plus 2 bytes for '0x' prefix. + - In non-HEX mode we need up to 2 bytes per character, + plus 2 bytes for leading and trailing '\'' characters. + */ if (dynstr_realloc(&extended_row,length * 2+2)) { fputs("Aborting dump (out of memory)",stderr); error= EX_EOM; goto err; } - dynstr_append(&extended_row,"\'"); - extended_row.length += + if (opt_hex_blob && is_blob) + { + dynstr_append(&extended_row, "0x"); + extended_row.length+= mysql_hex_string(extended_row.str + + extended_row.length, + row[i], length); + extended_row.str[extended_row.length]= '\0'; + } + else + { + dynstr_append(&extended_row,"\'"); + extended_row.length += mysql_real_escape_string(&mysql_connection, - &extended_row.str[extended_row.length],row[i],length); - extended_row.str[extended_row.length]='\0'; - dynstr_append(&extended_row,"\'"); + &extended_row.str[extended_row.length], + row[i],length); + extended_row.str[extended_row.length]='\0'; + dynstr_append(&extended_row,"\'"); + } } else { @@ -1180,7 +1210,19 @@ static void dumpTable(uint numFields, char *table) if (opt_xml) print_quoted_xml(md_result_file, field->name, row[i], lengths[i]); - else + else if (opt_hex_blob && is_blob) + { /* sakaik got this idea. */ + ulong counter; + char xx[4]; + unsigned char *ptr= row[i]; + fputs("0x", md_result_file); + for (counter = 0; counter < lengths[i]; counter++) + { + sprintf(xx, "%02X", ptr[counter]); + fputs(xx, md_result_file); + } + } + else unescape(md_result_file, row[i], lengths[i]); } else From 8d5703a3c788f73d8a9a964a444b0c52f4058096 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 5 Nov 2004 15:22:03 +0100 Subject: [PATCH 12/21] Change "Bootstrap" so that it will not fail on BK source trees of other versions; this is important because this 4.0 "Bootstrap" is the one generally used on host "build". Build-tools/Bootstrap: If the source tree does not contain any "Docs/Images/Makefile*" (due to an error, or because it is not yet prepared to contain the Images in the source tar-ball), a plain "rm" will fail and so cause "Bootstrap" to fail. (This has happened ...) Prevent this danger by using "rm -f". --- Build-tools/Bootstrap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Build-tools/Bootstrap b/Build-tools/Bootstrap index e21179fe78c..a7d347ba32f 100755 --- a/Build-tools/Bootstrap +++ b/Build-tools/Bootstrap @@ -288,7 +288,7 @@ unless ($opt_skip_manual) system ("bk cat $opt_docdir/Docs/$file.texi > $target_dir/Docs/$file.texi") == 0 or &abort("Could not update $file.texi in $target_dir/Docs/!"); } - system ("rm $target_dir/Docs/Images/Makefile*") == 0 + system ("rm -f $target_dir/Docs/Images/Makefile*") == 0 or &abort("Could not remove Makefiles in $target_dir/Docs/Images/!"); system ("cp $opt_docdir/Docs/Images/*.* $target_dir/Docs/Images") == 0 or &abort("Could not copy image files in $target_dir/Docs/Images/!"); From 3170761e02585ee4675e9da4427de28f43a74c1a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 5 Nov 2004 20:33:56 +0400 Subject: [PATCH 13/21] mysqldump.c: Dump VARCHAR(n) BINARY in HEX if --hex-blob too. client/mysqldump.c: Dump VARCHAR(n) BINARY in HEX if --hex-blob too. --- client/mysqldump.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/mysqldump.c b/client/mysqldump.c index a78eee3794a..0e840512ba0 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1119,6 +1119,7 @@ static void dumpTable(uint numFields, char *table) is_blob= (opt_hex_blob && (field->flags & BINARY_FLAG) && (field->type == FIELD_TYPE_STRING || + field->type == FIELD_TYPE_VAR_STRING || field->type == FIELD_TYPE_BLOB || field->type == FIELD_TYPE_LONG_BLOB || field->type == FIELD_TYPE_MEDIUM_BLOB || From 57ec8b2e48cf2bc5b870341a77e0fd5da482c62d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 5 Nov 2004 18:59:19 +0200 Subject: [PATCH 14/21] Changed default.c so that it now checks for my.ini and then my.cnf from the default directories. BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + mysys/default.c | 89 ++++++++++++++++++++++------------------ 2 files changed, 51 insertions(+), 39 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index a716afb2392..01b9190b044 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -47,6 +47,7 @@ hf@genie.(none) igor@hundin.mysql.fi igor@rurik.mysql.com ingo@mysql.com +jani@a193-229-222-105.elisa-laajakaista.fi jani@a80-186-24-72.elisa-laajakaista.fi jani@a80-186-41-201.elisa-laajakaista.fi jani@dsl-jkl1657.dial.inet.fi diff --git a/mysys/default.c b/mysys/default.c index 81290322223..ed7f4b47097 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -60,11 +60,7 @@ DATADIR, NullS, }; -#define default_ext ".cnf" /* extension for config file */ -#ifdef __WIN__ -#include -#define windows_ext ".ini" -#endif +static const char *f_extensions[]= { ".ini", ".cnf", 0 }; static int search_default_file(DYNAMIC_ARRAY *args,MEM_ROOT *alloc, const char *dir, const char *config_file, @@ -115,7 +111,8 @@ int load_defaults(const char *conf_file, const char **groups, uint args_used=0; int error= 0; MEM_ROOT alloc; - char *ptr,**res; + char *ptr, **res, **ext; + DBUG_ENTER("load_defaults"); init_alloc_root(&alloc,512,0); @@ -169,38 +166,43 @@ int load_defaults(const char *conf_file, const char **groups, } else if (dirname_length(conf_file)) { - if ((error= search_default_file(&args, &alloc, NullS, conf_file, - default_ext, &group)) < 0) - goto err; + for (ext= (char**) f_extensions; *ext; *ext++) + if ((error= search_default_file(&args, &alloc, NullS, conf_file, + *ext, &group)) < 0) + goto err; } else { #ifdef __WIN__ char system_dir[FN_REFLEN]; GetWindowsDirectory(system_dir,sizeof(system_dir)); - if ((search_default_file(&args, &alloc, system_dir, conf_file, - windows_ext, &group))) - goto err; + for (ext= (char**) f_extensions; *ext; *ext++) + if ((search_default_file(&args, &alloc, system_dir, conf_file, + *ext, &group))) + goto err; #endif #if defined(__EMX__) || defined(OS2) - if (getenv("ETC") && - (search_default_file(&args, &alloc, getenv("ETC"), conf_file, - default_ext, &group)) < 0) - goto err; + for (ext= (char**) f_extensions; *ext; *ext++) + if (getenv("ETC") && + (search_default_file(&args, &alloc, getenv("ETC"), conf_file, + *ext, &group)) < 0) + goto err; #endif for (dirs=default_directories ; *dirs; dirs++) { if (**dirs) { - if (search_default_file(&args, &alloc, *dirs, conf_file, - default_ext, &group) < 0) - goto err; + for (ext= (char**) f_extensions; *ext; *ext++) + if (search_default_file(&args, &alloc, *dirs, conf_file, + *ext, &group) < 0) + goto err; } else if (defaults_extra_file) { - if (search_default_file(&args, &alloc, NullS, defaults_extra_file, - default_ext, &group) < 0) - goto err; /* Fatal error */ + for (ext= (char**) f_extensions; ext; ext++) + if (search_default_file(&args, &alloc, NullS, defaults_extra_file, + *ext, &group) < 0) + goto err; /* Fatal error */ } } } @@ -478,8 +480,9 @@ void print_defaults(const char *conf_file, const char **groups) #ifdef __WIN__ bool have_ext=fn_ext(conf_file)[0] != 0; #endif - char name[FN_REFLEN]; + char name[FN_REFLEN], **ext; const char **dirs; + puts("\nDefault options are read from the following files in the given order:"); if (dirname_length(conf_file)) @@ -488,27 +491,35 @@ void print_defaults(const char *conf_file, const char **groups) { #ifdef __WIN__ GetWindowsDirectory(name,sizeof(name)); - printf("%s\\%s%s ",name,conf_file,have_ext ? "" : windows_ext); + if (have_ext) + for (ext= (char**) f_extensions; *ext; *ext++) + printf("%s\\%s%s ", name, conf_file, *ext); + else + printf("%s\\%s ", name, conf_file); #endif #if defined(__EMX__) || defined(OS2) - if (getenv("ETC")) - printf("%s\\%s%s ", getenv("ETC"), conf_file, default_ext); + for (ext= (char**) f_extensions; *ext; *ext++) + if (getenv("ETC")) + printf("%s\\%s%s ", getenv("ETC"), conf_file, *ext); #endif for (dirs=default_directories ; *dirs; dirs++) { - const char *pos; - char *end; - if (**dirs) - pos= *dirs; - else if (defaults_extra_file) - pos= defaults_extra_file; - else - continue; - end=convert_dirname(name, pos, NullS); - if (name[0] == FN_HOMELIB) /* Add . to filenames in home */ - *end++='.'; - strxmov(end,conf_file,default_ext," ",NullS); - fputs(name,stdout); + for (ext= (char**) f_extensions; *ext; *ext++) + { + const char *pos; + char *end; + if (**dirs) + pos= *dirs; + else if (defaults_extra_file) + pos= defaults_extra_file; + else + continue; + end= convert_dirname(name, pos, NullS); + if (name[0] == FN_HOMELIB) /* Add . to filenames in home */ + *end++='.'; + strxmov(end, conf_file, *ext, " ", NullS); + fputs(name,stdout); + } } puts(""); } From 442b2d89b1992dd727eae1c59c16499d052ceb54 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 5 Nov 2004 23:58:30 +0200 Subject: [PATCH 15/21] Fixed a typo that caused segmentation fault when using --defaults-extra-file option. --- mysys/default.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/default.c b/mysys/default.c index ed7f4b47097..416de09b661 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -199,7 +199,7 @@ int load_defaults(const char *conf_file, const char **groups, } else if (defaults_extra_file) { - for (ext= (char**) f_extensions; ext; ext++) + for (ext= (char**) f_extensions; *ext; *ext++) if (search_default_file(&args, &alloc, NullS, defaults_extra_file, *ext, &group) < 0) goto err; /* Fatal error */ From 01c80f55884e1695b4f2e16da9a2c10f9e9c9cbc Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 9 Nov 2004 00:19:39 +0400 Subject: [PATCH 16/21] mysql.h: Adding a prototype for the new function. include/mysql.h: Adding a prototype for the new function. --- include/mysql.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/mysql.h b/include/mysql.h index 8abeb86e32a..08ea2da2e58 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -392,6 +392,8 @@ unsigned long * STDCALL mysql_fetch_lengths(MYSQL_RES *result); MYSQL_FIELD * STDCALL mysql_fetch_field(MYSQL_RES *result); unsigned long STDCALL mysql_escape_string(char *to,const char *from, unsigned long from_length); +unsigned long STDCALL mysql_hex_string(char *to,const char *from, + unsigned long from_length); unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql, char *to,const char *from, unsigned long length); From d3605294f6cb7e31a691bb29427e0da6b51869d9 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 9 Nov 2004 11:03:02 -0600 Subject: [PATCH 17/21] Alphabetize some out-of-order options in option structure. Revise the --hex-blob help message string. (This will need revising after merge to 4.1, too, but the CHAR BINARY and VARCHAR BINARY data types will be BINARY and VARBINRY.) --- client/mysqldump.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 0e840512ba0..58d601654a4 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -114,6 +114,9 @@ static struct my_option my_long_options[] = {"character-sets-dir", OPT_CHARSETS_DIR, "Directory where character sets are", (gptr*) &charsets_dir, (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"comments", 'i', "Write additional information.", + (gptr*) &opt_comments, (gptr*) &opt_comments, 0, GET_BOOL, NO_ARG, + 1, 0, 0, 0, 0, 0}, {"complete-insert", 'c', "Use complete insert statements.", (gptr*) &cFlag, (gptr*) &cFlag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"compress", 'C', "Use compression in server/client protocol.", @@ -166,6 +169,9 @@ static struct my_option my_long_options[] = 0, 0, 0, 0, 0, 0}, {"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"hex-blob", OPT_HEXBLOB, "Dump binary strings (CHAR BINARY, " + "VARCHAR BINARY, BLOB) in hexadecimal format.", + (gptr*) &opt_hex_blob, (gptr*) &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"host", 'h', "Connect to host.", (gptr*) ¤t_host, (gptr*) ¤t_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"lines-terminated-by", OPT_LTB, "Lines in the i.file are terminated by ...", @@ -180,10 +186,6 @@ static struct my_option my_long_options[] = "Wrap tables with autocommit/commit statements.", (gptr*) &opt_autocommit, (gptr*) &opt_autocommit, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"single-transaction", OPT_TRANSACTION, - "Dump all tables in single transaction to get consistent snapshot. Mutually exclusive with --lock-tables.", - (gptr*) &opt_single_transaction, (gptr*) &opt_single_transaction, 0, GET_BOOL, NO_ARG, - 0, 0, 0, 0, 0, 0}, {"no-create-db", 'n', "'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given.}", (gptr*) &opt_create_db, (gptr*) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0, @@ -192,9 +194,6 @@ static struct my_option my_long_options[] = (gptr*) &tFlag, (gptr*) &tFlag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"no-data", 'd', "No row information.", (gptr*) &dFlag, (gptr*) &dFlag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"set-variable", 'O', - "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.", - 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"opt", OPT_OPTIMIZE, "Same as --add-drop-table --add-locks --all --quick --extended-insert --lock-tables --disable-keys", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -216,6 +215,13 @@ static struct my_option my_long_options[] = {"result-file", 'r', "Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\\n' from being converted to '\\r\\n' (carriage return + line feed).", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"set-variable", 'O', + "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"single-transaction", OPT_TRANSACTION, + "Dump all tables in single transaction to get consistent snapshot. Mutually exclusive with --lock-tables.", + (gptr*) &opt_single_transaction, (gptr*) &opt_single_transaction, 0, GET_BOOL, NO_ARG, + 0, 0, 0, 0, 0, 0}, {"socket", 'S', "Socket file to use for connection.", (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -246,11 +252,6 @@ static struct my_option my_long_options[] = (gptr*) &opt_net_buffer_length, (gptr*) &opt_net_buffer_length, 0, GET_ULONG, REQUIRED_ARG, 1024*1024L-1025, 4096, 16*1024L*1024L, MALLOC_OVERHEAD-1024, 1024, 0}, - {"comments", 'i', "Write additional information.", - (gptr*) &opt_comments, (gptr*) &opt_comments, 0, GET_BOOL, NO_ARG, - 1, 0, 0, 0, 0, 0}, - {"hex-blob", OPT_HEXBLOB, "Dump BLOBs in HEX.", - (gptr*) &opt_hex_blob, (gptr*) &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; From 12fbc41f5f76b84cf6b7f174f0b9d27e187d104b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 10 Nov 2004 15:07:55 +0100 Subject: [PATCH 18/21] Fix for BUG#6522 "Replication fails due to a rolled back transaction in the binlog" When we are writing a transaction to the binlog, we log BEGIN/COMMIT with zero error code. Example: all statements of trans succeeded, connection lost and so implicit rollback: we don't want ER_NET* errors to be logged in the BEGIN/ROLLBACK events, while statement events have 0. If there was really a serious error code, it's already in the statement events. sql/log.cc: When we write the cached binlog segment to disk binlog at COMMIT/ROLLBACK time: imagine this is rollback due to net timeout, after all statements of the transaction succeeded. Then we want a zero-error code in BEGIN. In other words, if there was a really serious error code it's already in the transaction's statement events. sql/sql_table.cc: out of date comment --- sql/log.cc | 9 +++++++++ sql/sql_table.cc | 1 - 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/sql/log.cc b/sql/log.cc index aa5d9d8753b..b2d015c1a14 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1370,6 +1370,14 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, bool commit_or_rollback) */ { Query_log_event qinfo(thd, "BEGIN", 5, TRUE); + /* + Imagine this is rollback due to net timeout, after all statements of + the transaction succeeded. Then we want a zero-error code in BEGIN. + In other words, if there was a really serious error code it's already + in the statement's events. + This is safer than thd->clear_error() against kills at shutdown. + */ + qinfo.error_code= 0; /* Now this Query_log_event has artificial log_pos 0. It must be adjusted to reflect the real position in the log. Not doing it would confuse the @@ -1403,6 +1411,7 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, bool commit_or_rollback) commit_or_rollback ? "COMMIT" : "ROLLBACK", commit_or_rollback ? 6 : 8, TRUE); + qinfo.error_code= 0; qinfo.set_log_pos(this); if (qinfo.write(&log_file) || flush_io_cache(&log_file)) goto err; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 65690e56039..1e5237b1428 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -911,7 +911,6 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, } table->file->extra(HA_EXTRA_WRITE_CACHE); DBUG_RETURN(table); - /* Note that leaving the function resets binlogging properties */ } From ce62fb28c0d101ecf1971f388dcdfce1b3145158 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 16:20:39 +0200 Subject: [PATCH 19/21] Removed check for .ini file elsewhere, except on Windows. --- mysys/default.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mysys/default.c b/mysys/default.c index 416de09b661..d260dd4b370 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -60,7 +60,11 @@ DATADIR, NullS, }; +#ifdef __WIN__ static const char *f_extensions[]= { ".ini", ".cnf", 0 }; +#else +static const char *f_extensions[]= { ".cnf", 0 }; +#endif static int search_default_file(DYNAMIC_ARRAY *args,MEM_ROOT *alloc, const char *dir, const char *config_file, From 98b31cd63c5fe671d7a3bc7b8e4f2daf20b7ee51 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 16:59:36 +0200 Subject: [PATCH 20/21] Some code clean-up and optimization. --- mysys/default.c | 90 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 30 deletions(-) diff --git a/mysys/default.c b/mysys/default.c index d260dd4b370..16e166a3ca5 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -68,7 +68,12 @@ static const char *f_extensions[]= { ".cnf", 0 }; static int search_default_file(DYNAMIC_ARRAY *args,MEM_ROOT *alloc, const char *dir, const char *config_file, - const char *ext, TYPELIB *group); + TYPELIB *group); + +static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc, + const char *dir, const char *ext, + const char *config_file, + TYPELIB *group); static char *remove_end_comment(char *ptr); @@ -164,15 +169,16 @@ int load_defaults(const char *conf_file, const char **groups, goto err; if (forced_default_file) { - if ((error= search_default_file(&args, &alloc, "", - forced_default_file, "", &group)) < 0) + if ((error= search_default_file_with_ext(&args, &alloc, "", "", + forced_default_file, + &group)) < 0) goto err; } else if (dirname_length(conf_file)) { for (ext= (char**) f_extensions; *ext; *ext++) if ((error= search_default_file(&args, &alloc, NullS, conf_file, - *ext, &group)) < 0) + &group)) < 0) goto err; } else @@ -180,33 +186,31 @@ int load_defaults(const char *conf_file, const char **groups, #ifdef __WIN__ char system_dir[FN_REFLEN]; GetWindowsDirectory(system_dir,sizeof(system_dir)); - for (ext= (char**) f_extensions; *ext; *ext++) - if ((search_default_file(&args, &alloc, system_dir, conf_file, - *ext, &group))) - goto err; + if ((search_default_file(&args, &alloc, system_dir, conf_file, &group))) + goto err; #endif #if defined(__EMX__) || defined(OS2) - for (ext= (char**) f_extensions; *ext; *ext++) - if (getenv("ETC") && - (search_default_file(&args, &alloc, getenv("ETC"), conf_file, - *ext, &group)) < 0) - goto err; + { + const char *etc; + if ((etc= getenv("ETC")) && + (search_default_file(&args, &alloc, etc, conf_file, + &group)) < 0) + goto err; + } #endif for (dirs=default_directories ; *dirs; dirs++) { if (**dirs) { - for (ext= (char**) f_extensions; *ext; *ext++) - if (search_default_file(&args, &alloc, *dirs, conf_file, - *ext, &group) < 0) - goto err; + if (search_default_file(&args, &alloc, *dirs, conf_file, + &group) < 0) + goto err; } else if (defaults_extra_file) { - for (ext= (char**) f_extensions; *ext; *ext++) - if (search_default_file(&args, &alloc, NullS, defaults_extra_file, - *ext, &group) < 0) - goto err; /* Fatal error */ + if (search_default_file(&args, &alloc, NullS, defaults_extra_file, + &group) < 0) + goto err; /* Fatal error */ } } } @@ -267,11 +271,28 @@ void free_defaults(char **argv) } +static int search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc, + const char *dir, + const char *config_file, TYPELIB *group) +{ + char **ext; + + for (ext= (char**) f_extensions; *ext; *ext++) + { + int error; + if ((error= search_default_file_with_ext(args, alloc, dir, *ext, + config_file, group)) < 0) + return error; + } + return 0; +} + + /* Open a configuration file (if exists) and read given options from it SYNOPSIS - search_default_file() + search_default_file_with_ext() args Store pointer to found options here alloc Allocate strings in this object dir directory to read @@ -286,9 +307,10 @@ void free_defaults(char **argv) 2 File is not a regular file (Warning) */ -static int search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc, - const char *dir, const char *config_file, - const char *ext, TYPELIB *group) +static int search_default_file_with_ext(DYNAMIC_ARRAY *args, MEM_ROOT *alloc, + const char *dir, const char *ext, + const char *config_file, + TYPELIB *group) { char name[FN_REFLEN+10],buff[4096],*ptr,*end,*value,*tmp; FILE *fp; @@ -482,7 +504,7 @@ static char *remove_end_comment(char *ptr) void print_defaults(const char *conf_file, const char **groups) { #ifdef __WIN__ - bool have_ext=fn_ext(conf_file)[0] != 0; + my_bool have_ext= fn_ext(conf_file)[0] != 0; #endif char name[FN_REFLEN], **ext; const char **dirs; @@ -495,16 +517,24 @@ void print_defaults(const char *conf_file, const char **groups) { #ifdef __WIN__ GetWindowsDirectory(name,sizeof(name)); - if (have_ext) + if (!have_ext) + { for (ext= (char**) f_extensions; *ext; *ext++) printf("%s\\%s%s ", name, conf_file, *ext); + } else printf("%s\\%s ", name, conf_file); #endif #if defined(__EMX__) || defined(OS2) - for (ext= (char**) f_extensions; *ext; *ext++) - if (getenv("ETC")) - printf("%s\\%s%s ", getenv("ETC"), conf_file, *ext); + { + const char *etc; + + if ((etc= getenv("ETC"))) + { + for (ext= (char**) f_extensions; *ext; *ext++) + printf("%s\\%s%s ", etc, conf_file, *ext); + } + } #endif for (dirs=default_directories ; *dirs; dirs++) { From b19eb67f08d04de3af744097e72023d550329035 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 20:59:03 +0000 Subject: [PATCH 21/21] Bug#6123 - GRANT USAGE creates useless mysql.db row Prevent creation of a row which grants no rights Test included mysql-test/r/grant.result: Test for Bug#6123 mysql-test/t/grant.test: Test for Bug#6123 sql/sql_acl.cc: Bug#6123 Prevent creation of useless row --- mysql-test/r/grant.result | 6 ++++++ mysql-test/t/grant.test | 9 +++++++++ sql/sql_acl.cc | 3 ++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index d4d8dd1f026..f0e5d16e916 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -150,3 +150,9 @@ GRANT SELECT ON `ab%`.* TO 'test11'@'localhost' GRANT SELECT ON `a%`.* TO 'test11'@'localhost' delete from mysql.user where user='test11'; delete from mysql.db where user='test11'; +create database db6123; +grant usage on db6123.* to test6123 identified by 'magic123'; +select host,db,user,select_priv,insert_priv from mysql.db where db="db6123"; +host db user select_priv insert_priv +delete from mysql.user where user='test6123'; +drop database db6123; diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index a278b9d5928..21173a356ce 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -105,3 +105,12 @@ flush privileges; show grants for test11@localhost; delete from mysql.user where user='test11'; delete from mysql.db where user='test11'; + +# +# Bug#6123: GRANT USAGE inserts useless Db row +# +create database db6123; +grant usage on db6123.* to test6123 identified by 'magic123'; +select host,db,user,select_priv,insert_priv from mysql.db where db="db6123"; +delete from mysql.user where user='test6123'; +drop database db6123; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index b3bc5a1e4f2..67ca62357ec 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1587,7 +1587,7 @@ static int replace_db_table(TABLE *table, const char *db, goto table_error; /* purecov: deadcode */ } } - else if ((error=table->file->write_row(table->record[0]))) + else if (rights && (error=table->file->write_row(table->record[0]))) { if (error && error != HA_ERR_FOUND_DUPP_KEY) /* purecov: inspected */ goto table_error; /* purecov: deadcode */ @@ -1597,6 +1597,7 @@ static int replace_db_table(TABLE *table, const char *db, if (old_row_exists) acl_update_db(combo.user.str,combo.host.str,db,rights); else + if (rights) acl_insert_db(combo.user.str,combo.host.str,db,rights); table->file->index_end(); DBUG_RETURN(0);