From 792efd59bce2413191d5620c6f0815e21f18b628 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 20 Sep 2012 12:48:59 +0300 Subject: [PATCH 01/14] MDEV-521 fix. After pullout item during single row subselect transformation it should be fixed properly. --- mysql-test/r/subselect.result | 15 +++++++++++++++ mysql-test/r/subselect_no_mat.result | 15 +++++++++++++++ mysql-test/r/subselect_no_opts.result | 15 +++++++++++++++ mysql-test/r/subselect_no_scache.result | 15 +++++++++++++++ mysql-test/r/subselect_no_semijoin.result | 15 +++++++++++++++ mysql-test/t/subselect.test | 13 +++++++++++++ sql/item_subselect.cc | 6 ++---- 7 files changed, 90 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 5126e6b8d5b..2dfe139739b 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -6163,5 +6163,20 @@ a ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) 3 NULL set optimizer_switch=@mdev367_optimizer_switch; DROP TABLE t1; +# +# MDEV-521 single value subselect transformation problem +# +CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('u1'),('u2'); +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +FLUSH TABLES; +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +DROP TABLE t1; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result index ad56c1c2f49..343e3368eba 100644 --- a/mysql-test/r/subselect_no_mat.result +++ b/mysql-test/r/subselect_no_mat.result @@ -6162,6 +6162,21 @@ a ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) 3 NULL set optimizer_switch=@mdev367_optimizer_switch; DROP TABLE t1; +# +# MDEV-521 single value subselect transformation problem +# +CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('u1'),('u2'); +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +FLUSH TABLES; +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +DROP TABLE t1; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set optimizer_switch=default; diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result index 92bd97593b3..1d1510defa0 100644 --- a/mysql-test/r/subselect_no_opts.result +++ b/mysql-test/r/subselect_no_opts.result @@ -6158,6 +6158,21 @@ a ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) 3 NULL set optimizer_switch=@mdev367_optimizer_switch; DROP TABLE t1; +# +# MDEV-521 single value subselect transformation problem +# +CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('u1'),('u2'); +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +FLUSH TABLES; +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +DROP TABLE t1; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set @optimizer_switch_for_subselect_test=null; diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result index 7e2ae9606ef..d80cd477fd0 100644 --- a/mysql-test/r/subselect_no_scache.result +++ b/mysql-test/r/subselect_no_scache.result @@ -6169,6 +6169,21 @@ a ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) 3 NULL set optimizer_switch=@mdev367_optimizer_switch; DROP TABLE t1; +# +# MDEV-521 single value subselect transformation problem +# +CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('u1'),('u2'); +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +FLUSH TABLES; +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +DROP TABLE t1; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set optimizer_switch=default; diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result index 53b914a5af0..2a1d685710e 100644 --- a/mysql-test/r/subselect_no_semijoin.result +++ b/mysql-test/r/subselect_no_semijoin.result @@ -6158,6 +6158,21 @@ a ( 3, 3 ) NOT IN ( SELECT NULL, NULL ) 3 NULL set optimizer_switch=@mdev367_optimizer_switch; DROP TABLE t1; +# +# MDEV-521 single value subselect transformation problem +# +CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('u1'),('u2'); +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +FLUSH TABLES; +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +f1 +u1 +u2 +DROP TABLE t1; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set @optimizer_switch_for_subselect_test=null; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 70682842ee1..bbdf1252334 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -5229,5 +5229,18 @@ set optimizer_switch=@mdev367_optimizer_switch; DROP TABLE t1; +--echo # +--echo # MDEV-521 single value subselect transformation problem +--echo # +CREATE TABLE t1 (f1 char(2), PRIMARY KEY (f1)) ENGINE=MyISAM; +INSERT INTO t1 VALUES ('u1'),('u2'); + +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); +FLUSH TABLES; +SELECT a.* FROM t1 a WHERE ( SELECT EXISTS ( SELECT 1 FROM t1 b WHERE b.f1 = a.f1 ) ); + +# Cleanup +DROP TABLE t1; + --echo # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index c86deecb813..6fc1a591594 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1007,11 +1007,9 @@ Item_singlerow_subselect::select_transformer(JOIN *join) } substitution= select_lex->item_list.head(); /* - as far as we moved content to upper level, field which depend of - 'upper' select is not really dependent => we remove this dependence + as far as we moved content to upper level we have to fix dependences & Co */ - substitution->walk(&Item::remove_dependence_processor, 0, - (uchar *) select_lex->outer_select()); + substitution->fix_after_pullout(select_lex->outer_select(), &substitution); } DBUG_RETURN(false); } From 7d82c6fa04a1469e657e2edb08e1629cd94c8c12 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 24 Sep 2012 11:33:41 +0200 Subject: [PATCH 02/14] MDEV-543 mysql_install_db doesn't work with blanks in either basedir or datadir path --- scripts/mysql_install_db.sh | 46 ++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 399d8d47be0..5fcd56ffdc8 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -248,7 +248,7 @@ fi # Now we can get arguments from the groups [mysqld] and [mysql_install_db] # in the my.cfg file, then re-run to merge with command line arguments. -parse_arguments `$print_defaults $defaults mysqld mysql_install_db` +parse_arguments `"$print_defaults" $defaults mysqld mysql_install_db` parse_arguments PICK-ARGS-FROM-ARGV "$@" # Configure paths to support files @@ -298,7 +298,7 @@ fill_help_tables="$pkgdatadir/fill_help_tables.sql" create_system_tables="$pkgdatadir/mysql_system_tables.sql" fill_system_tables="$pkgdatadir/mysql_system_tables_data.sql" -for f in $fill_help_tables $create_system_tables $fill_system_tables +for f in "$fill_help_tables" "$create_system_tables" "$fill_system_tables" do if test ! -f "$f" then @@ -329,14 +329,14 @@ hostname=`@HOSTNAME@` # Check if hostname is valid if test "$cross_bootstrap" -eq 0 -a "$in_rpm" -eq 0 -a "$force" -eq 0 then - resolved=`$extra_bindir/resolveip $hostname 2>&1` + resolved=`"$extra_bindir/resolveip" $hostname 2>&1` if test $? -ne 0 then - resolved=`$extra_bindir/resolveip localhost 2>&1` + resolved=`"$extra_bindir/resolveip" localhost 2>&1` if test $? -ne 0 then echo "Neither host '$hostname' nor 'localhost' could be looked up with" - echo "$extra_bindir/resolveip" + echo "'$extra_bindir/resolveip'" echo "Please configure the 'hostname' command to return a correct" echo "hostname." echo "If you want to solve this at a later stage, restart this script" @@ -358,16 +358,16 @@ then fi # Create database directories -for dir in $ldata $ldata/mysql $ldata/test +for dir in "$ldata" "$ldata/mysql" "$ldata/test" do - if test ! -d $dir + if test ! -d "$dir" then - mkdir -p $dir - chmod 700 $dir + mkdir -p "$dir" + chmod 700 "$dir" fi if test -w / -a ! -z "$user" then - chown $user $dir + chown $user "$dir" fi done @@ -388,15 +388,19 @@ fi # Configure mysqld command line mysqld_bootstrap="${MYSQLD_BOOTSTRAP-$mysqld}" -mysqld_install_cmd_line="$mysqld_bootstrap $defaults $mysqld_opt --bootstrap \ - --basedir=$basedir --datadir=$ldata --log-warnings=0 --loose-skip-innodb \ +mysqld_install_cmd_line() +{ + "$mysqld_bootstrap" $defaults "$mysqld_opt" --bootstrap \ + "--basedir=$basedir" "--datadir=$ldata" --log-warnings=0 --loose-skip-innodb \ --loose-skip-ndbcluster $args --max_allowed_packet=8M \ --default-storage-engine=myisam \ - --net_buffer_length=16K" + --net_buffer_length=16K +} + # Create the system and help tables by passing them to "mysqld --bootstrap" s_echo "Installing MariaDB/MySQL system tables..." -if { echo "use mysql;"; cat $create_system_tables $fill_system_tables; } | eval "$filter_cmd_line" | $mysqld_install_cmd_line > /dev/null +if { echo "use mysql;"; cat "$create_system_tables" "$fill_system_tables"; } | eval "$filter_cmd_line" | mysqld_install_cmd_line > /dev/null then s_echo "OK" else @@ -428,7 +432,7 @@ else fi s_echo "Filling help tables..." -if { echo "use mysql;"; cat $fill_help_tables; } | $mysqld_install_cmd_line > /dev/null +if { echo "use mysql;"; cat "$fill_help_tables"; } | mysqld_install_cmd_line > /dev/null then s_echo "OK" else @@ -450,11 +454,11 @@ then echo "PLEASE REMEMBER TO SET A PASSWORD FOR THE MariaDB root USER !" echo "To do so, start the server, then issue the following commands:" echo - echo "$bindir/mysqladmin -u root password 'new-password'" - echo "$bindir/mysqladmin -u root -h $hostname password 'new-password'" + echo "'$bindir/mysqladmin' -u root password 'new-password'" + echo "'$bindir/mysqladmin' -u root -h $hostname password 'new-password'" echo echo "Alternatively you can run:" - echo "$bindir/mysql_secure_installation" + echo "'$bindir/mysql_secure_installation'" echo echo "which will also give you the option of removing the test" echo "databases and anonymous user created by default. This is" @@ -466,14 +470,14 @@ then then echo echo "You can start the MariaDB daemon with:" - echo "cd $basedir ; $bindir/mysqld_safe &" + echo "cd '$basedir' ; '$bindir/mysqld_safe' &" echo echo "You can test the MariaDB daemon with mysql-test-run.pl" - echo "cd $basedir/mysql-test ; perl mysql-test-run.pl" + echo "cd '$basedir/mysql-test' ; perl mysql-test-run.pl" fi echo - echo "Please report any problems with the $scriptdir/mysqlbug script!" + echo "Please report any problems with the '$scriptdir/mysqlbug' script!" echo echo "The latest information about MariaDB is available at http://www.askmonty.org/." echo "You can find additional information about the MySQL part at:" From 22c5ffde30008c8f9127db60a99812cd311860ab Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 25 Sep 2012 20:23:01 +0200 Subject: [PATCH 03/14] a simple pam user mapper module --- mysql-test/suite/plugins/r/pam.result | 2 +- mysql-test/suite/plugins/t/pam.test | 2 +- plugin/auth_pam/mapper/pam_user_map.c | 93 +++++++++++++++++++++++ plugin/auth_pam/testing/pam_mariadb_mtr.c | 20 ++--- 4 files changed, 100 insertions(+), 17 deletions(-) create mode 100644 plugin/auth_pam/mapper/pam_user_map.c diff --git a/mysql-test/suite/plugins/r/pam.result b/mysql-test/suite/plugins/r/pam.result index 1c9036c317e..d1b2d291941 100644 --- a/mysql-test/suite/plugins/r/pam.result +++ b/mysql-test/suite/plugins/r/pam.result @@ -2,7 +2,7 @@ install plugin pam soname 'auth_pam.so'; create user test_pam identified via pam using 'mariadb_mtr'; # # athentication is successful, challenge/pin are ok -# note that current_user() differts from user() +# note that current_user() differs from user() # Challenge input first. Enter: not very secret challenge diff --git a/mysql-test/suite/plugins/t/pam.test b/mysql-test/suite/plugins/t/pam.test index 3f4c563d8dc..1968d7fdaa6 100644 --- a/mysql-test/suite/plugins/t/pam.test +++ b/mysql-test/suite/plugins/t/pam.test @@ -29,7 +29,7 @@ EOF --echo # --echo # athentication is successful, challenge/pin are ok ---echo # note that current_user() differts from user() +--echo # note that current_user() differs from user() --echo # --exec $MYSQL_TEST -u test_pam --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/pam_good.txt diff --git a/plugin/auth_pam/mapper/pam_user_map.c b/plugin/auth_pam/mapper/pam_user_map.c new file mode 100644 index 00000000000..e73ab6de544 --- /dev/null +++ b/plugin/auth_pam/mapper/pam_user_map.c @@ -0,0 +1,93 @@ +/* + Pam module to change user names arbitrarily in the pam stack. + + Compile as + + gcc pam_user_map.c -shared -lpam -fPIC -o pam_user_map.so + + Install as appropriate (for example, in /lib/security/). + Add to your /etc/pam.d/mysql (preferrably, at the end) this line: +========================================================= +auth required pam_user_map.so +========================================================= + + And create /etc/security/user_map.conf with the desired mapping + in the format: orig_user_name: mapped_user_name +========================================================= +#comments and emty lines are ignored +john: jack +bob: admin +top: accounting +========================================================= + +*/ + +#include +#include +#include + +#define FILENAME "/etc/security/user_map.conf" +#define skip(what) while (*s && (what)) s++ + +int pam_sm_authenticate(pam_handle_t *pamh, int flags, + int argc, const char *argv[]) +{ + int pam_err, line= 0; + const char *username; + char buf[256]; + FILE *f; + + f= fopen(FILENAME, "r"); + if (f == NULL) + { + pam_syslog(pamh, LOG_ERR, "Cannot open '%s'\n", FILENAME); + return PAM_SYSTEM_ERR; + } + + pam_err = pam_get_item(pamh, PAM_USER, (const void**)&username); + if (pam_err != PAM_SUCCESS) + goto ret; + + while (fgets(buf, sizeof(buf), f) != NULL) + { + char *s= buf, *from, *to, *end_from, *end_to; + line++; + + skip(isspace(*s)); + if (*s == '#' || *s == 0) continue; + from= s; + skip(isalnum(*s) || (*s == '_')); + end_from= s; + skip(isspace(*s)); + if (end_from == from || *s++ != ':') goto syntax_error; + skip(isspace(*s)); + to= s; + skip(isalnum(*s) || (*s == '_')); + end_to= s; + if (end_to == to) goto syntax_error; + + *end_from= *end_to= 0; + if (strcmp(username, from) == 0) + { + pam_err= pam_set_item(pamh, PAM_USER, to); + goto ret; + } + } + pam_err= PAM_SUCCESS; + goto ret; + +syntax_error: + pam_syslog(pamh, LOG_ERR, "Syntax error at %s:%d", FILENAME, line); + pam_err= PAM_SYSTEM_ERR; +ret: + fclose(f); + return pam_err; +} + +int pam_sm_setcred(pam_handle_t *pamh, int flags, + int argc, const char *argv[]) +{ + + return PAM_SUCCESS; +} + diff --git a/plugin/auth_pam/testing/pam_mariadb_mtr.c b/plugin/auth_pam/testing/pam_mariadb_mtr.c index 73defe30112..1078b88cf26 100644 --- a/plugin/auth_pam/testing/pam_mariadb_mtr.c +++ b/plugin/auth_pam/testing/pam_mariadb_mtr.c @@ -10,7 +10,7 @@ Create /etc/pam.d/mariadb_mtr with ========================================================= auth required pam_mariadb_mtr.so pam_test -account required pam_mariadb_mtr.so +account required pam_permit.so ========================================================= */ @@ -21,9 +21,8 @@ account required pam_mariadb_mtr.so #define N 3 -PAM_EXTERN int -pam_sm_authenticate(pam_handle_t *pamh, int flags, - int argc, const char *argv[]) +int pam_sm_authenticate(pam_handle_t *pamh, int flags, + int argc, const char *argv[]) { struct pam_conv *conv; struct pam_response *resp = 0; @@ -69,17 +68,8 @@ ret: return retval; } -PAM_EXTERN int -pam_sm_setcred(pam_handle_t *pamh, int flags, - int argc, const char *argv[]) -{ - - return PAM_SUCCESS; -} - -PAM_EXTERN int -pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, - int argc, const char *argv[]) +int pam_sm_setcred(pam_handle_t *pamh, int flags, + int argc, const char *argv[]) { return PAM_SUCCESS; From 37155bf74a29a57829cc13947ac346b0f2c8fd28 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 26 Sep 2012 15:30:08 +0200 Subject: [PATCH 04/14] Fix some failures in 5.1 Buildbot: - Fix some warnings in newer GCC (-Werror ...). - Fix wrong STACK_DIRECTION detected by configure due to compiler inlining. --- config/ac-macros/misc.m4 | 11 +++---- sql/mysqld.cc | 50 ++++++++++++++--------------- storage/maria/ha_maria.cc | 6 ++-- storage/maria/ma_ft_nlq_search.c | 1 + storage/myisam/ft_nlq_search.c | 1 + storage/xtradb/handler/ha_innodb.cc | 12 +++---- 6 files changed, 41 insertions(+), 40 deletions(-) diff --git a/config/ac-macros/misc.m4 b/config/ac-macros/misc.m4 index 996ac62e025..53d0fed273a 100644 --- a/config/ac-macros/misc.m4 +++ b/config/ac-macros/misc.m4 @@ -456,10 +456,8 @@ fi AC_DEFUN([MYSQL_STACK_DIRECTION], [AC_CACHE_CHECK(stack direction for C alloca, ac_cv_c_stack_direction, [AC_TRY_RUN([#include - /* Prevent compiler optimization by HP's compiler, see bug#42213 */ -#if defined(__HP_cc) || defined (__HP_aCC) || defined (__hpux) -#pragma noinline -#endif + /* Prevent compiler inline optimization, see bug#42213 */ + int (volatile *ptr_f)(); int find_stack_direction () { static char *addr = 0; @@ -467,14 +465,15 @@ AC_DEFUN([MYSQL_STACK_DIRECTION], if (addr == 0) { addr = &dummy; - return find_stack_direction (); + return (*prt_f) (); } else return (&dummy > addr) ? 1 : -1; } int main () { - exit (find_stack_direction() < 0); + ptr_f = find_stack_direction; + exit ((*ptr_f)() < 0); }], ac_cv_c_stack_direction=1, ac_cv_c_stack_direction=-1, ac_cv_c_stack_direction=)]) AC_DEFINE_UNQUOTED(STACK_DIRECTION, $ac_cv_c_stack_direction) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 629ffe26f2c..66cdc3eba1c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5991,7 +5991,7 @@ struct my_option my_long_options[] = {"debug-crc-break", OPT_DEBUG_CRC, "Call my_debug_put_break_here() if crc matches this number (for debug).", &opt_my_crc_dbug_check, &opt_my_crc_dbug_check, - 0, GET_ULONG, REQUIRED_ARG, 0, 0, ~(ulong) 0L, 0, 0, 0}, + 0, GET_ULONG, REQUIRED_ARG, 0, 0, ~(ulonglong) 0, 0, 0, 0}, {"debug-flush", OPT_DEBUG_FLUSH, "Default debug log with flush after write", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"debug-assert-if-crashed-table", OPT_DEBUG_ASSERT_IF_CRASHED_TABLE, @@ -6221,7 +6221,7 @@ each time the SQL thread starts.", #ifdef HAVE_MMAP {"log-tc-size", OPT_LOG_TC_SIZE, "Size of transaction coordinator log.", &opt_tc_log_size, &opt_tc_log_size, 0, GET_ULONG, - REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, (longlong) ULONG_MAX, 0, + REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, (ulonglong) ULONG_MAX, 0, TC_LOG_PAGE_SIZE, 0}, #endif {"log-update", OPT_UPDATE_LOG, @@ -6785,12 +6785,12 @@ thread is in the relay logs.", "during a transaction. If you often use big, multi-statement " "transactions you can increase this to get more performance.", &binlog_cache_size, &binlog_cache_size, 0, GET_ULONG, - REQUIRED_ARG, 32*1024L, IO_SIZE, (longlong) ULONG_MAX, 0, IO_SIZE, 0}, + REQUIRED_ARG, 32*1024L, IO_SIZE, (ulonglong) ULONG_MAX, 0, IO_SIZE, 0}, {"bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE, "Size of tree cache used in bulk insert optimization. Note that this " "is a limit per thread.", &global_system_variables.bulk_insert_buff_size, &max_system_variables.bulk_insert_buff_size, - 0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, (longlong) ULONG_MAX, 0, 1, 0}, + 0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, (ulonglong) ULONG_MAX, 0, 1, 0}, {"connect_timeout", OPT_CONNECT_TIMEOUT, "The number of seconds the mysqld server is waiting for a connect packet " "before responding with 'Bad handshake'.", &connect_timeout, &connect_timeout, @@ -6815,7 +6815,7 @@ thread is in the relay logs.", "will check if there are any SELECT statements pending. If so, it allows " "these to execute before continuing.", &delayed_insert_limit, &delayed_insert_limit, 0, GET_ULONG, - REQUIRED_ARG, DELAYED_LIMIT, 1, (longlong) ULONG_MAX, 0, 1, 0}, + REQUIRED_ARG, DELAYED_LIMIT, 1, (ulonglong) ULONG_MAX, 0, 1, 0}, {"delayed_insert_timeout", OPT_DELAYED_INSERT_TIMEOUT, "How long a INSERT DELAYED thread should wait for INSERT statements before terminating.", &delayed_insert_timeout, &delayed_insert_timeout, 0, @@ -6825,7 +6825,7 @@ thread is in the relay logs.", "If the queue becomes full, any client that does INSERT DELAYED will wait " "until there is room in the queue again.", &delayed_queue_size, &delayed_queue_size, 0, GET_ULONG, - REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, (longlong) ULONG_MAX, 0, 1, 0}, + REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, (ulonglong) ULONG_MAX, 0, 1, 0}, {"div_precision_increment", OPT_DIV_PRECINCREMENT, "Precision of the result of '/' operator will be increased on that value.", &global_system_variables.div_precincrement, @@ -6865,7 +6865,7 @@ thread is in the relay logs.", "The maximum length of the result of function group_concat.", &global_system_variables.group_concat_max_len, &max_system_variables.group_concat_max_len, 0, GET_ULONG, - REQUIRED_ARG, 1024, 4, (longlong) ULONG_MAX, 0, 1, 0}, + REQUIRED_ARG, 1024, 4, (ulonglong) ULONG_MAX, 0, 1, 0}, {"interactive_timeout", OPT_INTERACTIVE_TIMEOUT, "The number of seconds the server waits for activity on an interactive " "connection before closing it.", @@ -6876,7 +6876,7 @@ thread is in the relay logs.", "The size of the buffer that is used for full joins.", &global_system_variables.join_buff_size, &max_system_variables.join_buff_size, 0, GET_ULONG, - REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, (longlong) ULONG_MAX, + REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, (ulonglong) ULONG_MAX, MALLOC_OVERHEAD, IO_SIZE, 0}, {"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE, "Don't overwrite stale .MYD and .MYI even if no directory is specified.", @@ -6897,7 +6897,7 @@ thread is in the relay logs.", "This specifies the percentage ratio of that number of hits to the total " "number of blocks in key cache.", &dflt_key_cache_var.param_age_threshold, 0, 0, - (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, 300, 100, (longlong) ULONG_MAX, + (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, 300, 100, (ulonglong) ULONG_MAX, 0, 100, 0}, {"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE, "The default size of key cache blocks.", @@ -6918,7 +6918,7 @@ thread is in the relay logs.", "this to reduce output on slow query log)", &global_system_variables.log_slow_rate_limit, &max_system_variables.log_slow_rate_limit, 0, GET_ULONG, - REQUIRED_ARG, 1, 1, ~0L, 0, 1L, 0}, + REQUIRED_ARG, 1, 1, ~0ULL, 0, 1L, 0}, {"log-slow-verbosity", OPT_LOG_SLOW_VERBOSITY, "Choose how verbose the messages to your slow log will be. Multiple flags " "allowed in a comma-separated string. [query_plan, innodb]", @@ -6972,7 +6972,7 @@ thread is in the relay logs.", "If there is more than this number of interrupted connections from a host " "this host will be blocked from further connections.", &max_connect_errors, &max_connect_errors, 0, GET_ULONG, - REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, (longlong) ULONG_MAX, 0, 1, 0}, + REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, (ulonglong) ULONG_MAX, 0, 1, 0}, // Default max_connections of 151 is larger than Apache's default max // children, to avoid "too many connections" error in a common setup {"max_connections", OPT_MAX_CONNECTIONS, @@ -7041,7 +7041,7 @@ thread is in the relay logs.", "Maximum number of temporary tables a client can keep open at a time.", &global_system_variables.max_tmp_tables, &max_system_variables.max_tmp_tables, 0, GET_ULONG, - REQUIRED_ARG, 32, 1, (longlong) ULONG_MAX, 0, 1, 0}, + REQUIRED_ARG, 32, 1, (ulonglong) ULONG_MAX, 0, 1, 0}, {"max_user_connections", OPT_MAX_USER_CONNECTIONS, "The maximum number of active connections for a single user (0 = no limit).", &max_user_connections, &max_user_connections, 0, GET_UINT, @@ -7054,12 +7054,12 @@ thread is in the relay logs.", "Don't log queries which examine less than min_examined_row_limit rows to file.", &global_system_variables.min_examined_row_limit, &max_system_variables.min_examined_row_limit, 0, GET_ULONG, - REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1L, 0}, + REQUIRED_ARG, 0, 0, (ulonglong) ULONG_MAX, 0, 1L, 0}, {"multi_range_count", OPT_MULTI_RANGE_COUNT, "Number of key ranges to request at once.", &global_system_variables.multi_range_count, &max_system_variables.multi_range_count, 0, - GET_ULONG, REQUIRED_ARG, 256, 1, (longlong) ULONG_MAX, 0, 1, 0}, + GET_ULONG, REQUIRED_ARG, 256, 1, (ulonglong) ULONG_MAX, 0, 1, 0}, {"myisam_block_size", OPT_MYISAM_BLOCK_SIZE, "Block size to be used for MyISAM index pages.", &opt_myisam_block_size, &opt_myisam_block_size, 0, GET_ULONG, REQUIRED_ARG, @@ -7095,7 +7095,7 @@ thread is in the relay logs.", "disables parallel repair.", &global_system_variables.myisam_repair_threads, &max_system_variables.myisam_repair_threads, 0, - GET_ULONG, REQUIRED_ARG, 1, 1, (longlong) ULONG_MAX, 0, 1, 0}, + GET_ULONG, REQUIRED_ARG, 1, 1, (ulonglong) ULONG_MAX, 0, 1, 0}, {"myisam_sort_buffer_size", OPT_MYISAM_SORT_BUFFER_SIZE, "The buffer that is allocated when sorting the index when doing a REPAIR " "or when creating indexes with CREATE INDEX or ALTER TABLE.", @@ -7126,7 +7126,7 @@ thread is in the relay logs.", "If a read on a communication port is interrupted, retry this many times before giving up.", &global_system_variables.net_retry_count, &max_system_variables.net_retry_count,0, - GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, (longlong) ULONG_MAX, + GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, (ulonglong) ULONG_MAX, 0, 1, 0}, {"net_write_timeout", OPT_NET_WRITE_TIMEOUT, "Number of seconds to wait for a block to be written to a connection before " @@ -7192,19 +7192,19 @@ thread is in the relay logs.", "Allocation block size for query parsing and execution.", &global_system_variables.query_alloc_block_size, &max_system_variables.query_alloc_block_size, 0, GET_ULONG, - REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, (longlong) ULONG_MAX, 0, 1024, + REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, (ulonglong) ULONG_MAX, 0, 1024, 0}, #ifdef HAVE_QUERY_CACHE {"query_cache_limit", OPT_QUERY_CACHE_LIMIT, "Don't cache results that are bigger than this.", &query_cache_limit, &query_cache_limit, 0, GET_ULONG, - REQUIRED_ARG, 1024*1024L, 0, (longlong) ULONG_MAX, 0, 1, 0}, + REQUIRED_ARG, 1024*1024L, 0, (ulonglong) ULONG_MAX, 0, 1, 0}, {"query_cache_min_res_unit", OPT_QUERY_CACHE_MIN_RES_UNIT, "Minimal size of unit in which space for results is allocated (last unit " "will be trimmed after writing all result data).", &query_cache_min_res_unit, &query_cache_min_res_unit, 0, GET_ULONG, REQUIRED_ARG, QUERY_CACHE_MIN_RESULT_DATA_SIZE, - 0, (longlong) ULONG_MAX, 0, 1, 0}, + 0, (ulonglong) ULONG_MAX, 0, 1, 0}, #endif /*HAVE_QUERY_CACHE*/ {"query_cache_size", OPT_QUERY_CACHE_SIZE, "The memory allocated to store results from old queries.", @@ -7228,13 +7228,13 @@ thread is in the relay logs.", &global_system_variables.query_prealloc_size, &max_system_variables.query_prealloc_size, 0, GET_ULONG, REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE, - (longlong) ULONG_MAX, 0, 1024, 0}, + (ulonglong) ULONG_MAX, 0, 1024, 0}, {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE, "Allocation block size for storing ranges during optimization.", &global_system_variables.range_alloc_block_size, &max_system_variables.range_alloc_block_size, 0, GET_ULONG, REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, - (longlong) ULONG_MAX, 0, 1024, 0}, + (ulonglong) ULONG_MAX, 0, 1024, 0}, {"read_buffer_size", OPT_RECORD_BUFFER, "Each thread that does a sequential scan allocates a buffer of this size " "for each table it scans. If you do many sequential scans, you may want " @@ -7303,7 +7303,7 @@ thread is in the relay logs.", "Synchronously flush binary log to disk after every #th event. " "Use 0 (default) to disable synchronous flushing.", &sync_binlog_period, &sync_binlog_period, 0, GET_ULONG, - REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1, 0}, + REQUIRED_ARG, 0, 0, (ulonglong) ULONG_MAX, 0, 1, 0}, {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default.", &opt_sync_frm, &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -7348,7 +7348,7 @@ thread is in the relay logs.", {"thread_stack", OPT_THREAD_STACK, "The stack size for each thread.", &my_thread_stack_size, &my_thread_stack_size, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK, - (sizeof(void*)<=4)?1024L*128L: ((256-16)*1024L), (longlong) ULONG_MAX, 0, 1024, 0}, + (sizeof(void*)<=4)?1024L*128L: ((256-16)*1024L), (ulonglong) ULONG_MAX, 0, 1024, 0}, { "time_format", OPT_TIME_FORMAT, "The TIME format (for future).", &opt_date_time_formats[MYSQL_TIMESTAMP_TIME], @@ -7364,13 +7364,13 @@ thread is in the relay logs.", "Allocation block size for transactions to be stored in binary log.", &global_system_variables.trans_alloc_block_size, &max_system_variables.trans_alloc_block_size, 0, GET_ULONG, - REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, (longlong) ULONG_MAX, 0, 1024, + REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, (ulonglong) ULONG_MAX, 0, 1024, 0}, {"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE, "Persistent buffer for transactions to be stored in binary log.", &global_system_variables.trans_prealloc_size, &max_system_variables.trans_prealloc_size, 0, GET_ULONG, - REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, (longlong) ULONG_MAX, 0, + REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, (ulonglong) ULONG_MAX, 0, 1024, 0}, {"thread_handling", OPT_THREAD_HANDLING, "Define threads usage for handling queries: " diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index b261451d8dc..09df4c9e03b 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -186,7 +186,7 @@ static MYSQL_SYSVAR_ULONG(pagecache_age_threshold, "until it is considered aged enough to be downgraded to a warm block. " "This specifies the percentage ratio of that number of hits to the " "total number of blocks in the page cache.", 0, 0, - 300, 100, ~0L, 100); + 300, 100, ~(unsigned long)0, 100); static MYSQL_SYSVAR_ULONGLONG(pagecache_buffer_size, pagecache_buffer_size, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, @@ -209,12 +209,12 @@ static MYSQL_SYSVAR_SET(recover, maria_recover_options, PLUGIN_VAR_OPCMDARG, static MYSQL_THDVAR_ULONG(repair_threads, PLUGIN_VAR_RQCMDARG, "Number of threads to use when repairing maria tables. The value of 1 " "disables parallel repair.", - 0, 0, 1, 1, ~0L, 1); + 0, 0, 1, 1, ~(unsigned long)0, 1); static MYSQL_THDVAR_ULONG(sort_buffer_size, PLUGIN_VAR_RQCMDARG, "The buffer that is allocated when sorting the index when doing a " "REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.", - 0, 0, 128L*1024L*1024L, 4, ~0L, 1); + 0, 0, 128L*1024L*1024L, 4, ~(unsigned long)0, 1); static MYSQL_THDVAR_ENUM(stats_method, PLUGIN_VAR_RQCMDARG, "Specifies how maria index statistics collection code should treat " diff --git a/storage/maria/ma_ft_nlq_search.c b/storage/maria/ma_ft_nlq_search.c index e0e1e2ce0d3..7506c5dd12b 100644 --- a/storage/maria/ma_ft_nlq_search.c +++ b/storage/maria/ma_ft_nlq_search.c @@ -82,6 +82,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) #error #endif DBUG_ENTER("walk_and_match"); + LINT_INIT(subkeys.i); word->weight=LWS_FOR_QUERY; diff --git a/storage/myisam/ft_nlq_search.c b/storage/myisam/ft_nlq_search.c index 9ebdef582c9..be8d8390ba4 100644 --- a/storage/myisam/ft_nlq_search.c +++ b/storage/myisam/ft_nlq_search.c @@ -83,6 +83,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) #error #endif DBUG_ENTER("walk_and_match"); + LINT_INIT(subkeys.i); word->weight=LWS_FOR_QUERY; diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 3dacac1e258..e3a55a55e93 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -11621,7 +11621,7 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite, static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity, PLUGIN_VAR_RQCMDARG, "Number of IOPs the server can do. Tunes the background IO rate", - NULL, NULL, 200, 100, ~0L, 0); + NULL, NULL, 200, 100, ~0UL, 0); static MYSQL_SYSVAR_ULONG(fast_shutdown, innobase_fast_shutdown, PLUGIN_VAR_OPCMDARG, @@ -11709,7 +11709,7 @@ static MYSQL_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing, static MYSQL_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag, PLUGIN_VAR_RQCMDARG, "Desired maximum length of the purge queue (0 = no limit)", - NULL, NULL, 0, 0, ~0L, 0); + NULL, NULL, 0, 0, ~0UL, 0); static MYSQL_SYSVAR_BOOL(rollback_on_timeout, innobase_rollback_on_timeout, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, @@ -11796,7 +11796,7 @@ static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency, static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter, PLUGIN_VAR_RQCMDARG, "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket", - NULL, NULL, 500L, 1L, ~0L, 0); + NULL, NULL, 500L, 1L, ~0UL, 0); #ifdef EXTENDED_FOR_KILLIDLE #define kill_idle_help_text "If non-zero value, the idle session with transaction which is idle over the value in seconds is killed by InnoDB." @@ -11866,12 +11866,12 @@ static MYSQL_SYSVAR_LONG(open_files, innobase_open_files, static MYSQL_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds, PLUGIN_VAR_RQCMDARG, "Count of spin-loop rounds in InnoDB mutexes (30 by default)", - NULL, NULL, 30L, 0L, ~0L, 0); + NULL, NULL, 30L, 0L, ~0UL, 0); static MYSQL_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay, PLUGIN_VAR_OPCMDARG, "Maximum delay between polling for a spin lock (6 by default)", - NULL, NULL, 6L, 0L, ~0L, 0); + NULL, NULL, 6L, 0L, ~0UL, 0); static MYSQL_SYSVAR_BOOL(thread_concurrency_timer_based, innobase_thread_concurrency_timer_based, @@ -11887,7 +11887,7 @@ static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency, static MYSQL_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay, PLUGIN_VAR_RQCMDARG, "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep", - NULL, NULL, 10000L, 0L, ~0L, 0); + NULL, NULL, 10000L, 0L, ~0UL, 0); static MYSQL_SYSVAR_STR(data_file_path, innobase_data_file_path, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, From 1f2f353cd6df4b5af5134aa9011e02bc3b0a3f89 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 26 Sep 2012 11:59:49 +0200 Subject: [PATCH 05/14] always force the language in mysql_install_db --- scripts/mysql_install_db.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 5fcd56ffdc8..165faf34d9a 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -320,8 +320,10 @@ then cannot_find_file "$langdir/errmsg.sys" exit 1 fi - mysqld_opt="--language=$langdir" +else + langdir=english fi +mysqld_opt="--language=$langdir" # Try to determine the hostname hostname=`@HOSTNAME@` From 8c2bb705f11956cdc0acb67182466a903dcdd19b Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Thu, 27 Sep 2012 13:18:07 +0500 Subject: [PATCH 06/14] MDEV-495 backport --ignore-db-dir. The feature was backported from MySQL 5.6. Some code was added to make commands as SELECT * FROM ignored_db.t1; CALL ignored_db.proc(); USE ignored_db; to take that option into account. per-file comments: mysql-test/r/ignore_db_dirs_basic.result test result added. mysql-test/t/ignore_db_dirs_basic-master.opt options for the test, actually the set of --ignore-db-dir lines. mysql-test/t/ignore_db_dirs_basic.test test for the feature. Same test from 5.6 was taken as a basis, then tests for SELECT, CALL etc were added. per-file comments: sql/mysql_priv.h MDEV-495 backport --ignore-db-dir. interface for db_name_is_in_ignore_list() added. sql/mysqld.cc MDEV-495 backport --ignore-db-dir. --ignore-db-dir handling. sql/set_var.cc MDEV-495 backport --ignore-db-dir. the @@ignore_db_dirs variable added. sql/sql_show.cc MDEV-495 backport --ignore-db-dir. check if the directory is ignored. sql/sql_show.h MDEV-495 backport --ignore-db-dir. interface added for opt_ignored_db_dirs. sql/table.cc MDEV-495 backport --ignore-db-dir. check if the directory is ignored. --- mysql-test/r/ignore_db_dirs_basic.result | 47 ++++ mysql-test/t/ignore_db_dirs_basic-master.opt | 11 + mysql-test/t/ignore_db_dirs_basic.test | 38 +++ sql/mysql_priv.h | 2 + sql/mysqld.cc | 35 ++- sql/set_var.cc | 3 + sql/sql_show.cc | 281 +++++++++++++++++++ sql/sql_show.h | 9 + sql/table.cc | 3 + 9 files changed, 428 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/ignore_db_dirs_basic.result create mode 100644 mysql-test/t/ignore_db_dirs_basic-master.opt create mode 100644 mysql-test/t/ignore_db_dirs_basic.test diff --git a/mysql-test/r/ignore_db_dirs_basic.result b/mysql-test/r/ignore_db_dirs_basic.result new file mode 100644 index 00000000000..a0bbcb54f15 --- /dev/null +++ b/mysql-test/r/ignore_db_dirs_basic.result @@ -0,0 +1,47 @@ +select @@ignore_db_dirs; +@@ignore_db_dirs +e,lost+found,.mysqlgui,ignored_db +# Check that SHOW DATABASES ignores all directories from +# @@ignore_db_dirs and all directories with names starting +# with '.' +SHOW DATABASES; +Database +information_schema +#mysql50#.otherdir +mtr +mysql +test +USE ignored_db; +ERROR 42000: Incorrect database name 'ignored_db' +SELECT * FROM ignored_db.t1; +ERROR 42000: Incorrect database name 'ignored_db' +CALL ignored_db.p1(); +ERROR 42000: Incorrect database name 'ignored_db' +SELECT COUNT(*) FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='ignored_db'; +COUNT(*) +1 +CREATE DATABASE ignored_db; +ERROR 42000: Incorrect database name 'ignored_db' +CREATE DATABASE `lost+found`; +USE `lost+found`; +CREATE TABLE t1(id INT); +INSERT INTO t1 VALUES (1), (2); +SELECT * FROM `lost+found`.t1; +id +1 +2 +SHOW DATABASES; +Database +information_schema +#mysql50#.otherdir +lost+found +mtr +mysql +test +DROP DATABASE `lost+found`; +SET @@global.ignore_db_dirs = 'aha'; +ERROR HY000: Variable 'ignore_db_dirs' is a read only variable +SET @@local.ignore_db_dirs = 'aha'; +ERROR HY000: Variable 'ignore_db_dirs' is a read only variable +SET @@ignore_db_dirs = 'aha'; +ERROR HY000: Variable 'ignore_db_dirs' is a read only variable diff --git a/mysql-test/t/ignore_db_dirs_basic-master.opt b/mysql-test/t/ignore_db_dirs_basic-master.opt new file mode 100644 index 00000000000..30ee4f67284 --- /dev/null +++ b/mysql-test/t/ignore_db_dirs_basic-master.opt @@ -0,0 +1,11 @@ +--ignore-db-dir=a +--ignore-db-dir=b +--ignore-db-dir=c +--ignore-db-dir= +--ignore-db-dir=d +--ignore-db-dir x +--ignore-db-dir= +--ignore-db-dir=e +--ignore-db-dir=lost+found +--ignore-db-dir=.mysqlgui +--ignore-db-dir=ignored_db diff --git a/mysql-test/t/ignore_db_dirs_basic.test b/mysql-test/t/ignore_db_dirs_basic.test new file mode 100644 index 00000000000..9544fc540f9 --- /dev/null +++ b/mysql-test/t/ignore_db_dirs_basic.test @@ -0,0 +1,38 @@ +select @@ignore_db_dirs; +let $MYSQLD_DATADIR= `select @@datadir`; + +mkdir $MYSQLD_DATADIR/.mysqlgui; +mkdir $MYSQLD_DATADIR/.otherdir; +mkdir $MYSQLD_DATADIR/lost+found; +mkdir $MYSQLD_DATADIR/ignored_db; +--echo # Check that SHOW DATABASES ignores all directories from +--echo # @@ignore_db_dirs and all directories with names starting +--echo # with '.' +SHOW DATABASES; +--error ER_WRONG_DB_NAME +USE ignored_db; +--error ER_WRONG_DB_NAME +SELECT * FROM ignored_db.t1; +--error ER_WRONG_DB_NAME +CALL ignored_db.p1(); +SELECT COUNT(*) FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='ignored_db'; +--error ER_WRONG_DB_NAME +CREATE DATABASE ignored_db; +CREATE DATABASE `lost+found`; +USE `lost+found`; +CREATE TABLE t1(id INT); +INSERT INTO t1 VALUES (1), (2); +SELECT * FROM `lost+found`.t1; +SHOW DATABASES; +DROP DATABASE `lost+found`; +rmdir $MYSQLD_DATADIR/.mysqlgui; +rmdir $MYSQLD_DATADIR/.otherdir; +rmdir $MYSQLD_DATADIR/lost+found; +rmdir $MYSQLD_DATADIR/ignored_db; + +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SET @@global.ignore_db_dirs = 'aha'; +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SET @@local.ignore_db_dirs = 'aha'; +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SET @@ignore_db_dirs = 'aha'; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 14810fc7119..5f20e9f0591 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -2834,6 +2834,8 @@ bool load_collation(MEM_ROOT *mem_root, CHARSET_INFO *dflt_cl, CHARSET_INFO **cl); +bool db_name_is_in_ignore_db_dirs_list(const char *dbase); + #endif /* MYSQL_SERVER */ extern "C" int test_if_data_home_dir(const char *dir); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 26fd22ef95b..e6653e410cb 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -33,6 +33,7 @@ #include #include "debug_sync.h" #include "log_event.h" +#include "sql_show.h" #include "../storage/myisam/ha_myisam.h" @@ -1447,6 +1448,7 @@ void clean_up(bool print_message) #endif my_tz_free(); my_database_names_free(); + ignore_db_dirs_free(); #ifndef NO_EMBEDDED_ACCESS_CHECKS servers_free(1); acl_free(1); @@ -3332,6 +3334,9 @@ static int init_common_variables(const char *conf_file_name, int argc, mysql_init_variables()) return 1; + if (ignore_db_dirs_init()) + return 1; + #ifdef HAVE_TZNAME { struct tm tm_tmp; @@ -3677,6 +3682,12 @@ You should consider changing lower_case_table_names to 1 or 2", files_charset_info : &my_charset_bin); + if (ignore_db_dirs_process_additions()) + { + sql_print_error("An error occurred while storing ignore_db_dirs to a hash."); + return 1; + } + return 0; } @@ -5999,7 +6010,8 @@ enum options_mysqld OPT_MAX_LONG_DATA_SIZE, OPT_MASTER_VERIFY_CHECKSUM, OPT_SLAVE_SQL_VERIFY_CHECKSUM, - OPT_QUERY_CACHE_STRIP_COMMENTS + OPT_QUERY_CACHE_STRIP_COMMENTS, + OPT_IGNORE_DB_DIRECTORY }; @@ -6288,6 +6300,11 @@ struct my_option my_long_options[] = each time the SQL thread starts.", &opt_init_slave, &opt_init_slave, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"ignore-db-dir", OPT_IGNORE_DB_DIRECTORY, + "Specifies a directory to add to the ignore list when collecting " + "database names from the datadir. Put a blank argument to reset " + "the list accumulated so far.", 0, 0, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, {"language", 'L', "Client error messages in given language. May be given as a full path.", &language_ptr, &language_ptr, 0, GET_STR, REQUIRED_ARG, @@ -9286,6 +9303,22 @@ mysqld_get_one_option(int optid, case OPT_MAX_LONG_DATA_SIZE: max_long_data_size_used= true; break; + + + case OPT_IGNORE_DB_DIRECTORY: + if (*argument == 0) + ignore_db_dirs_reset(); + else + { + if (push_ignored_db_dir(argument)) + { + sql_print_error("Can't start server: " + "cannot process --ignore-db-dir=%.*s", + FN_REFLEN, argument); + return 1; + } + } + break; } return 0; } diff --git a/sql/set_var.cc b/sql/set_var.cc index c52e415e657..94a1b6a1cef 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -67,6 +67,7 @@ #include #include #include "events.h" +#include "sql_show.h" // opt_ignore_db_dirs /* WITH_NDBCLUSTER_STORAGE_ENGINE */ #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE @@ -1013,6 +1014,8 @@ static sys_var_readonly sys_in_transaction(&vars, "in_transaction", OPT_SESSION, SHOW_BOOL, in_transaction); +static sys_var_const_str_ptr sys_ignore_db_dirs(&vars, "ignore_db_dirs", + &opt_ignore_db_dirs); bool sys_var::check(THD *thd, set_var *var) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 0a23a95bbcf..562ccea488f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -379,6 +379,284 @@ bool mysqld_show_privileges(THD *thd) } +/** Hash of LEX_STRINGs used to search for ignored db directories. */ +static HASH ignore_db_dirs_hash; + +/** + An array of LEX_STRING pointers to collect the options at + option parsing time. +*/ +static DYNAMIC_ARRAY ignore_db_dirs_array; + +/** + A value for the read only system variable to show a list of + ignored directories. +*/ +char *opt_ignore_db_dirs= NULL; + +/** + This flag is ON if: + - the list of ignored directories is not empty + + - and some of the ignored directory names + need no tablename-to-filename conversion. + Otherwise, if the name of the directory contains + unconditional characters like '+' or '.', they + never can match the database directory name. So the + db_name_is_in_ignore_db_dirs_list() can just return at once. +*/ +static bool skip_ignored_dir_check= TRUE; + +/** + Sets up the data structures for collection of directories at option + processing time. + We need to collect the directories in an array first, because + we need the character sets initialized before setting up the hash. + + @return state + @retval TRUE failed + @retval FALSE success +*/ + +bool +ignore_db_dirs_init() +{ + return my_init_dynamic_array(&ignore_db_dirs_array, sizeof(LEX_STRING *), + 0, 0); +} + + +/** + Retrieves the key (the string itself) from the LEX_STRING hash members. + + Needed by hash_init(). + + @param data the data element from the hash + @param out len_ret Placeholder to return the length of the key + @param unused + @return a pointer to the key +*/ + +static uchar * +db_dirs_hash_get_key(const uchar *data, size_t *len_ret, + my_bool __attribute__((unused))) +{ + LEX_STRING *e= (LEX_STRING *) data; + + *len_ret= e->length; + return (uchar *) e->str; +} + + +/** + Wrap a directory name into a LEX_STRING and push it to the array. + + Called at option processing time for each --ignore-db-dir option. + + @param path the name of the directory to push + @return state + @retval TRUE failed + @retval FALSE success +*/ + +bool +push_ignored_db_dir(char *path) +{ + LEX_STRING *new_elt; + char *new_elt_buffer; + size_t path_len= strlen(path); + + if (!path_len || path_len >= FN_REFLEN) + return true; + + // No need to normalize, it's only a directory name, not a path. + if (!my_multi_malloc(0, + &new_elt, sizeof(LEX_STRING), + &new_elt_buffer, path_len + 1, + NullS)) + return true; + new_elt->str= new_elt_buffer; + memcpy(new_elt_buffer, path, path_len); + new_elt_buffer[path_len]= 0; + new_elt->length= path_len; + return insert_dynamic(&ignore_db_dirs_array, (uchar*) &new_elt); +} + + +/** + Clean up the directory ignore options accumulated so far. + + Called at option processing time for each --ignore-db-dir option + with an empty argument. +*/ + +void +ignore_db_dirs_reset() +{ + LEX_STRING **elt; + while (NULL!= (elt= (LEX_STRING **) pop_dynamic(&ignore_db_dirs_array))) + if (elt && *elt) + my_free(*elt, MYF(0)); +} + + +/** + Free the directory ignore option variables. + + Called at server shutdown. +*/ + +void +ignore_db_dirs_free() +{ + if (opt_ignore_db_dirs) + { + my_free(opt_ignore_db_dirs, MYF(0)); + opt_ignore_db_dirs= NULL; + } + ignore_db_dirs_reset(); + delete_dynamic(&ignore_db_dirs_array); + my_hash_free(&ignore_db_dirs_hash); +} + + +/** + Initialize the ignore db directories hash and status variable from + the options collected in the array. + + Called when option processing is over and the server's in-memory + structures are fully initialized. + + @return state + @retval TRUE failed + @retval FALSE success +*/ + +static void dispose_db_dir(void *ptr) +{ + my_free(ptr, MYF(0)); +} + + +bool +ignore_db_dirs_process_additions() +{ + ulong i; + size_t len; + char *ptr; + LEX_STRING *dir; + + + DBUG_ASSERT(opt_ignore_db_dirs == NULL); + + skip_ignored_dir_check= TRUE; + + if (my_hash_init(&ignore_db_dirs_hash, + lower_case_table_names ? + character_set_filesystem : &my_charset_bin, + 0, 0, 0, db_dirs_hash_get_key, + dispose_db_dir, + HASH_UNIQUE)) + return true; + + /* len starts from 1 because of the terminating zero. */ + len= 1; + for (i= 0; i < ignore_db_dirs_array.elements; i++) + { + get_dynamic(&ignore_db_dirs_array, (uchar *) &dir, i); + len+= dir->length + 1; // +1 for the comma + if (skip_ignored_dir_check) + { + char buff[FN_REFLEN]; + uint buff_len; + buff_len= tablename_to_filename(dir->str, buff, sizeof(buff)); + skip_ignored_dir_check= strcmp(dir->str, buff) != 0; + } + } + + /* No delimiter for the last directory. */ + if (len > 1) + len--; + + /* +1 the terminating zero */ + ptr= opt_ignore_db_dirs= (char *) my_malloc(len + 1, MYF(0)); + if (!ptr) + return true; + + /* Make sure we have an empty string to start with. */ + *ptr= 0; + + for (i= 0; i < ignore_db_dirs_array.elements; i++) + { + get_dynamic(&ignore_db_dirs_array, (uchar *) &dir, i); + if (my_hash_insert(&ignore_db_dirs_hash, (uchar *) dir)) + return true; + ptr= strnmov(ptr, dir->str, dir->length); + if (i + 1 < ignore_db_dirs_array.elements) + ptr= strmov(ptr, ","); + + /* + Set the transferred array element to NULL to avoid double free + in case of error. + */ + dir= NULL; + set_dynamic(&ignore_db_dirs_array, (uchar *) &dir, i); + } + + /* make sure the string is terminated */ + DBUG_ASSERT(ptr - opt_ignore_db_dirs <= (ptrdiff_t) len); + *ptr= 0; + + /* + It's OK to empty the array here as the allocated elements are + referenced through the hash now. + */ + reset_dynamic(&ignore_db_dirs_array); + + return false; +} + + +/** + Check if a directory name is in the hash of ignored directories. + + @return search result + @retval TRUE found + @retval FALSE not found +*/ + +static inline bool +is_in_ignore_db_dirs_list(const char *directory) +{ + return ignore_db_dirs_hash.records && + NULL != my_hash_search(&ignore_db_dirs_hash, (const uchar *) directory, + strlen(directory)); +} + + +/** + Check if a database name is in the hash of ignored directories. + + @return search result + @retval TRUE found + @retval FALSE not found +*/ + +bool +db_name_is_in_ignore_db_dirs_list(const char *directory) +{ + char buff[FN_REFLEN]; + uint buff_len; + + if (skip_ignored_dir_check) + return 0; + + buff_len= tablename_to_filename(directory, buff, sizeof(buff)); + + return my_hash_search(&ignore_db_dirs_hash, (uchar *) buff, buff_len)!=NULL; +} + + /*************************************************************************** List all column types ***************************************************************************/ @@ -552,6 +830,9 @@ find_files(THD *thd, List *files, const char *db, if (!MY_S_ISDIR(file->mystat->st_mode)) continue; + if (is_in_ignore_db_dirs_list(file->name)) + continue; + file_name_len= filename_to_tablename(file->name, uname, sizeof(uname)); if (wild) { diff --git a/sql/sql_show.h b/sql/sql_show.h index fec73122e8b..e3077c560d7 100644 --- a/sql/sql_show.h +++ b/sql/sql_show.h @@ -41,4 +41,13 @@ int view_store_create_info(THD *thd, TABLE_LIST *table, String *buff); int copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table); + +/* Handle the ignored database directories list for SHOW/I_S. */ +bool ignore_db_dirs_init(); +void ignore_db_dirs_free(); +void ignore_db_dirs_reset(); +bool ignore_db_dirs_process_additions(); +bool push_ignored_db_dir(char *path); +extern char *opt_ignore_db_dirs; + #endif /* SQL_SHOW_H */ diff --git a/sql/table.cc b/sql/table.cc index 2be94c55205..0247dc167ee 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3197,6 +3197,9 @@ bool check_db_name(LEX_STRING *org_name) if (lower_case_table_names && name != any_db) my_casedn_str(files_charset_info, name); + if (db_name_is_in_ignore_db_dirs_list(name)) + return 1; + return check_table_name(name, name_length, check_for_path_chars); } From 5e366d063d073d0f43acf34250ba217d31012df8 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 27 Sep 2012 12:25:45 +0200 Subject: [PATCH 07/14] Fix incorrect assembler in Taocrypt which causes crashes on i386 with certain GCC versions/options --- extra/yassl/taocrypt/include/misc.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/extra/yassl/taocrypt/include/misc.hpp b/extra/yassl/taocrypt/include/misc.hpp index b6925f916f8..c58713855dd 100644 --- a/extra/yassl/taocrypt/include/misc.hpp +++ b/extra/yassl/taocrypt/include/misc.hpp @@ -136,9 +136,13 @@ void CleanUp(); // Turn on ia32 ASM for Big Integer // CodeWarrior defines _MSC_VER +// +// Do not use assembler with GCC, as the implementation for it is broken; +// it does not use proper GCC asm contraints and makes assumptions about +// frame pointers and so on, which breaks depending on GCC version and +// optimization level. #if !defined(TAOCRYPT_DISABLE_X86ASM) && ((defined(_MSC_VER) && \ - !defined(__MWERKS__) && defined(_M_IX86)) || \ - (defined(__GNUC__) && defined(__i386__))) + !defined(__MWERKS__) && defined(_M_IX86))) #define TAOCRYPT_X86ASM_AVAILABLE #endif From e290d2bed52b0d5d930a0bc3362008ddb27915a6 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 28 Sep 2012 09:54:43 +0200 Subject: [PATCH 08/14] Fix compiler warnings that breaks build (-Werror). --- sql/sql_show.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 562ccea488f..e01e75db00f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -568,8 +568,7 @@ ignore_db_dirs_process_additions() if (skip_ignored_dir_check) { char buff[FN_REFLEN]; - uint buff_len; - buff_len= tablename_to_filename(dir->str, buff, sizeof(buff)); + (void) tablename_to_filename(dir->str, buff, sizeof(buff)); skip_ignored_dir_check= strcmp(dir->str, buff) != 0; } } From 66bd2b56fce6be2a083ef04b593fb0f8e644d5b4 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 29 Sep 2012 22:44:13 -0700 Subject: [PATCH 09/14] Fixed LP bug #1058071 (mdev-564). In some rare cases when the value of the system variable join_buffer_size was set to a number less than 256 the function JOIN_CACHE::set_constants determined the size of an offset in the join buffer equal to 1 though the minimal join buffer required more than 256 bytes. This could cause a crash of the server when records from the join buffer were read. --- mysql-test/r/join_cache.result | 50 ++++++++++++++++++++ mysql-test/r/select.result | 70 ++++++++++++++-------------- mysql-test/r/select_jcl6.result | 56 +++++++++++----------- mysql-test/r/select_pkeycache.result | 70 ++++++++++++++-------------- mysql-test/t/join_cache.test | 49 +++++++++++++++++++ mysql-test/t/select.test | 2 +- sql/sql_join_cache.cc | 29 ++++++++++-- 7 files changed, 223 insertions(+), 103 deletions(-) diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index 380e6dd0e46..2c634c3d92b 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -5586,4 +5586,54 @@ set join_buffer_size=default; set join_cache_level=default; set optimizer_switch=@tmp_optimizer_switch; DROP TABLE t1,t2,t3; +# +# Bug #1058071: LEFT JOIN using blobs +# (mdev-564) when join buffer size is small +# +CREATE TABLE t1 ( +col269 decimal(31,10) unsigned DEFAULT NULL, +col280 multipoint DEFAULT NULL, +col281 tinyint(1) DEFAULT NULL, +col282 time NOT NULL, +col284 datetime DEFAULT NULL, +col286 date DEFAULT NULL, +col287 datetime DEFAULT NULL, +col288 decimal(30,29) DEFAULT NULL, +col291 time DEFAULT NULL, +col292 time DEFAULT NULL +) ENGINE=Aria; +INSERT INTO t1 VALUES +(0.0,PointFromText('POINT(9 0)'),0,'11:24:05','2013-04-14 21:30:28',NULL,'2011-12-20 06:00:34',9.9,'13:04:39',NULL), +(0.0,NULL,127,'05:43:12','2012-09-05 06:15:27','2027-01-01','2011-10-29 10:48:29',0.0,'06:24:05','11:33:37'), +(0.0,NULL,127,'12:54:41','2013-01-12 11:32:58','2011-11-03','2013-01-03 02:00:34',00,'11:54:15','20:19:15'), +(0.0,PointFromText('POINT(9 0)'),0,'19:48:07','2012-07-16 15:45:25','2012-03-25','2013-09-07 17:21:52',0.5,'17:36:54','21:24:19'), +(0.0,PointFromText('POINT(9 0)'),0,'03:43:48','2012-09-28 00:00:00','2012-06-26','2011-11-16 05:01:09',00,'01:25:42','19:30:06'), +(0.0,LineStringFromText('LINESTRING(0 0,9 9,0 0,9 0,0 0)'),127,'11:33:21','2012-03-31 10:29:22','2012-10-10','2012-04-21 19:21:06',NULL,'05:13:22','09:48:34'), +(NULL,PointFromText('POINT(9 0)'),127,'00:00:00','0000-00-00','2012-04-04 21:26:12','2013-03-04',0.0,'12:54:30',NULL), +(NULL,PointFromText('POINT(9 0)'),1,'00:00:00','2013-05-01 22:37:49','2013-06-26','2012-09-22 17:31:03',0.0,'08:09:57','11:15:36'); +Warnings: +Note 1265 Data truncated for column 'col286' at row 7 +CREATE TABLE t2 (b int) ENGINE=Aria; +INSERT INTO t2 VALUES (NULL); +CREATE TABLE t3 (c int) ENGINE=Aria; +INSERT INTO t3 VALUES (NULL); +set @tmp_optimizer_switch=@@optimizer_switch; +set optimizer_switch = 'outer_join_with_cache=on,join_cache_incremental=on'; +set join_buffer_size=128; +Warnings: +Warning 1292 Truncated incorrect join_buffer_size value: '128' +EXPLAIN +SELECT 1 AS c FROM t1 NATURAL LEFT JOIN t2 LEFT OUTER JOIN t3 ON 1 +GROUP BY elt(t1.col282,1,t1.col280); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 8 Using temporary; Using filesort +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join) +SELECT 1 AS c FROM t1 NATURAL LEFT JOIN t2 LEFT OUTER JOIN t3 ON 1 +GROUP BY elt(t1.col282,1,t1.col280); +c +1 +set join_buffer_size=default; +set optimizer_switch=@tmp_optimizer_switch; +DROP table t1,t2,t3; set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 51e347ab728..5a234c17409 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4817,7 +4817,7 @@ CREATE TABLE t5 (f1 int) ; INSERT INTO t5 VALUES (20),(5); CREATE TABLE t6(f1 int); INSERT INTO t6 VALUES (9),(7); -SET SESSION join_buffer_size = 2048; +SET SESSION join_buffer_size = 2176; EXPLAIN SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; id select_type table type possible_keys key key_len ref rows Extra @@ -4831,50 +4831,50 @@ SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; f1 f1 f1 f1 f2 f1 f1 3 9 NULL NULL NULL 20 9 7 9 NULL NULL NULL 20 9 -3 9 NULL NULL NULL 20 7 -7 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 5 9 -7 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 5 7 18 9 NULL NULL NULL 20 9 3 9 NULL NULL NULL 20 9 -18 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 20 7 -18 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 5 9 -18 9 NULL NULL NULL 5 7 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 20 9 -18 9 NULL NULL NULL 20 9 -7 9 NULL NULL NULL 20 7 -18 9 NULL NULL NULL 20 7 -7 9 NULL NULL NULL 5 9 -18 9 NULL NULL NULL 5 9 -7 9 NULL NULL NULL 5 7 -18 9 NULL NULL NULL 5 7 -3 9 NULL NULL NULL 20 9 7 9 NULL NULL NULL 20 9 3 9 NULL NULL NULL 20 7 7 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 5 9 -7 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 5 7 -18 9 NULL NULL NULL 20 9 -3 9 NULL NULL NULL 20 9 18 9 NULL NULL NULL 20 7 3 9 NULL NULL NULL 20 7 -18 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 5 9 -18 9 NULL NULL NULL 5 7 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 20 9 -18 9 NULL NULL NULL 20 9 7 9 NULL NULL NULL 20 7 -18 9 NULL NULL NULL 20 7 +18 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 5 9 7 9 NULL NULL NULL 5 9 18 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 9 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 20 7 +18 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 20 9 +7 9 NULL NULL NULL 20 9 +18 9 NULL NULL NULL 20 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 20 7 +7 9 NULL NULL NULL 20 7 +18 9 NULL NULL NULL 20 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 9 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 5 7 7 9 NULL NULL NULL 5 7 18 9 NULL NULL NULL 5 7 SET SESSION join_buffer_size = DEFAULT; diff --git a/mysql-test/r/select_jcl6.result b/mysql-test/r/select_jcl6.result index 6eaa85a9efe..b7f278a327f 100644 --- a/mysql-test/r/select_jcl6.result +++ b/mysql-test/r/select_jcl6.result @@ -4828,7 +4828,7 @@ CREATE TABLE t5 (f1 int) ; INSERT INTO t5 VALUES (20),(5); CREATE TABLE t6(f1 int); INSERT INTO t6 VALUES (9),(7); -SET SESSION join_buffer_size = 2048; +SET SESSION join_buffer_size = 2176; EXPLAIN SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; id select_type table type possible_keys key key_len ref rows Extra @@ -4843,48 +4843,48 @@ f1 f1 f1 f1 f2 f1 f1 3 9 NULL NULL NULL 20 9 7 9 NULL NULL NULL 20 9 18 9 NULL NULL NULL 20 9 -3 9 NULL NULL NULL 5 9 -7 9 NULL NULL NULL 5 9 -18 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 20 7 -7 9 NULL NULL NULL 20 7 -18 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 5 7 -18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 20 9 +7 9 NULL NULL NULL 20 9 +18 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 20 9 +7 9 NULL NULL NULL 20 9 +18 9 NULL NULL NULL 20 9 3 9 NULL NULL NULL 20 9 7 9 NULL NULL NULL 20 9 18 9 NULL NULL NULL 20 9 3 9 NULL NULL NULL 5 9 7 9 NULL NULL NULL 5 9 18 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 20 7 -7 9 NULL NULL NULL 20 7 -18 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 5 7 -18 9 NULL NULL NULL 5 7 -3 9 NULL NULL NULL 20 9 -7 9 NULL NULL NULL 20 9 -18 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 9 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 9 3 9 NULL NULL NULL 5 9 7 9 NULL NULL NULL 5 9 18 9 NULL NULL NULL 5 9 3 9 NULL NULL NULL 20 7 7 9 NULL NULL NULL 20 7 18 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 5 7 -18 9 NULL NULL NULL 5 7 -3 9 NULL NULL NULL 20 9 -7 9 NULL NULL NULL 20 9 -18 9 NULL NULL NULL 20 9 -3 9 NULL NULL NULL 5 9 -7 9 NULL NULL NULL 5 9 -18 9 NULL NULL NULL 5 9 3 9 NULL NULL NULL 20 7 7 9 NULL NULL NULL 20 7 18 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 20 7 +7 9 NULL NULL NULL 20 7 +18 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 20 7 +7 9 NULL NULL NULL 20 7 +18 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 7 3 9 NULL NULL NULL 5 7 7 9 NULL NULL NULL 5 7 18 9 NULL NULL NULL 5 7 diff --git a/mysql-test/r/select_pkeycache.result b/mysql-test/r/select_pkeycache.result index 51e347ab728..5a234c17409 100644 --- a/mysql-test/r/select_pkeycache.result +++ b/mysql-test/r/select_pkeycache.result @@ -4817,7 +4817,7 @@ CREATE TABLE t5 (f1 int) ; INSERT INTO t5 VALUES (20),(5); CREATE TABLE t6(f1 int); INSERT INTO t6 VALUES (9),(7); -SET SESSION join_buffer_size = 2048; +SET SESSION join_buffer_size = 2176; EXPLAIN SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; id select_type table type possible_keys key key_len ref rows Extra @@ -4831,50 +4831,50 @@ SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; f1 f1 f1 f1 f2 f1 f1 3 9 NULL NULL NULL 20 9 7 9 NULL NULL NULL 20 9 -3 9 NULL NULL NULL 20 7 -7 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 5 9 -7 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 5 7 18 9 NULL NULL NULL 20 9 3 9 NULL NULL NULL 20 9 -18 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 20 7 -18 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 5 9 -18 9 NULL NULL NULL 5 7 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 20 9 -18 9 NULL NULL NULL 20 9 -7 9 NULL NULL NULL 20 7 -18 9 NULL NULL NULL 20 7 -7 9 NULL NULL NULL 5 9 -18 9 NULL NULL NULL 5 9 -7 9 NULL NULL NULL 5 7 -18 9 NULL NULL NULL 5 7 -3 9 NULL NULL NULL 20 9 7 9 NULL NULL NULL 20 9 3 9 NULL NULL NULL 20 7 7 9 NULL NULL NULL 20 7 -3 9 NULL NULL NULL 5 9 -7 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 5 7 -18 9 NULL NULL NULL 20 9 -3 9 NULL NULL NULL 20 9 18 9 NULL NULL NULL 20 7 3 9 NULL NULL NULL 20 7 -18 9 NULL NULL NULL 5 9 -3 9 NULL NULL NULL 5 9 -18 9 NULL NULL NULL 5 7 -3 9 NULL NULL NULL 5 7 -7 9 NULL NULL NULL 20 9 -18 9 NULL NULL NULL 20 9 7 9 NULL NULL NULL 20 7 -18 9 NULL NULL NULL 20 7 +18 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 5 9 7 9 NULL NULL NULL 5 9 18 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 9 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 5 7 +7 9 NULL NULL NULL 20 7 +18 9 NULL NULL NULL 20 9 +3 9 NULL NULL NULL 20 9 +7 9 NULL NULL NULL 20 9 +18 9 NULL NULL NULL 20 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 20 7 +3 9 NULL NULL NULL 20 7 +7 9 NULL NULL NULL 20 7 +18 9 NULL NULL NULL 20 7 +7 9 NULL NULL NULL 5 7 +18 9 NULL NULL NULL 5 9 +3 9 NULL NULL NULL 5 9 +7 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 9 +18 9 NULL NULL NULL 5 7 +3 9 NULL NULL NULL 5 7 7 9 NULL NULL NULL 5 7 18 9 NULL NULL NULL 5 7 SET SESSION join_buffer_size = DEFAULT; diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index 0962f1bf766..eabab4891ce 100644 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -3587,5 +3587,54 @@ set optimizer_switch=@tmp_optimizer_switch; DROP TABLE t1,t2,t3; +--echo # +--echo # Bug #1058071: LEFT JOIN using blobs +--echo # (mdev-564) when join buffer size is small +--echo # + +CREATE TABLE t1 ( + col269 decimal(31,10) unsigned DEFAULT NULL, + col280 multipoint DEFAULT NULL, + col281 tinyint(1) DEFAULT NULL, + col282 time NOT NULL, + col284 datetime DEFAULT NULL, + col286 date DEFAULT NULL, + col287 datetime DEFAULT NULL, + col288 decimal(30,29) DEFAULT NULL, + col291 time DEFAULT NULL, + col292 time DEFAULT NULL +) ENGINE=Aria; + +INSERT INTO t1 VALUES +(0.0,PointFromText('POINT(9 0)'),0,'11:24:05','2013-04-14 21:30:28',NULL,'2011-12-20 06:00:34',9.9,'13:04:39',NULL), +(0.0,NULL,127,'05:43:12','2012-09-05 06:15:27','2027-01-01','2011-10-29 10:48:29',0.0,'06:24:05','11:33:37'), +(0.0,NULL,127,'12:54:41','2013-01-12 11:32:58','2011-11-03','2013-01-03 02:00:34',00,'11:54:15','20:19:15'), +(0.0,PointFromText('POINT(9 0)'),0,'19:48:07','2012-07-16 15:45:25','2012-03-25','2013-09-07 17:21:52',0.5,'17:36:54','21:24:19'), +(0.0,PointFromText('POINT(9 0)'),0,'03:43:48','2012-09-28 00:00:00','2012-06-26','2011-11-16 05:01:09',00,'01:25:42','19:30:06'), +(0.0,LineStringFromText('LINESTRING(0 0,9 9,0 0,9 0,0 0)'),127,'11:33:21','2012-03-31 10:29:22','2012-10-10','2012-04-21 19:21:06',NULL,'05:13:22','09:48:34'), +(NULL,PointFromText('POINT(9 0)'),127,'00:00:00','0000-00-00','2012-04-04 21:26:12','2013-03-04',0.0,'12:54:30',NULL), +(NULL,PointFromText('POINT(9 0)'),1,'00:00:00','2013-05-01 22:37:49','2013-06-26','2012-09-22 17:31:03',0.0,'08:09:57','11:15:36'); + +CREATE TABLE t2 (b int) ENGINE=Aria; +INSERT INTO t2 VALUES (NULL); +CREATE TABLE t3 (c int) ENGINE=Aria; +INSERT INTO t3 VALUES (NULL); + +set @tmp_optimizer_switch=@@optimizer_switch; +set optimizer_switch = 'outer_join_with_cache=on,join_cache_incremental=on'; +set join_buffer_size=128; + +EXPLAIN +SELECT 1 AS c FROM t1 NATURAL LEFT JOIN t2 LEFT OUTER JOIN t3 ON 1 + GROUP BY elt(t1.col282,1,t1.col280); + +SELECT 1 AS c FROM t1 NATURAL LEFT JOIN t2 LEFT OUTER JOIN t3 ON 1 + GROUP BY elt(t1.col282,1,t1.col280); + +set join_buffer_size=default; +set optimizer_switch=@tmp_optimizer_switch; + +DROP table t1,t2,t3; + # this must be the last command in the file set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index b937462e3e9..890da70caad 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -4126,7 +4126,7 @@ INSERT INTO t5 VALUES (20),(5); CREATE TABLE t6(f1 int); INSERT INTO t6 VALUES (9),(7); -SET SESSION join_buffer_size = 2048; +SET SESSION join_buffer_size = 2176; EXPLAIN SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 5c803f85c49..1121c591c3b 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -680,7 +680,23 @@ void JOIN_CACHE::set_constants() uint len= length + fields*sizeof(uint)+blobs*sizeof(uchar *) + (prev_cache ? prev_cache->get_size_of_rec_offset() : 0) + sizeof(ulong); - buff_size= max(join->thd->variables.join_buff_size, 2*len); + /* + The values of size_of_rec_ofs, size_of_rec_len, size_of_fld_ofs, + base_prefix_length, pack_length, pack_length_with_blob_ptrs + will be recalculated later in this function when we get the estimate + for the actual value of the join buffer size. + */ + size_of_rec_ofs= size_of_rec_len= size_of_fld_ofs= 4; + base_prefix_length= (with_length ? size_of_rec_len : 0) + + (prev_cache ? prev_cache->get_size_of_rec_offset() : 0); + pack_length= (with_length ? size_of_rec_len : 0) + + (prev_cache ? prev_cache->get_size_of_rec_offset() : 0) + + length + fields*sizeof(uint); + pack_length_with_blob_ptrs= pack_length + blobs*sizeof(uchar *); + min_buff_size= 0; + min_records= 1; + buff_size= max(join->thd->variables.join_buff_size, + get_min_join_buffer_size()); size_of_rec_ofs= offset_size(buff_size); size_of_rec_len= blobs ? size_of_rec_ofs : offset_size(len); size_of_fld_ofs= size_of_rec_len; @@ -753,19 +769,24 @@ ulong JOIN_CACHE::get_min_join_buffer_size() if (!min_buff_size) { size_t len= 0; + size_t len_last= 0; for (JOIN_TAB *tab= start_tab; tab != join_tab; tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS)) { len+= tab->get_max_used_fieldlength(); + len_last=+ tab->get_used_fieldlength(); } - len+= get_record_max_affix_length() + get_max_key_addon_space_per_record(); - size_t min_sz= len*min_records; + size_t len_addon= get_record_max_affix_length() + + get_max_key_addon_space_per_record(); + len+= len_addon; + len_last+= len_addon; + size_t min_sz= len*(min_records-1) + len_last; + min_sz+= pack_length_with_blob_ptrs; size_t add_sz= 0; for (uint i=0; i < min_records; i++) add_sz+= join_tab_scan->aux_buffer_incr(i+1); avg_aux_buffer_incr= add_sz/min_records; min_sz+= add_sz; - min_sz+= pack_length_with_blob_ptrs; set_if_bigger(min_sz, 1); min_buff_size= min_sz; } From 9bf8a5937fe542b6da10f3acc866df1cf4a145d1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 1 Oct 2012 15:42:49 +0200 Subject: [PATCH 10/14] increase the version --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 0a7651f37bb..84eca46fae0 100644 --- a/configure.in +++ b/configure.in @@ -13,7 +13,7 @@ dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MariaDB Server], [5.3.8-MariaDB], [], [mysql]) +AC_INIT([MariaDB Server], [5.3.9-MariaDB], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From c56fd181bff92dd377b4664583d4fe04ead16ac7 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 1 Oct 2012 19:04:17 -0700 Subject: [PATCH 11/14] Added the reported test case for LP bug #823237 (a duplicate of bug #823189). --- mysql-test/r/view.result | 49 ++++++++++++++++++++++++++++++++++++++++ mysql-test/t/view.test | 40 ++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index fc60d70317e..c8546f92bf9 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -4414,6 +4414,55 @@ a a DROP VIEW v1; DROP TABLE t1,t2,t3,t4; # +# LP bug #823237: dependent subquery with LEFT JOIN +# referencing view in WHERE +# (duplicate of LP bug #823189) +# +CREATE TABLE t1 (a int); +CREATE TABLE t2 ( b int, d int, e int); +INSERT INTO t2 VALUES (7,8,0); +CREATE TABLE t3 ( c int); +INSERT INTO t3 VALUES (0); +CREATE TABLE t4 (a int, b int, c int); +INSERT INTO t4 VALUES (93,1,0), (95,NULL,0); +CREATE VIEW v4 AS SELECT * FROM t4; +EXPLAIN EXTENDED +SELECT * FROM t3 , t4 +WHERE t4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d ) +WHERE t2.b > t4.b); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 system NULL NULL NULL NULL 1 100.00 +1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where +2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1 100.00 +2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found +Warnings: +Note 1276 Field or reference 'test.t4.b' of SELECT #2 was resolved in SELECT #1 +Note 1003 select 0 AS `c`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t3` join `test`.`t4` where (`test`.`t4`.`c` <= <`test`.`t4`.`b`>((select 0 from `test`.`t2` left join `test`.`t1` on(0) where (7 > `test`.`t4`.`b`)))) +SELECT * FROM t3 , t4 +WHERE t4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d ) +WHERE t2.b > t4.b); +c a b c +0 93 1 0 +EXPLAIN EXTENDED +SELECT * FROM t3, v4 +WHERE v4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d ) +WHERE t2.b > v4.b); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 system NULL NULL NULL NULL 1 100.00 +1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where +2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1 100.00 +2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found +Warnings: +Note 1276 Field or reference 'v4.b' of SELECT #2 was resolved in SELECT #1 +Note 1003 select 0 AS `c`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t3` join `test`.`t4` where (`test`.`t4`.`c` <= <`test`.`t4`.`b`>((select 0 from `test`.`t2` left join `test`.`t1` on(0) where (7 > `test`.`t4`.`b`)))) +SELECT * FROM t3, v4 +WHERE v4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d ) +WHERE t2.b > v4.b); +c a b c +0 93 1 0 +DROP VIEW v4; +DROP TABLE t1,t2,t3,t4; +# # BUG#833600: Wrong result with view + outer join + uncorrelated subquery (non-semijoin) # CREATE TABLE t1 ( a int, b int ); diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index bd3b485034d..3b590140d56 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -4344,6 +4344,46 @@ DROP VIEW v1; DROP TABLE t1,t2,t3,t4; +--echo # +--echo # LP bug #823237: dependent subquery with LEFT JOIN +--echo # referencing view in WHERE +--echo # (duplicate of LP bug #823189) +--echo # + +CREATE TABLE t1 (a int); + +CREATE TABLE t2 ( b int, d int, e int); +INSERT INTO t2 VALUES (7,8,0); + +CREATE TABLE t3 ( c int); +INSERT INTO t3 VALUES (0); + +CREATE TABLE t4 (a int, b int, c int); +INSERT INTO t4 VALUES (93,1,0), (95,NULL,0); + +CREATE VIEW v4 AS SELECT * FROM t4; + +EXPLAIN EXTENDED +SELECT * FROM t3 , t4 + WHERE t4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d ) + WHERE t2.b > t4.b); +SELECT * FROM t3 , t4 + WHERE t4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d ) + WHERE t2.b > t4.b); + + +EXPLAIN EXTENDED +SELECT * FROM t3, v4 + WHERE v4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d ) + WHERE t2.b > v4.b); + +SELECT * FROM t3, v4 + WHERE v4.c <= (SELECT t2.e FROM t2 LEFT JOIN t1 ON ( t1.a = t2.d ) + WHERE t2.b > v4.b); + +DROP VIEW v4; +DROP TABLE t1,t2,t3,t4; + --echo # --echo # BUG#833600: Wrong result with view + outer join + uncorrelated subquery (non-semijoin) --echo # From b0d11675fb46f5db458896a9a17f03bd53d98e88 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 5 Oct 2012 12:26:55 +0300 Subject: [PATCH 12/14] Fix of MDEV-589. The problem was in incorrect detection of merged views in tem_direct_view_ref::used_tables() . --- mysql-test/r/view.result | 21 +++++++++++++++++++++ mysql-test/t/view.test | 23 +++++++++++++++++++++++ sql/item.cc | 4 ++-- sql/table.h | 1 + 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index c8546f92bf9..332d3dadef0 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -4567,6 +4567,27 @@ id id bbb iddqd val1 30631 NULL NULL NULL NULL drop view v2; drop table t1,t2; +# +# MDEV-589 (LP BUG#1007647) : +# Assertion `vcol_table == 0 || vcol_table == table' failed in +# fill_record(THD*, List&, List&, bool) +# +CREATE TABLE t1 (f1 INT, f2 INT); +CREATE TABLE t2 (f1 INT, f2 INT); +CREATE ALGORITHM=MERGE VIEW v1 AS SELECT a1.f1, a2.f2 FROM t1 AS a1, t1 AS a2; +CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM v1; +CREATE ALGORITHM=MERGE VIEW v3 AS SELECT a1.f1, a2.f2 FROM t1 AS a1, t2 AS a2; +CREATE ALGORITHM=MERGE VIEW v4 AS SELECT * FROM v3; +INSERT INTO v3 (f1, f2) VALUES (1, 2); +ERROR HY000: Can not modify more than one base table through a join view 'test.v3' +INSERT INTO v1 (f1, f2) VALUES (1, 2); +ERROR HY000: Can not modify more than one base table through a join view 'test.v1' +INSERT INTO v4 (f1, f2) VALUES (1, 2); +ERROR HY000: Can not modify more than one base table through a join view 'test.v4' +INSERT INTO v2 (f1, f2) VALUES (1, 2); +ERROR HY000: Can not modify more than one base table through a join view 'test.v2' +drop view v4,v3,v2,v1; +drop table t1,t2; # ----------------------------------------------------------------- # -- End of 5.3 tests. # ----------------------------------------------------------------- diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 3b590140d56..337af624813 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -4503,6 +4503,29 @@ create algorithm=MERGE view v2 as select 2 as id, id is null as bbb, id as iddqd select t1.*, v2.* from t1 left join v2 on t1.id = v2.id; drop view v2; drop table t1,t2; + +--echo # +--echo # MDEV-589 (LP BUG#1007647) : +--echo # Assertion `vcol_table == 0 || vcol_table == table' failed in +--echo # fill_record(THD*, List&, List&, bool) +--echo # +CREATE TABLE t1 (f1 INT, f2 INT); +CREATE TABLE t2 (f1 INT, f2 INT); +CREATE ALGORITHM=MERGE VIEW v1 AS SELECT a1.f1, a2.f2 FROM t1 AS a1, t1 AS a2; +CREATE ALGORITHM=MERGE VIEW v2 AS SELECT * FROM v1; +CREATE ALGORITHM=MERGE VIEW v3 AS SELECT a1.f1, a2.f2 FROM t1 AS a1, t2 AS a2; +CREATE ALGORITHM=MERGE VIEW v4 AS SELECT * FROM v3; +--error ER_VIEW_MULTIUPDATE +INSERT INTO v3 (f1, f2) VALUES (1, 2); +--error ER_VIEW_MULTIUPDATE +INSERT INTO v1 (f1, f2) VALUES (1, 2); +--error ER_VIEW_MULTIUPDATE +INSERT INTO v4 (f1, f2) VALUES (1, 2); +--error ER_VIEW_MULTIUPDATE +INSERT INTO v2 (f1, f2) VALUES (1, 2); +drop view v4,v3,v2,v1; +drop table t1,t2; + --echo # ----------------------------------------------------------------- --echo # -- End of 5.3 tests. --echo # ----------------------------------------------------------------- diff --git a/sql/item.cc b/sql/item.cc index 18a86aa2d1a..98c27266415 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -9175,7 +9175,7 @@ table_map Item_direct_view_ref::used_tables() const { return get_depended_from() ? OUTER_REF_TABLE_BIT : - ((view->merged || !view->table) ? + ((view->is_merged_derived() || view->merged || !view->table) ? (*ref)->used_tables() : view->table->map); } @@ -9184,7 +9184,7 @@ table_map Item_direct_view_ref::not_null_tables() const { return get_depended_from() ? 0 : - ((view->merged || !view->table) ? + ((view->is_merged_derived() || view->merged || !view->table) ? (*ref)->not_null_tables() : view->table->map); } diff --git a/sql/table.h b/sql/table.h index 8ce73162aaf..a2d3aa73f7e 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1600,6 +1600,7 @@ struct TABLE_LIST /* TRUE <=> derived table should be filled right after optimization. */ bool fill_me; /* TRUE <=> view/DT is merged. */ + /* TODO: replace with derived_type */ bool merged; bool merged_for_insert; /* TRUE <=> don't prepare this derived table/view as it should be merged.*/ From d2d6c8b8e8c973f6201b3472b7f451a9e16d0d44 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 10 Oct 2012 09:21:22 +0400 Subject: [PATCH 13/14] Backport of: olav.sandstaa@oracle.com-20120516074923-vd0dhp183vqcp2ql .. into MariaDB 5.3 Fix for Bug#12667154 SAME QUERY EXEC AS WHERE SUBQ GIVES DIFFERENT RESULTS ON IN() & NOT IN() COMP #3 This bug causes a wrong result in mysql-trunk when ICP is used and bad performance in mysql-5.5 and mysql-trunk. Using the query from bug report to explain what happens and causes the wrong result from the query when ICP is enabled: 1. The t3 table contains four records. The outer query will read these and for each of these it will execute the subquery. 2. Before the first execution of the subquery it will be optimized. In this case the important is what happens to the first table t1: -make_join_select() will call the range optimizer which decides that t1 should be accessed using a range scan on the k1 index It creates a QUICK_RANGE_SELECT object for this. -As the last part of optimization the ICP code pushes the condition down to the storage engine for table t1 on the k1 index. This produces the following information in the explain for this table: 2 DEPENDENT SUBQUERY t1 range k1 k1 5 NULL 3 Using index condition; Using filesort Note the use of filesort. 3. The first execution of the subquery does (among other things) due to the need for sorting: a. Call create_sort_index() which again will call find_all_keys(): b. find_all_keys() will read the required keys for all qualifying rows from the storage engine. To do this it checks if it has a quick-select for the table. It will use the quick-select for reading records. In this case it will read four records from the storage engine (based on the range criteria). The storage engine will evaluate the pushed index condition for each record. c. At the end of create_sort_index() there is code that cleans up a lot of stuff on the join tab. One of the things that is cleaned is the select object. The result of this is that the quick-select object created in make_join_select is deleted. 4. The second execution of the subquery does the same as the first but the result is different: a. Call create_sort_index() which again will call find_all_keys() (same as for the first execution) b. find_all_keys() will read the keys from the storage engine. To do this it checks if it has a quick-select for the table. Now there is NO quick-select object(!) (since it was deleted in step 3c). So find_all_keys defaults to read the table using a table scan instead. So instead of reading the four relevant records in the range it reads the entire table (6 records). It then evaluates the table's condition (and here it goes wrong). Since the entire condition has been pushed down to the storage engine using ICP all 6 records qualify. (Note that the storage engine will not evaluate the pushed index condition in this case since it was pushed for the k1 index and now we do a table scan without any index being used). The result is that here we return six qualifying key values instead of four due to not evaluating the table's condition. c. As above. 5. The two last execution of the subquery will also produce wrong results for the same reason. Summary: The problem occurs due to all but the first executions of the subquery is done as a table scan without evaluating the table's condition (which is pushed to the storage engine on a different index). This is caused by the create_sort_index() function deleting the quick-select object that should have been used for executing the subquery as a range scan. Note that this bug in addition to causing wrong results also can result in bad performance due to executing the subquery using a table scan instead of a range scan. This is an issue in MySQL 5.5. The fix for this problem is to avoid that the Quick-select-object that the optimizer created is deleted when create_sort_index() is doing clean-up of the join-tab. This will ensure that the quick-select object and the corresponding pushed index condition will be available and used by all following executions of the subquery. --- mysql-test/r/subselect2.result | 19 +++++++++++++++++++ mysql-test/t/subselect2.test | 19 +++++++++++++++++++ sql/sql_select.cc | 32 ++++++++++++++++++++++++++++---- 3 files changed, 66 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/subselect2.result b/mysql-test/r/subselect2.result index 41c445329cb..a7689c37a0a 100644 --- a/mysql-test/r/subselect2.result +++ b/mysql-test/r/subselect2.result @@ -179,4 +179,23 @@ pk a b SET optimizer_switch=@tmp_optimizer_switch; DROP VIEW v1; DROP TABLE t1,t2,t3; +# +# MDEV-567: Wrong result from a query with correlated subquery if ICP is allowed +# +CREATE TABLE t1 (a int, b int, INDEX idx(a)); +INSERT INTO t1 VALUES (9,0), (7,1), (1,9), (7,3), (2,1); +CREATE TABLE t2 (a int, b int, INDEX idx(a)); +INSERT INTO t2 VALUES (2,1), (6,4), (7,6), (9,4); +CREATE TABLE t3 (a int, b int); +INSERT INTO t3 VALUES (1,0), (1,1), (1,3); +SELECT * FROM t3 +WHERE a = (SELECT COUNT(DISTINCT t2.b) FROM t1, t2 +WHERE t1.a = t2.a AND t2.a BETWEEN 7 AND 9 +AND t3.b = t1.b +GROUP BY t1.b); +a b +1 0 +1 1 +1 3 +DROP TABLE t1, t2, t3; set optimizer_switch=@subselect2_test_tmp; diff --git a/mysql-test/t/subselect2.test b/mysql-test/t/subselect2.test index 8d2939bdb53..75cf842fbdb 100644 --- a/mysql-test/t/subselect2.test +++ b/mysql-test/t/subselect2.test @@ -203,5 +203,24 @@ SET optimizer_switch=@tmp_optimizer_switch; DROP VIEW v1; DROP TABLE t1,t2,t3; +--echo # +--echo # MDEV-567: Wrong result from a query with correlated subquery if ICP is allowed +--echo # +CREATE TABLE t1 (a int, b int, INDEX idx(a)); +INSERT INTO t1 VALUES (9,0), (7,1), (1,9), (7,3), (2,1); + +CREATE TABLE t2 (a int, b int, INDEX idx(a)); +INSERT INTO t2 VALUES (2,1), (6,4), (7,6), (9,4); + +CREATE TABLE t3 (a int, b int); +INSERT INTO t3 VALUES (1,0), (1,1), (1,3); + +SELECT * FROM t3 + WHERE a = (SELECT COUNT(DISTINCT t2.b) FROM t1, t2 + WHERE t1.a = t2.a AND t2.a BETWEEN 7 AND 9 + AND t3.b = t1.b + GROUP BY t1.b); +DROP TABLE t1, t2, t3; + set optimizer_switch=@subselect2_test_tmp; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5f2e97d57c1..438cec61c6d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -18687,6 +18687,14 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, /* Currently ORDER BY ... LIMIT is not supported in subqueries. */ DBUG_ASSERT(join->group_list || !join->is_in_subquery()); + /* + If we have a select->quick object that is created outside of + create_sort_index() and this is part of a subquery that + potentially can be executed multiple times then we should not + delete the quick object on exit from this function. + */ + bool keep_quick= select && select->quick && join->join_tab_save; + /* When there is SQL_BIG_RESULT do not sort using index for GROUP BY, and thus force sorting on disk unless a group min-max optimization @@ -18738,6 +18746,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, get_quick_select_for_ref(thd, table, &tab->ref, tab->found_records)))) goto err; + DBUG_ASSERT(!keep_quick); } } @@ -18769,10 +18778,25 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, tablesort_result_cache= table->sort.io_cache; table->sort.io_cache= NULL; - - select->cleanup(); // filesort did select - table->quick_keys.clear_all(); // as far as we cleanup select->quick - table->intersect_keys.clear_all(); + /* + If a quick object was created outside of create_sort_index() + that might be reused, then do not call select->cleanup() since + it will delete the quick object. + */ + if (!keep_quick) + { + select->cleanup(); + /* + The select object should now be ready for the next use. If it + is re-used then there exists a backup copy of this join tab + which has the pointer to it. The join tab will be restored in + JOIN::reset(). So here we just delete the pointer to it. + */ + tab->select= NULL; + // If we deleted the quick select object we need to clear quick_keys + table->quick_keys.clear_all(); + } + // Restore the output resultset table->sort.io_cache= tablesort_result_cache; } tab->set_select_cond(NULL, __LINE__); From 362c2bca3e170031d33622f27d978c9570d0a9f5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 10 Oct 2012 22:42:50 +0300 Subject: [PATCH 14/14] Fix of MDEV-3799. Find left table in right join (which turned to left join by reordering tables in join list but phisical order of tables of SELECT left as it was). --- mysql-test/r/derived_view.result | 6 ++++-- mysql-test/r/view.result | 22 ++++++++++++++++++++++ mysql-test/t/view.test | 23 +++++++++++++++++++++++ sql/table.cc | 9 +++++++++ 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result index 6061fbb8800..a4f7a71dcb5 100644 --- a/mysql-test/r/derived_view.result +++ b/mysql-test/r/derived_view.result @@ -1677,6 +1677,7 @@ SELECT t.b, t.c, t1.a FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t WHERE t.b AND t.c = t1.a; b c a +8 c c EXPLAIN EXTENDED SELECT t.b, t.c, t1.a FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t @@ -1691,6 +1692,7 @@ SELECT t.b, t.c, t1.a FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t WHERE t.b <> 0 AND t.c = t1.a; b c a +8 c c INSERT INTO t3 VALUES (100), (200); EXPLAIN EXTENDED SELECT t.b, t.c, t1.a @@ -1706,7 +1708,7 @@ SELECT t.b, t.c, t1.a FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t WHERE t.b AND t.c = t1.a; b c a -NULL NULL c +8 c c EXPLAIN EXTENDED SELECT t.b, t.c, t1.a FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t @@ -1721,7 +1723,7 @@ SELECT t.b, t.c, t1.a FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t WHERE t.b <> 0 AND t.c = t1.a; b c a -NULL NULL c +8 c c SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2,t3; # diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 332d3dadef0..c12bf8ada06 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -4588,6 +4588,28 @@ INSERT INTO v2 (f1, f2) VALUES (1, 2); ERROR HY000: Can not modify more than one base table through a join view 'test.v2' drop view v4,v3,v2,v1; drop table t1,t2; +# +# MDEV-3799 fix of above bugfix (MDEV-589) +# Wrong result (NULLs instead of real values) with RIGHT JOIN +# in a FROM subquery and derived_merge=on +# +CREATE TABLE t1 (f1 INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (4),(6); +CREATE TABLE t2 (f2 INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (7),(8); +SELECT * FROM ( +SELECT * FROM t1 RIGHT JOIN t2 ON f1 = f2 +) AS alias; +f1 f2 +NULL 7 +NULL 8 +SELECT * FROM ( +SELECT * FROM t2 LEFT JOIN t1 ON f1 = f2 +) AS alias; +f2 f1 +7 NULL +8 NULL +drop tables t1,t2; # ----------------------------------------------------------------- # -- End of 5.3 tests. # ----------------------------------------------------------------- diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 337af624813..3bed7d5dd93 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -4526,6 +4526,29 @@ INSERT INTO v2 (f1, f2) VALUES (1, 2); drop view v4,v3,v2,v1; drop table t1,t2; +--echo # +--echo # MDEV-3799 fix of above bugfix (MDEV-589) +--echo # Wrong result (NULLs instead of real values) with RIGHT JOIN +--echo # in a FROM subquery and derived_merge=on +--echo # + +CREATE TABLE t1 (f1 INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (4),(6); + +CREATE TABLE t2 (f2 INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (7),(8); + +SELECT * FROM ( + SELECT * FROM t1 RIGHT JOIN t2 ON f1 = f2 +) AS alias; + +SELECT * FROM ( + SELECT * FROM t2 LEFT JOIN t1 ON f1 = f2 +) AS alias; + +drop tables t1,t2; + + --echo # ----------------------------------------------------------------- --echo # -- End of 5.3 tests. --echo # ----------------------------------------------------------------- diff --git a/sql/table.cc b/sql/table.cc index 0247dc167ee..faa248f43f6 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4462,7 +4462,16 @@ TABLE *TABLE_LIST::get_real_join_table() tbl= (tbl->view != NULL ? tbl->view->select_lex.get_table_list() : tbl->derived->first_select()->get_table_list()); + + /* find left table in outer join on this level */ + while(tbl->outer_join & JOIN_TYPE_RIGHT) + { + DBUG_ASSERT(tbl->next_local); + tbl= tbl->next_local; + } + } + return tbl->table; }