diff --git a/mysql-test/extra/rpl_tests/rpl_log.test b/mysql-test/extra/rpl_tests/rpl_log.test index 116bdd1028e..c9d9a4214d2 100644 --- a/mysql-test/extra/rpl_tests/rpl_log.test +++ b/mysql-test/extra/rpl_tests/rpl_log.test @@ -77,11 +77,12 @@ connection slave; # to go into the relay log (the master always sends a fake one when replication # starts). start slave; -# -# This is timing out in pushbuild and should be changed to use -# wait_slave_status.inc -# -sleep 2; +--disable_query_log +--disable_result_log +let $result_pattern= '%127.0.0.1%root%master-bin.000002%slave-relay-bin.000007%Yes%Yes%0%0%None%'; +--source include/wait_slave_status.inc +--enable_query_log +--enable_result_log sync_with_master; flush logs; stop slave; diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 878c5cb5451..2a4e3555e3b 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -1 +1,56 @@ -drop table if exists t1; +drop table if exists t1,t2; +create table t1 ( +c_id int(11) not null default '0', +org_id int(11) default null, +unique key contacts$c_id (c_id), +key contacts$org_id (org_id) +) engine=innodb; +insert into t1 values +(2,null),(120,null),(141,null),(218,7), (128,1), +(151,2),(234,2),(236,2),(243,2),(255,2),(259,2),(232,3),(235,3),(238,3), +(246,3),(253,3),(269,3),(285,3),(291,3),(293,3),(131,4),(230,4),(231,4); +create table t2 ( +slai_id int(11) not null default '0', +owner_tbl int(11) default null, +owner_id int(11) default null, +sla_id int(11) default null, +inc_web int(11) default null, +inc_email int(11) default null, +inc_chat int(11) default null, +inc_csr int(11) default null, +inc_total int(11) default null, +time_billed int(11) default null, +activedate timestamp null default null, +expiredate timestamp null default null, +state int(11) default null, +sla_set int(11) default null, +unique key t2$slai_id (slai_id), +key t2$owner_id (owner_id), +key t2$sla_id (sla_id) +) engine=innodb; +insert into t2(slai_id, owner_tbl, owner_id, sla_id) values +(1,3,1,1), (3,3,10,2), (4,3,3,6), (5,3,2,5), (6,3,8,3), (7,3,9,7), +(8,3,6,8), (9,3,4,9), (10,3,5,10), (11,3,11,11), (12,3,7,12); +flush tables; +select si.slai_id +from t1 c join t2 si on +((si.owner_tbl = 3 and si.owner_id = c.org_id) or +( si.owner_tbl = 2 and si.owner_id = c.c_id)) +where +c.c_id = 218 and expiredate is null; +slai_id +12 +select * from t1 where org_id is null; +c_id org_id +2 NULL +120 NULL +141 NULL +select si.slai_id +from t1 c join t2 si on +((si.owner_tbl = 3 and si.owner_id = c.org_id) or +( si.owner_tbl = 2 and si.owner_id = c.c_id)) +where +c.c_id = 218 and expiredate is null; +slai_id +12 +drop table t1, t2; diff --git a/mysql-test/r/rpl_user_variables.result b/mysql-test/r/rpl_user_variables.result index b553d37a187..ed0d2782394 100644 --- a/mysql-test/r/rpl_user_variables.result +++ b/mysql-test/r/rpl_user_variables.result @@ -78,5 +78,6 @@ abcn1 abcn1n2 abc\def This is a test +insert into t1 select * FROM (select @var1 union select @var2) AS t2; drop table t1; stop slave; diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index b942b9fbc0d..f31e4d64789 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -1,5 +1,59 @@ -- source include/have_innodb.inc --disable_warnings -drop table if exists t1; +drop table if exists t1,t2; --enable_warnings + +# BUG#16798: Uninitialized row buffer reads in ref-or-null optimizer +# (repeatable only w/innodb). +create table t1 ( + c_id int(11) not null default '0', + org_id int(11) default null, + unique key contacts$c_id (c_id), + key contacts$org_id (org_id) +) engine=innodb; +insert into t1 values + (2,null),(120,null),(141,null),(218,7), (128,1), + (151,2),(234,2),(236,2),(243,2),(255,2),(259,2),(232,3),(235,3),(238,3), + (246,3),(253,3),(269,3),(285,3),(291,3),(293,3),(131,4),(230,4),(231,4); + +create table t2 ( + slai_id int(11) not null default '0', + owner_tbl int(11) default null, + owner_id int(11) default null, + sla_id int(11) default null, + inc_web int(11) default null, + inc_email int(11) default null, + inc_chat int(11) default null, + inc_csr int(11) default null, + inc_total int(11) default null, + time_billed int(11) default null, + activedate timestamp null default null, + expiredate timestamp null default null, + state int(11) default null, + sla_set int(11) default null, + unique key t2$slai_id (slai_id), + key t2$owner_id (owner_id), + key t2$sla_id (sla_id) +) engine=innodb; +insert into t2(slai_id, owner_tbl, owner_id, sla_id) values + (1,3,1,1), (3,3,10,2), (4,3,3,6), (5,3,2,5), (6,3,8,3), (7,3,9,7), + (8,3,6,8), (9,3,4,9), (10,3,5,10), (11,3,11,11), (12,3,7,12); + +flush tables; +select si.slai_id +from t1 c join t2 si on + ((si.owner_tbl = 3 and si.owner_id = c.org_id) or + ( si.owner_tbl = 2 and si.owner_id = c.c_id)) +where + c.c_id = 218 and expiredate is null; + +select * from t1 where org_id is null; +select si.slai_id +from t1 c join t2 si on + ((si.owner_tbl = 3 and si.owner_id = c.org_id) or + ( si.owner_tbl = 2 and si.owner_id = c.c_id)) +where + c.c_id = 218 and expiredate is null; + +drop table t1, t2; diff --git a/mysql-test/t/rpl_user_variables.test b/mysql-test/t/rpl_user_variables.test index cb2a1e1d853..cc0dd60d01b 100644 --- a/mysql-test/t/rpl_user_variables.test +++ b/mysql-test/t/rpl_user_variables.test @@ -55,6 +55,7 @@ SELECT * FROM t1 ORDER BY n; sync_slave_with_master; SELECT * FROM t1 ORDER BY n; connection master; +insert into t1 select * FROM (select @var1 union select @var2) AS t2; drop table t1; sync_slave_with_master; stop slave; diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 83bc8ce8954..744a4791307 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -31,7 +31,6 @@ Usage: $0 [OPTIONS] --defaults-file=FILE Use the specified defaults file --defaults-extra-file=FILE Also use defaults from the specified file --ledir=DIRECTORY Look for mysqld in the specified directory - --log-error=FILE Log errors to the specified log file --open-files-limit=LIMIT Limit the number of open files --core-file-size=LIMIT Limit core files to the specified size --timezone=TZ Set the system timezone @@ -46,6 +45,11 @@ EOF exit 1 } +shell_quote_string() { + # This sed command makes sure that any special chars are quoted, + # so the arg gets passed exactly to the server. + echo "$1" | sed -e 's,\([^a-zA-Z0-9/_.=-]\),\\\1,g' +} parse_arguments() { # We only need to pass arguments through to the server if we don't @@ -69,14 +73,14 @@ parse_arguments() { --pid-file=*) pid_file=`echo "$arg" | sed -e "s;--pid-file=;;"` ;; --user=*) user=`echo "$arg" | sed -e "s;--[^=]*=;;"` ; SET_USER=1 ;; - # these two might have been set in a [mysqld_safe] section of my.cnf + # these might have been set in a [mysqld_safe] section of my.cnf # they are added to mysqld command line to override settings from my.cnf + --log-error=*) err_log=`echo "$arg" | sed -e "s;--log-error=;;"` ;; --socket=*) mysql_unix_port=`echo "$arg" | sed -e "s;--socket=;;"` ;; --port=*) mysql_tcp_port=`echo "$arg" | sed -e "s;--port=;;"` ;; # mysqld_safe-specific options - must be set in my.cnf ([mysqld_safe])! --ledir=*) ledir=`echo "$arg" | sed -e "s;--ledir=;;"` ;; - --log-error=*) err_log=`echo "$arg" | sed -e "s;--log-error=;;"` ;; --open-files-limit=*) open_files=`echo "$arg" | sed -e "s;--open-files-limit=;;"` ;; --core-file-size=*) core_file_size=`echo "$arg" | sed -e "s;--core-file-size=;;"` ;; --timezone=*) TZ=`echo "$arg" | sed -e "s;--timezone=;;"` ; export TZ; ;; @@ -97,9 +101,7 @@ parse_arguments() { *) if test -n "$pick_args" then - # This sed command makes sure that any special chars are quoted, - # so the arg gets passed exactly to the server. - args="$args "`echo "$arg" | sed -e 's,\([^a-zA-Z0-9_.-]\),\\\\\1,g'` + append_arg_to_args "$arg" fi ;; esac @@ -194,6 +196,10 @@ else print_defaults="my_print_defaults" fi +append_arg_to_args () { + args="$args "`shell_quote_string "$1"` +} + args= SET_USER=2 parse_arguments `$print_defaults $defaults --loose-verbose mysqld server` @@ -239,15 +245,39 @@ else * ) pid_file="$DATADIR/$pid_file" ;; esac fi -test -z "$err_log" && err_log=$DATADIR/`@HOSTNAME@`.err +append_arg_to_args "--pid-file=$pid_file" + +if [ -n "$err_log" ] +then + # mysqld adds ".err" if there is no extension on the --log-err + # argument; must match that here, or mysqld_safe will write to a + # different log file than mysqld + + # mysqld does not add ".err" to "--log-error=foo."; it considers a + # trailing "." as an extension + if expr "$err_log" : '.*\.[^/]*$' > /dev/null + then + : + else + err_log="$err_log".err + fi + + case "$err_log" in + /* ) ;; + * ) err_log="$DATADIR/$err_log" ;; + esac +else + err_log=$DATADIR/`@HOSTNAME@`.err +fi +append_arg_to_args "--log-error=$err_log" if test -n "$mysql_unix_port" then - args="--socket=$mysql_unix_port $args" + append_arg_to_args "--socket=$mysql_unix_port" fi if test -n "$mysql_tcp_port" then - args="--port=$mysql_tcp_port $args" + append_arg_to_args "--port=$mysql_tcp_port" fi if test $niceness -eq 0 @@ -314,7 +344,7 @@ then if test -n "$open_files" then ulimit -n $open_files - args="--open-files-limit=$open_files $args" + append_arg_to_args "--open-files-limit=$open_files" fi if test -n "$core_file_size" then @@ -372,12 +402,18 @@ echo "`date +'%y%m%d %H:%M:%S mysqld started'`" >> $err_log while true do rm -f $safe_mysql_unix_port $pid_file # Some extra safety - if test -z "$args" - then - $NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file=$pid_file @MYSQLD_DEFAULT_SWITCHES@ >> $err_log 2>&1 - else - eval "$NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file=$pid_file @MYSQLD_DEFAULT_SWITCHES@ $args >> $err_log 2>&1" - fi + + cmd="$NOHUP_NICENESS" + + for i in "$ledir/$MYSQLD" "$defaults" "--basedir=$MY_BASEDIR_VERSION" \ + "--datadir=$DATADIR" "$USER_OPTION" + do + cmd="$cmd "`shell_quote_string "$i"` + done + cmd="$cmd $args >> "`shell_quote_string "$err_log"`" 2>&1" + #echo "Running mysqld: [$cmd]" + eval "$cmd" + if test ! -f $pid_file # This is removed if normal shutdown then echo "STOPPING server from pid file $pid_file" diff --git a/sql/handlerton-win.cc b/sql/handlerton-win.cc new file mode 100644 index 00000000000..9ce4eab2444 --- /dev/null +++ b/sql/handlerton-win.cc @@ -0,0 +1,72 @@ +#include "mysql_priv.h" + +extern handlerton heap_hton; +extern handlerton myisam_hton; +extern handlerton myisammrg_hton; +extern handlerton binlog_hton; +#ifdef WITH_INNOBASE_STORAGE_ENGINE +extern handlerton innobase_hton; +#endif +#ifdef WITH_BERKELEY_STORAGE_ENGINE +extern handlerton berkeley_hton; +#endif +#ifdef WITH_EXAMPLE_STORAGE_ENGINE +extern handlerton example_hton; +#endif +#ifdef WITH_ARCHIVE_STORAGE_ENGINE +extern handlerton archive_hton; +#endif +#ifdef WITH_CSV_STORAGE_ENGINE +extern handlerton tina_hton; +#endif +#ifdef WITH_BLACKHOLE_STORAGE_ENGINE +extern handlerton blackhole_hton; +#endif +#ifdef WITH_FEDERATED_STORAGE_ENGINE +extern handlerton federated_hton; +#endif +#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE +extern handlerton ndbcluster_hton; +#endif +#ifdef WITH_PARTITION_STORAGE_ENGINE +extern handlerton partition_hton; +#endif + +/* + This array is used for processing compiled in engines. +*/ +handlerton *sys_table_types[]= +{ + &heap_hton, + &myisam_hton, +#ifdef WITH_INNOBASE_STORAGE_ENGINE + &innobase_hton, +#endif +#ifdef WITH_BERKELEY_STORAGE_ENGINE + &berkeley_hton, +#endif +#ifdef WITH_EXAMPLE_STORAGE_ENGINE + &example_hton, +#endif +#ifdef WITH_ARCHIVE_STORAGE_ENGINE + &archive_hton, +#endif +#ifdef WITH_CSV_STORAGE_ENGINE + &tina_hton, +#endif +#ifdef WITH_BLACKHOLE_STORAGE_ENGINE + &blackhole_hton, +#endif +#ifdef WITH_FEDERATED_STORAGE_ENGINE + &federated_hton, +#endif +#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE + &ndbcluster_hton, +#endif +#ifdef WITH_PARTITION_STORAGE_ENGINE + &partition_hton, +#endif + &myisammrg_hton, + &binlog_hton, + NULL +}; diff --git a/sql/item_func.cc b/sql/item_func.cc index c4854f052b5..beeaf73d741 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3948,14 +3948,24 @@ int get_var_with_binlog(THD *thd, enum_sql_command sql_command, sql_set_variables(), we could instead manually call check() and update(); this would save memory and time; but calling sql_set_variables() makes one unique place to maintain (sql_set_variables()). + + Manipulation with lex is necessary since free_underlaid_joins + is going to release memory belonging to the main query. */ List tmp_var_list; + LEX *sav_lex= thd->lex, lex_tmp; + thd->lex= &lex_tmp; + lex_start(thd, NULL, 0); tmp_var_list.push_back(new set_var_user(new Item_func_set_user_var(name, new Item_null()))); /* Create the variable */ if (sql_set_variables(thd, &tmp_var_list)) + { + thd->lex= sav_lex; goto err; + } + thd->lex= sav_lex; if (!(var_entry= get_variable(&thd->user_vars, name, 0))) goto err; } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 6d0a0f4799c..14bcb437337 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2087,19 +2087,20 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) sl->exclude_from_table_unique_test= FALSE; /* - Copy WHERE, HAVING clause pointers to avoid damaging them by optimisation + Copy WHERE, HAVING clause pointers to avoid damaging them + by optimisation */ - if (sl->prep_where) - { - sl->where= sl->prep_where->copy_andor_structure(thd); - sl->where->cleanup(); - } - if (sl->prep_having) - { - sl->having= sl->prep_having->copy_andor_structure(thd); - sl->having->cleanup(); - } - DBUG_ASSERT(sl->join == 0); + if (sl->prep_where) + { + sl->where= sl->prep_where->copy_andor_structure(thd); + sl->where->cleanup(); + } + if (sl->prep_having) + { + sl->having= sl->prep_having->copy_andor_structure(thd); + sl->having->cleanup(); + } + DBUG_ASSERT(sl->join == 0); ORDER *order; /* Fix GROUP list */ for (order= (ORDER *)sl->group_list.first; order; order= order->next) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c762091311d..f72d8fe0146 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2419,7 +2419,19 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, { if (old->field == new_fields->field) { - if (new_fields->val->used_tables()) + /* + NOTE: below const_item() call really works as "!used_tables()", i.e. + it can return FALSE where it is feasible to make it return TRUE. + + The cause is as follows: Some of the tables are already known to be + const tables (the detection code is in make_join_statistics(), + above the update_ref_and_keys() call), but we didn't propagate + information about this: TABLE::const_table is not set to TRUE, and + Item::update_used_tables() hasn't been called for each item. + The result of this is that we're missing some 'ref' accesses. + TODO: OptimizerTeam: Fix this + */ + if (!new_fields->val->const_item()) { /* If the value matches, we can use the key reference. @@ -2449,7 +2461,8 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, new_fields->null_rejecting); } else if (old->eq_func && new_fields->eq_func && - (old->val->is_null() || new_fields->val->is_null())) + ((old->val->const_item() && old->val->is_null()) || + new_fields->val->is_null())) { /* field = expression OR field IS NULL */ old->level= and_level;