summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysqlslap.c20
-rw-r--r--client/mysqltest.cc47
-rw-r--r--mysql-test/collections/README.experimental6
-rw-r--r--mysql-test/collections/default.experimental2
-rw-r--r--mysql-test/include/plugin.defs41
-rw-r--r--mysql-test/include/wait_for_status_var.inc22
-rw-r--r--mysql-test/lib/mtr_cases.pm7
-rw-r--r--mysql-test/lib/mtr_report.pm18
-rwxr-xr-xmysql-test/mysql-test-run.pl202
-rw-r--r--mysql-test/r/func_str.result16
-rw-r--r--mysql-test/r/gis.result8
-rw-r--r--mysql-test/r/join_outer.result70
-rw-r--r--mysql-test/r/mysqlbinlog_row_big.result8
-rw-r--r--mysql-test/r/mysqltest.result37
-rw-r--r--mysql-test/r/select.result64
-rw-r--r--mysql-test/r/type_timestamp.result29
-rw-r--r--mysql-test/r/view_grant.result126
-rw-r--r--mysql-test/suite/bugs/t/bug57108.test2
-rw-r--r--mysql-test/suite/perfschema/r/server_init.result4
-rw-r--r--mysql-test/suite/perfschema/t/server_init.test3
-rw-r--r--mysql-test/suite/rpl/r/rpl_heartbeat_basic.result46
-rw-r--r--mysql-test/suite/rpl/t/rpl_heartbeat_basic.test51
-rw-r--r--mysql-test/t/bug46261.test2
-rw-r--r--mysql-test/t/fulltext_plugin.test2
-rw-r--r--mysql-test/t/func_str.test11
-rw-r--r--mysql-test/t/gis.test10
-rw-r--r--mysql-test/t/join_outer.test82
-rw-r--r--mysql-test/t/mysqlbinlog_row_big.test4
-rw-r--r--mysql-test/t/mysqltest.test6
-rw-r--r--mysql-test/t/plugin.test10
-rw-r--r--mysql-test/t/plugin_auth_qa_2-master.opt4
-rw-r--r--mysql-test/t/plugin_auth_qa_3-master.opt4
-rw-r--r--mysql-test/t/plugin_not_embedded.test4
-rw-r--r--mysql-test/t/select.test70
-rw-r--r--mysql-test/t/type_timestamp.test18
-rw-r--r--mysql-test/t/view_grant.test144
-rw-r--r--mysys/my_getsystime.c140
-rw-r--r--mysys/my_init.c3
-rw-r--r--mysys/my_thr_init.c4
-rw-r--r--mysys/mysys_priv.h4
-rw-r--r--sql/item.cc3
-rw-r--r--sql/item_cmpfunc.cc4
-rw-r--r--sql/item_geofunc.h1
-rw-r--r--sql/item_strfunc.cc45
-rw-r--r--sql/item_strfunc.h10
-rw-r--r--sql/sql_select.cc8
-rw-r--r--sql/sql_string.cc41
-rw-r--r--sql/sql_string.h10
-rw-r--r--sql/sql_view.cc42
49 files changed, 1113 insertions, 402 deletions
diff --git a/client/mysqlslap.c b/client/mysqlslap.c
index 4e8e4f1aa67..01d96f1f75e 100644
--- a/client/mysqlslap.c
+++ b/client/mysqlslap.c
@@ -1507,7 +1507,12 @@ generate_primary_key_list(MYSQL *mysql, option_string *engine_stmt)
exit(1);
}
- result= mysql_store_result(mysql);
+ if (!(result= mysql_store_result(mysql)))
+ {
+ fprintf(stderr, "%s: Error when storing result: %d %s\n",
+ my_progname, mysql_errno(mysql), mysql_error(mysql));
+ exit(1);
+ }
primary_keys_number_of= mysql_num_rows(result);
/* So why check this? Blackhole :) */
@@ -1879,10 +1884,15 @@ limit_not_met:
{
if (mysql_field_count(mysql))
{
- result= mysql_store_result(mysql);
- while ((row = mysql_fetch_row(result)))
- counter++;
- mysql_free_result(result);
+ if (!(result= mysql_store_result(mysql)))
+ fprintf(stderr, "%s: Error when storing result: %d %s\n",
+ my_progname, mysql_errno(mysql), mysql_error(mysql));
+ else
+ {
+ while ((row= mysql_fetch_row(result)))
+ counter++;
+ mysql_free_result(result);
+ }
}
} while(mysql_next_result(mysql) == 0);
queries++;
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index f266197116b..6d1630ebdaa 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -468,6 +468,8 @@ TYPELIB command_typelib= {array_elements(command_names),"",
command_names, 0};
DYNAMIC_STRING ds_res;
+/* Points to ds_warning in run_query, so it can be freed */
+DYNAMIC_STRING *ds_warn= 0;
char builtin_echo[FN_REFLEN];
@@ -488,7 +490,7 @@ VAR* var_init(VAR* v, const char *name, int name_len, const char *val,
VAR* var_get(const char *var_name, const char** var_name_end,
my_bool raw, my_bool ignore_not_existing);
void eval_expr(VAR* v, const char *p, const char** p_end,
- bool open_end=false, bool backtick=true);
+ bool open_end=false, bool do_eval=true);
my_bool match_delimiter(int c, const char *delim, uint length);
void dump_result_to_reject_file(char *buf, int size);
void dump_warning_messages();
@@ -1275,6 +1277,8 @@ void free_used_memory()
my_free(embedded_server_args[--embedded_server_arg_count]);
delete_dynamic(&q_lines);
dynstr_free(&ds_res);
+ if (ds_warn)
+ dynstr_free(ds_warn);
free_all_replace();
my_free(opt_pass);
free_defaults(default_argv);
@@ -1318,6 +1322,17 @@ static void cleanup_and_exit(int exit_code)
exit(exit_code);
}
+void print_file_stack()
+{
+ for (struct st_test_file* err_file= cur_file;
+ err_file != file_stack;
+ err_file--)
+ {
+ fprintf(stderr, "included from %s at line %d:\n",
+ err_file->file_name, err_file->lineno);
+ }
+}
+
void die(const char *fmt, ...)
{
static int dying= 0;
@@ -1337,8 +1352,12 @@ void die(const char *fmt, ...)
/* Print the error message */
fprintf(stderr, "mysqltest: ");
if (cur_file && cur_file != file_stack)
- fprintf(stderr, "In included file \"%s\": ",
+ {
+ fprintf(stderr, "In included file \"%s\": \n",
cur_file->file_name);
+ print_file_stack();
+ }
+
if (start_lineno > 0)
fprintf(stderr, "At line %u: ", start_lineno);
if (fmt)
@@ -1368,20 +1387,14 @@ void die(const char *fmt, ...)
void abort_not_supported_test(const char *fmt, ...)
{
va_list args;
- struct st_test_file* err_file= cur_file;
DBUG_ENTER("abort_not_supported_test");
/* Print include filestack */
fprintf(stderr, "The test '%s' is not supported by this installation\n",
file_stack->file_name);
fprintf(stderr, "Detected in file %s at line %d\n",
- err_file->file_name, err_file->lineno);
- while (err_file != file_stack)
- {
- err_file--;
- fprintf(stderr, "included from %s at line %d\n",
- err_file->file_name, err_file->lineno);
- }
+ cur_file->file_name, cur_file->lineno);
+ print_file_stack();
/* Print error message */
va_start(args, fmt);
@@ -2519,7 +2532,7 @@ void var_set_query_get_value(struct st_command *command, VAR *var)
break;
}
}
- eval_expr(var, value, 0);
+ eval_expr(var, value, 0, false, false);
}
dynstr_free(&ds_query);
mysql_free_result(res);
@@ -2551,12 +2564,16 @@ void var_copy(VAR *dest, VAR *src)
void eval_expr(VAR *v, const char *p, const char **p_end,
- bool open_end, bool backtick)
+ bool open_end, bool do_eval)
{
DBUG_ENTER("eval_expr");
DBUG_PRINT("enter", ("p: '%s'", p));
+ /* Skip to treat as pure string if no evaluation */
+ if (! do_eval)
+ goto NO_EVAL;
+
if (*p == '$')
{
VAR *vp;
@@ -2576,7 +2593,7 @@ void eval_expr(VAR *v, const char *p, const char **p_end,
DBUG_VOID_RETURN;
}
- if (*p == '`' && backtick)
+ if (*p == '`')
{
var_query_set(v, p, p_end);
DBUG_VOID_RETURN;
@@ -2599,6 +2616,7 @@ void eval_expr(VAR *v, const char *p, const char **p_end,
}
}
+ NO_EVAL:
{
int new_val_len = (p_end && *p_end) ?
(int) (*p_end - p) : (int) strlen(p);
@@ -7679,6 +7697,8 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
die ("Cannot reap on a connection without pending send");
init_dynamic_string(&ds_warnings, NULL, 0, 256);
+ ds_warn= &ds_warnings;
+
/*
Evaluate query if this is an eval command
*/
@@ -7836,6 +7856,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
ds, &ds_warnings);
dynstr_free(&ds_warnings);
+ ds_warn= 0;
if (command->type == Q_EVAL || command->type == Q_SEND_EVAL)
dynstr_free(&eval_query);
diff --git a/mysql-test/collections/README.experimental b/mysql-test/collections/README.experimental
index 2f5ee7b00ab..924e062b76a 100644
--- a/mysql-test/collections/README.experimental
+++ b/mysql-test/collections/README.experimental
@@ -15,9 +15,13 @@ The syntax is as follows:
and any subsequent characters are ignored.
4) The full test case name including the suite and execution mode
- must be specified, for example:
+ may be specified, for example:
main.alias 'row' # bug#00000
+4b) Now, combinations will also be covered if only the test name is
+ specified, for example:
+ rpl.rpl_ps # Covers 'row', 'mix' and 'stmt'
+
5) As an exception to item 4, the last character of the test case
specification may be an asterisk (*). In that case, all test cases that
start with the same characters up to the last letter before the asterisk
diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental
index fd02498f39a..22378ebe174 100644
--- a/mysql-test/collections/default.experimental
+++ b/mysql-test/collections/default.experimental
@@ -21,7 +21,7 @@ main.wait_timeout @solaris # Bug#51244 2010-04-26 alik wait_timeou
rpl.rpl_heartbeat_basic # BUG#54820 2010-06-26 alik rpl.rpl_heartbeat_basic fails sporadically again
rpl.rpl_heartbeat_2slaves # BUG#43828 2009-10-22 luis fails sporadically
-rpl.rpl_innodb_bug28430* # Bug#46029
+rpl.rpl_innodb_bug28430 # Bug#46029
sys_vars.max_sp_recursion_depth_func @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun
sys_vars.plugin_dir_basic # Bug#52223 2010-11-24 alik Test "plugin_dir_basic" does not support RPM build (test) directory structure
diff --git a/mysql-test/include/plugin.defs b/mysql-test/include/plugin.defs
new file mode 100644
index 00000000000..4da03dc2cc9
--- /dev/null
+++ b/mysql-test/include/plugin.defs
@@ -0,0 +1,41 @@
+# Definition file for plugins.
+#
+# <lib name> <directory> <variable> [<plugin name>,...]
+#
+# The following variables will be set for a plugin, where PLUGVAR
+# represents the variable name given as the 3rd item
+#
+# PLUGVAR: name of plugin file including extension .so or .dll
+# PLUGVAR_DIR: name of directory where plugin was found
+# PLUGVAR_OPT: mysqld option --plugin_dir=....
+# PLUGVAR_LOAD: option --plugin_load=.... if the 4th element is present
+#
+# If a listed plugin is not found, the corresponding variables will be
+# set to empty, they will not be unset.
+#
+# The PLUGVAR variable is not quoted, so you must remember to quote it
+# when using it in an INSTALL PLUGIN command.
+#
+# The envorinment variables can be used in tests. If adding a new plugin,
+# you are free to pick your variable name, but please keep it upper
+# case for consistency.
+#
+# The _LOAD variable will have a form
+#
+# --plugin_load=<name1>=<lib_name>;<name2>=<lib_name>.....
+#
+# with name1, name2 etc from the comma separated list of plugin names
+# in the optional 4th argument.
+
+auth_test_plugin plugin/auth PLUGIN_AUTH test_plugin_server
+qa_auth_interface plugin/auth PLUGIN_AUTH_INTERFACE qa_auth_interface
+qa_auth_server plugin/auth PLUGIN_AUTH_SERVER qa_auth_server
+qa_auth_client plugin/auth PLUGIN_AUTH_CLIENT qa_auth_client
+udf_example sql UDF_EXAMPLE_LIB
+ha_example storage/example EXAMPLE_PLUGIN EXAMPLE
+semisync_master plugin/semisync SEMISYNC_MASTER_PLUGIN
+semisync_slave plugin/semisync SEMISYNC_SLAVE_PLUGIN
+ha_archive storage/archive ARCHIVE_PLUGIN
+ha_blackhole storage/blackhole BLACKHOLE_PLUGIN
+ha_federated storage/federated FEDERATED_PLUGIN
+mypluglib plugin/fulltext SIMPLE_PARSER
diff --git a/mysql-test/include/wait_for_status_var.inc b/mysql-test/include/wait_for_status_var.inc
index 9f4962aeaed..5c68254f00e 100644
--- a/mysql-test/include/wait_for_status_var.inc
+++ b/mysql-test/include/wait_for_status_var.inc
@@ -50,8 +50,23 @@ if (!$_status_var_comparsion)
let $_status_var_comparsion= =;
}
+# Get type of variable
+let $_is_number= 0;
+if (`SELECT '$status_var_value' REGEXP '^[\+\-]*[0-9]+(\.[0-9]+)*\$'`)
+{
+ let $_is_number= 1;
+}
+
let $_show_status_value= query_get_value("SHOW $status_type STATUS LIKE '$status_var'", Value, 1);
-while (`SELECT NOT('$_show_status_value' $_status_var_comparsion '$status_var_value')`)
+
+# Set way of comparing
+let $_query= SELECT NOT('$_show_status_value' $_status_var_comparsion '$status_var_value');
+if ($is_number)
+{
+ let $_query= SELECT NOT($_show_status_value $_status_var_comparsion $status_var_value);
+}
+
+while (`$_query`)
{
if (!$_status_timeout_counter)
{
@@ -65,4 +80,9 @@ while (`SELECT NOT('$_show_status_value' $_status_var_comparsion '$status_var_va
dec $_status_timeout_counter;
sleep 0.1;
let $_show_status_value= query_get_value("SHOW $status_type STATUS LIKE '$status_var'", Value, 1);
+ let $_query= SELECT NOT('$_show_status_value' $_status_var_comparsion '$status_var_value');
+ if ($is_number)
+ {
+ let $_query= SELECT NOT($_show_status_value $_status_var_comparsion $status_var_value);
+ }
}
diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm
index f1f1ac35dcd..856982e98a1 100644
--- a/mysql-test/lib/mtr_cases.pm
+++ b/mysql-test/lib/mtr_cases.pm
@@ -229,8 +229,11 @@ sub collect_test_cases ($$$$) {
sub split_testname {
my ($test_name)= @_;
- # Get rid of directory part and split name on .'s
- my @parts= split(/\./, basename($test_name));
+ # If .test file name is used, get rid of directory part
+ $test_name= basename($test_name) if $test_name =~ /\.test$/;
+
+ # Now split name on .'s
+ my @parts= split(/\./, $test_name);
if (@parts == 1){
# Only testname given, ex: alias
diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm
index af75178473d..cd3f9ce1041 100644
--- a/mysql-test/lib/mtr_report.pm
+++ b/mysql-test/lib/mtr_report.pm
@@ -129,7 +129,8 @@ sub mtr_report_test ($) {
# Find out if this test case is an experimental one, so we can treat
# the failure as an expected failure instead of a regression.
for my $exp ( @$::experimental_test_cases ) {
- if ( $exp ne $test_name ) {
+ # Include pattern match for combinations
+ if ( $exp ne $test_name && $test_name !~ /^$exp / ) {
# if the expression is not the name of this test case, but has
# an asterisk at the end, determine if the characters up to
# but excluding the asterisk are the same
@@ -395,7 +396,7 @@ sub mtr_report_stats ($$;$) {
##############################################################################
sub mtr_print_line () {
- print '-' x 60 . "\n";
+ print '-' x 74 . "\n";
}
@@ -405,13 +406,18 @@ sub mtr_print_thick_line {
}
-sub mtr_print_header () {
+sub mtr_print_header ($) {
+ my ($wid) = @_;
print "\n";
printf "TEST";
- print " " x 38;
+ if ($wid) {
+ print " " x 34 . "WORKER ";
+ } else {
+ print " " x 38;
+ }
print "RESULT ";
- print "TIME (ms)" if $timer;
- print "\n";
+ print "TIME (ms) or " if $timer;
+ print "COMMENT\n";
mtr_print_line();
print "\n";
}
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index a7683b8d807..b786066faf6 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -131,10 +131,6 @@ my $opt_start_dirty;
my $opt_start_exit;
my $start_only;
-my $auth_interface_fn; # the name of qa_auth_interface plugin
-my $auth_server_fn; # the name of qa_auth_server plugin
-my $auth_client_fn; # the name of qa_auth_client plugin
-my $auth_filename; # the name of the authentication test plugin
my $auth_plugin; # the path to the authentication test plugin
END {
@@ -442,7 +438,7 @@ sub main {
mtr_report();
mtr_print_thick_line();
- mtr_print_header();
+ mtr_print_header($opt_parallel > 1);
mark_time_used('init');
@@ -1124,27 +1120,7 @@ sub command_line_setup {
"$basedir/sql/share/charsets",
"$basedir/share/charsets");
- # Look for auth test plugins
- if (IS_WINDOWS)
- {
- $auth_filename = "auth_test_plugin.dll";
- $auth_interface_fn = "qa_auth_interface.dll";
- $auth_server_fn = "qa_auth_server.dll";
- $auth_client_fn = "qa_auth_client.dll";
- }
- else
- {
- $auth_filename = "auth_test_plugin.so";
- $auth_interface_fn = "qa_auth_interface.so";
- $auth_server_fn = "qa_auth_server.so";
- $auth_client_fn = "qa_auth_client.so";
- }
- $auth_plugin=
- mtr_file_exists(vs_config_dirs('plugin/auth/',$auth_filename),
- "$basedir/plugin/auth/.libs/" . $auth_filename,
- "$basedir/lib/mysql/plugin/" . $auth_filename,
- "$basedir/lib/plugin/" . $auth_filename);
-
+ ($auth_plugin)= find_plugin("auth_test_plugin", "plugin/auth");
if (using_extern())
{
@@ -1983,6 +1959,53 @@ sub find_plugin($$)
return $lib_example_plugin;
}
+#
+# Read plugin defintions file
+#
+
+sub read_plugin_defs($)
+{
+ my ($defs_file)= @_;
+
+ open(PLUGDEF, '<', $defs_file)
+ or mtr_error("Can't read plugin defintions file $defs_file");
+
+ while (<PLUGDEF>) {
+ next if /^#/;
+ my ($plug_file, $plug_loc, $plug_var, $plug_names)= split;
+ # Allow empty lines
+ next unless $plug_file;
+ mtr_error("Lines in $defs_file must have 3 or 4 items") unless $plug_var;
+
+ my ($plugin)= find_plugin($plug_file, $plug_loc);
+
+ # Set env. variables that tests may use, set to empty if plugin
+ # listed in def. file but not found.
+
+ if ($plugin) {
+ $ENV{$plug_var}= basename($plugin);
+ $ENV{$plug_var.'_DIR'}= dirname($plugin);
+ $ENV{$plug_var.'_OPT'}= "--plugin-dir=".dirname($plugin);
+ if ($plug_names) {
+ my $lib_name= basename($plugin);
+ my $load_var= "--plugin_load=";
+ my $semi= '';
+ foreach my $plug_name (split (',', $plug_names)) {
+ $load_var .= $semi . "$plug_name=$lib_name";
+ $semi= ';';
+ }
+ $ENV{$plug_var.'_LOAD'}= $load_var;
+ }
+ } else {
+ $ENV{$plug_var}= "";
+ $ENV{$plug_var.'_DIR'}= "";
+ $ENV{$plug_var.'_OPT'}= "";
+ $ENV{$plug_var.'_LOAD'}= "" if $plug_names;
+ }
+ }
+ close PLUGDEF;
+}
+
sub environment_setup {
umask(022);
@@ -2019,127 +2042,16 @@ sub environment_setup {
}
# --------------------------------------------------------------------------
- # Add the path where mysqld will find udf_example.so
- # --------------------------------------------------------------------------
- my $udf_example_filename;
- if (IS_WINDOWS)
- {
- $udf_example_filename = "udf_example.dll";
- }
- else
- {
- $udf_example_filename = "udf_example.so";
- }
- my $lib_udf_example=
- mtr_file_exists(vs_config_dirs('sql', $udf_example_filename),
- "$basedir/sql/.libs/$udf_example_filename",);
-
- if ( $lib_udf_example )
- {
- push(@ld_library_paths, dirname($lib_udf_example));
- }
-
- $ENV{'UDF_EXAMPLE_LIB'}=
- ($lib_udf_example ? basename($lib_udf_example) : "");
- $ENV{'UDF_EXAMPLE_LIB_OPT'}= "--plugin-dir=".
- ($lib_udf_example ? dirname($lib_udf_example) : "");
-
- # --------------------------------------------------------------------------
- # Add the path where mysqld will find the auth test plugin (dialog.so/dll)
- # --------------------------------------------------------------------------
- if ($auth_plugin)
- {
- $ENV{'PLUGIN_AUTH'}= basename($auth_plugin);
- $ENV{'PLUGIN_AUTH_OPT'}= "--plugin-dir=".dirname($auth_plugin);
-
- $ENV{'PLUGIN_AUTH_LOAD'}="--plugin_load=test_plugin_server=".$auth_filename;
- $ENV{'PLUGIN_AUTH_INTERFACE'}="--plugin_load=qa_auth_interface=".$auth_interface_fn;
- $ENV{'PLUGIN_AUTH_SERVER'}="--plugin_load=qa_auth_server=".$auth_server_fn;
- $ENV{'PLUGIN_AUTH_CLIENT'}="--plugin_load=qa_auth_client=".$auth_client_fn;
- }
- else
- {
- $ENV{'PLUGIN_AUTH'}= "";
- $ENV{'PLUGIN_AUTH_OPT'}="--plugin-dir=";
- $ENV{'PLUGIN_AUTH_LOAD'}="";
- $ENV{'PLUGIN_AUTH_INTERFACE'}="";
- $ENV{'PLUGIN_AUTH_SERVER'}="";
- $ENV{'PLUGIN_AUTH_CLIENT'}="";
- }
-
-
- # --------------------------------------------------------------------------
- # Add the path where mysqld will find ha_example.so
- # --------------------------------------------------------------------------
- if ($mysql_version_id >= 50100) {
- my ($lib_example_plugin) = find_plugin("ha_example", "storage/example");
-
- if($lib_example_plugin)
- {
- $ENV{'EXAMPLE_PLUGIN'}=
- ($lib_example_plugin ? basename($lib_example_plugin) : "");
- $ENV{'EXAMPLE_PLUGIN_OPT'}= "--plugin-dir=".
- ($lib_example_plugin ? dirname($lib_example_plugin) : "");
-
- $ENV{'HA_EXAMPLE_SO'}="'".basename($lib_example_plugin)."'";
- $ENV{'EXAMPLE_PLUGIN_LOAD'}="--plugin_load=EXAMPLE=".basename($lib_example_plugin);
- }
- else
- {
- # Some ".opt" files use some of these variables, so they must be defined
- $ENV{'EXAMPLE_PLUGIN'}= "";
- $ENV{'EXAMPLE_PLUGIN_OPT'}= "";
- $ENV{'HA_EXAMPLE_SO'}= "";
- $ENV{'EXAMPLE_PLUGIN_LOAD'}= "";
- }
- }
-
-
- # --------------------------------------------------------------------------
- # Add the path where mysqld will find semisync plugins
+ # Read definitions from include/plugin.defs
+ #
+ # Plugin settings should no longer be added here, instead
+ # place definitions in include/plugin.defs.
+ # See comment in that file for details.
# --------------------------------------------------------------------------
- if (!$opt_embedded_server) {
-
-
- my ($lib_semisync_master_plugin) = find_plugin("semisync_master", "plugin/semisync");
- my ($lib_semisync_slave_plugin) = find_plugin("semisync_slave", "plugin/semisync");
-
-
- if ($lib_semisync_master_plugin && $lib_semisync_slave_plugin)
- {
- $ENV{'SEMISYNC_MASTER_PLUGIN'}= basename($lib_semisync_master_plugin);
- $ENV{'SEMISYNC_SLAVE_PLUGIN'}= basename($lib_semisync_slave_plugin);
- $ENV{'SEMISYNC_PLUGIN_OPT'}= "--plugin-dir=".dirname($lib_semisync_master_plugin);
- }
- else
- {
- $ENV{'SEMISYNC_MASTER_PLUGIN'}= "";
- $ENV{'SEMISYNC_SLAVE_PLUGIN'}= "";
- $ENV{'SEMISYNC_PLUGIN_OPT'}="--plugin-dir=";
- }
- }
-
- # ----------------------------------------------------
- # Add the paths where mysqld will find archive/blackhole/federated plugins.
- # ----------------------------------------------------
- $ENV{'ARCHIVE_PLUGIN_DIR'} =
- dirname(find_plugin("ha_archive", "storage/archive"));
- $ENV{'BLACKHOLE_PLUGIN_DIR'} =
- dirname(find_plugin("ha_blackhole", "storage/blackhole"));
- $ENV{'FEDERATED_PLUGIN_DIR'} =
- dirname(find_plugin("ha_federated", "storage/federated"));
-
- # ----------------------------------------------------
- # Add the path where mysqld will find mypluglib.so
- # ----------------------------------------------------
-
- my ($lib_simple_parser) = find_plugin("mypluglib", "plugin/fulltext");
+ read_plugin_defs("include/plugin.defs");
- $ENV{'MYPLUGLIB_SO'}="'".basename($lib_simple_parser)."'";
- $ENV{'SIMPLE_PARSER'}=
- ($lib_simple_parser ? basename($lib_simple_parser) : "");
- $ENV{'SIMPLE_PARSER_OPT'}= "--plugin-dir=".
- ($lib_simple_parser ? dirname($lib_simple_parser) : "");
+ # Simplify reference to semisync plugins
+ $ENV{'SEMISYNC_PLUGIN_OPT'}= $ENV{'SEMISYNC_MASTER_PLUGIN_OPT'};
# --------------------------------------------------------------------------
# Valgrind need to be run with debug libraries otherwise it's almost
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index 41fe9c096b0..81fe2413725 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -2615,6 +2615,22 @@ CONVERT(('' IN (REVERSE(CAST(('') AS DECIMAL)), '')), CHAR(3))
1
Warnings:
Warning 1292 Truncated incorrect DECIMAL value: ''
+#
+# Bug#58165: "my_empty_string" gets modified and causes LOAD DATA to fail
+# and other crashes
+#
+CREATE TABLE t1 ( a TEXT );
+SELECT 'aaaaaaaaaaaaaa' INTO OUTFILE 'bug58165.txt';
+SELECT insert( substring_index( 'a', 'a', 'b' ), 1, 0, 'x' );
+insert( substring_index( 'a', 'a', 'b' ), 1, 0, 'x' )
+x
+Warnings:
+Warning 1292 Truncated incorrect INTEGER value: 'b'
+LOAD DATA INFILE 'bug58165.txt' INTO TABLE t1;
+SELECT * FROM t1;
+a
+aaaaaaaaaaaaaa
+DROP TABLE t1;
End of 5.1 tests
Start of 5.4 tests
SELECT format(12345678901234567890.123, 3);
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index 5663f167d00..7939d01beff 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -1014,6 +1014,14 @@ SET @a=0x00000000030000000100000000000000000000000000144000000000000014400000000
SET @a=POLYFROMWKB(@a);
SET @a=0x00000000030000000000000000000000000000000000144000000000000014400000000000001840000000000000184000000000000014400000000000001440;
SET @a=POLYFROMWKB(@a);
+create table t1(a polygon NOT NULL)engine=myisam;
+insert into t1 values (geomfromtext("point(0 1)"));
+insert into t1 values (geomfromtext("point(1 0)"));
+select * from (select polygon(t1.a) as p from t1 order by t1.a) d;
+p
+NULL
+NULL
+drop table t1;
End of 5.1 tests
CREATE TABLE t1(
col0 BINARY NOT NULL,
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index 99ca9f05535..ecd53003513 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -1432,4 +1432,74 @@ WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL
GROUP BY t2.f1, t2.f2;
f1 f1 f2
DROP TABLE t1,t2;
+#
+# Bug#57034 incorrect OUTER JOIN result when joined on unique key
+#
+CREATE TABLE t1 (pk INT PRIMARY KEY,
+col_int INT,
+col_int_unique INT UNIQUE KEY);
+INSERT INTO t1 VALUES (1,NULL,2), (2,0,0);
+CREATE TABLE t2 (pk INT PRIMARY KEY,
+col_int INT,
+col_int_unique INT UNIQUE KEY);
+INSERT INTO t2 VALUES (1,0,1), (2,0,2);
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2
+ON t1.col_int_unique = t2.col_int_unique AND t1.col_int = t2.col_int
+WHERE t1.pk=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
+1 SIMPLE t2 const col_int_unique col_int_unique 5 const 1
+SELECT * FROM t1 LEFT JOIN t2
+ON t1.col_int_unique = t2.col_int_unique AND t1.col_int = t2.col_int
+WHERE t1.pk=1;
+pk col_int col_int_unique pk col_int col_int_unique
+1 NULL 2 NULL NULL NULL
+DROP TABLE t1,t2;
+#
+# Bug#48046 Server incorrectly processing JOINs on NULL values
+#
+CREATE TABLE `BB` (
+`pk` int(11) NOT NULL AUTO_INCREMENT,
+`time_key` time DEFAULT NULL,
+`varchar_key` varchar(1) DEFAULT NULL,
+`varchar_nokey` varchar(1) DEFAULT NULL,
+PRIMARY KEY (`pk`),
+KEY `time_key` (`time_key`),
+KEY `varchar_key` (`varchar_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
+INSERT INTO `BB` VALUES (10,'18:27:58',NULL,NULL);
+SELECT table1.time_key AS field1, table2.pk
+FROM BB table1 LEFT JOIN BB table2
+ON table2.varchar_nokey = table1.varchar_key
+HAVING field1;
+field1 pk
+18:27:58 NULL
+DROP TABLE BB;
+#
+# Bug#49600 Server incorrectly processing RIGHT JOIN with
+# constant WHERE clause and no index
+#
+CREATE TABLE `BB` (
+`col_datetime_key` datetime DEFAULT NULL,
+`col_varchar_key` varchar(1) DEFAULT NULL,
+`col_varchar_nokey` varchar(1) DEFAULT NULL,
+KEY `col_datetime_key` (`col_datetime_key`),
+KEY `col_varchar_key` (`col_varchar_key`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO `BB` VALUES ('1900-01-01 00:00:00',NULL,NULL);
+SELECT table1.col_datetime_key
+FROM BB table1 RIGHT JOIN BB table2
+ON table2 .col_varchar_nokey = table1.col_varchar_key
+WHERE 7;
+col_datetime_key
+NULL
+ALTER TABLE BB DISABLE KEYS;
+SELECT table1.col_datetime_key
+FROM BB table1 RIGHT JOIN BB table2
+ON table2 .col_varchar_nokey = table1.col_varchar_key
+WHERE 7;
+col_datetime_key
+NULL
+DROP TABLE BB;
End of 5.1 tests
diff --git a/mysql-test/r/mysqlbinlog_row_big.result b/mysql-test/r/mysqlbinlog_row_big.result
index 46fa0dc79cd..0bdbfdcee3a 100644
--- a/mysql-test/r/mysqlbinlog_row_big.result
+++ b/mysql-test/r/mysqlbinlog_row_big.result
@@ -36,8 +36,8 @@ c1 LONGTEXT
#
# Insert some big rows.
#
-256MB
-INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 16777216));
+64MB
+INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 4194304));
affected rows: 1
32MB
INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 2097152));
@@ -53,7 +53,7 @@ affected rows: 1
# Do not display the column value itself, just its length.
#
SELECT LENGTH(c1) FROM t1;
-LENGTH(c1) 268435456
+LENGTH(c1) 67108864
LENGTH(c1) 33554432
LENGTH(c1) 4194304
LENGTH(c1) 524288
@@ -69,7 +69,7 @@ info: Rows matched: 4 Changed: 4 Warnings: 0
# Do not display the column value itself, just its length.
#
SELECT LENGTH(c1) FROM t1;
-LENGTH(c1) 536870912
+LENGTH(c1) 134217728
LENGTH(c1) 1048576
LENGTH(c1) 67108864
LENGTH(c1) 8388608
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index c3b6d22ef38..9c8f49c333b 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -311,12 +311,33 @@ failing query in let
create table t1 (a varchar(100));
insert into t1 values ('`select 42`');
`select 42`
+insert into t1 values ('$dollar');
+$dollar
+`select 42`
drop table t1;
mysqltest: At line 1: Error running query 'failing query': 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'failing query' at line 1
mysqltest: At line 1: Missing required argument 'filename' to command 'source'
mysqltest: At line 1: Could not open './non_existingFile' for reading, errno: 2
-mysqltest: In included file "MYSQLTEST_VARDIR/tmp/recursive.sql": At line 1: Source directives are nesting too deep
-mysqltest: In included file "MYSQLTEST_VARDIR/tmp/error.sql": At line 1: query 'garbage ' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
+mysqltest: In included file "MYSQLTEST_VARDIR/tmp/recursive.sql":
+included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
+included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
+included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
+included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
+included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
+included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
+included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
+included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
+included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
+included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
+included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
+included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
+included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
+included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
+included from MYSQLTEST_VARDIR/tmp/recursive.sql at line 1:
+At line 1: Source directives are nesting too deep
+mysqltest: In included file "MYSQLTEST_VARDIR/tmp/error.sql":
+included from MYSQLTEST_VARDIR/tmp/error.sql at line 1:
+At line 1: query 'garbage ' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1
2 = outer loop variable after while
here is the sourced script
@@ -444,7 +465,9 @@ counter is 6
counter is 7
1
Testing while with not
-mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest_while.inc": At line 64: Nesting too deeply
+mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest_while.inc":
+included from MYSQLTEST_VARDIR/tmp/mysqltest_while.inc at line 65:
+At line 64: Nesting too deeply
mysqltest: At line 1: missing '(' in while
mysqltest: At line 1: missing ')' in while
mysqltest: At line 1: Missing '{' after while. Found "dec $i"
@@ -493,8 +516,12 @@ mysqltest: At line 1: query 'connect con2,localhost,root,,illegal_db' failed: 1
mysqltest: At line 1: Illegal argument for port: 'illegal_port'
mysqltest: At line 1: Illegal option to connect: SMTP
200 connects succeeded
-mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 3: connection 'test_con1' not found in connection pool
-mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 2: Connection test_con1 already exists
+mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql":
+included from MYSQLTEST_VARDIR/tmp/mysqltest.sql at line 3:
+At line 3: connection 'test_con1' not found in connection pool
+mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql":
+included from MYSQLTEST_VARDIR/tmp/mysqltest.sql at line 2:
+At line 2: Connection test_con1 already exists
show tables;
ERROR 3D000: No database selected
connect con1,localhost,root,,;
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index a345a2ae6aa..af0ef29bb53 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -4867,6 +4867,70 @@ SELECT 1 FROM t1 ORDER BY a COLLATE latin1_german2_ci;
1
1
DROP TABLE t1;
+#
+# Bug #58422: Incorrect result when OUTER JOIN'ing
+# with an empty table
+#
+CREATE TABLE t_empty(pk INT PRIMARY KEY, i INT) ENGINE = MYISAM;
+CREATE TABLE t1(pk INT PRIMARY KEY, i INT) ENGINE = MYISAM;
+INSERT INTO t1 VALUES (1,1), (2,2), (3,3);
+CREATE TABLE t2(pk INT PRIMARY KEY, i INT) ENGINE = MYISAM;
+INSERT INTO t2 VALUES (1,1), (2,2), (3,3);
+EXPLAIN
+SELECT *
+FROM
+t1
+LEFT OUTER JOIN
+(t2 INNER JOIN t_empty ON TRUE)
+ON t1.pk=t2.pk
+WHERE t2.pk <> 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT *
+FROM
+t1
+LEFT OUTER JOIN
+(t2 INNER JOIN t_empty ON TRUE)
+ON t1.pk=t2.pk
+WHERE t2.pk <> 2;
+pk i pk i pk i
+EXPLAIN
+SELECT *
+FROM
+t1
+LEFT OUTER JOIN
+(t2 CROSS JOIN t_empty)
+ON t1.pk=t2.pk
+WHERE t2.pk <> 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT *
+FROM
+t1
+LEFT OUTER JOIN
+(t2 CROSS JOIN t_empty)
+ON t1.pk=t2.pk
+WHERE t2.pk <> 2;
+pk i pk i pk i
+EXPLAIN
+SELECT *
+FROM
+t1
+LEFT OUTER JOIN
+(t2 INNER JOIN t_empty ON t_empty.i=t2.i)
+ON t1.pk=t2.pk
+WHERE t2.pk <> 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT *
+FROM
+t1
+LEFT OUTER JOIN
+(t2 INNER JOIN t_empty ON t_empty.i=t2.i)
+ON t1.pk=t2.pk
+WHERE t2.pk <> 2;
+pk i pk i pk i
+DROP TABLE t1,t2,t_empty;
End of 5.1 tests
#
# Bug#54515: Crash in opt_range.cc::get_best_group_min_max on
diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result
index 10a2b47ba02..d5769bfd59a 100644
--- a/mysql-test/r/type_timestamp.result
+++ b/mysql-test/r/type_timestamp.result
@@ -540,3 +540,32 @@ a
2010-03-05 11:08:02
DROP TABLE t1;
End of Bug#50888
+#
+# Bug59330: Incorrect result when comparing an aggregate
+# function with TIMESTAMP
+#
+CREATE TABLE t1 (dt DATETIME, ts TIMESTAMP);
+INSERT INTO t1 VALUES('2011-01-06 12:34:30', '2011-01-06 12:34:30');
+SELECT MAX(dt), MAX(ts) FROM t1;
+MAX(dt) MAX(ts)
+2011-01-06 12:34:30 2011-01-06 12:34:30
+SELECT MAX(ts) < '2010-01-01 00:00:00' FROM t1;
+MAX(ts) < '2010-01-01 00:00:00'
+0
+SELECT MAX(dt) < '2010-01-01 00:00:00' FROM t1;
+MAX(dt) < '2010-01-01 00:00:00'
+0
+SELECT MAX(ts) > '2010-01-01 00:00:00' FROM t1;
+MAX(ts) > '2010-01-01 00:00:00'
+1
+SELECT MAX(dt) > '2010-01-01 00:00:00' FROM t1;
+MAX(dt) > '2010-01-01 00:00:00'
+1
+SELECT MAX(ts) = '2011-01-06 12:34:30' FROM t1;
+MAX(ts) = '2011-01-06 12:34:30'
+1
+SELECT MAX(dt) = '2011-01-06 12:34:30' FROM t1;
+MAX(dt) = '2011-01-06 12:34:30'
+1
+DROP TABLE t1;
+End of 5.5 tests
diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result
index 1412df20012..9a0408bc174 100644
--- a/mysql-test/r/view_grant.result
+++ b/mysql-test/r/view_grant.result
@@ -1248,3 +1248,129 @@ Note 1449 The user specified as a definer ('unknown'@'unknown') does not exist
LOCK TABLES v1 READ;
ERROR HY000: The user specified as a definer ('unknown'@'unknown') does not exist
DROP VIEW v1;
+#
+# Bug #58499 "DEFINER-security view selecting from INVOKER-security view
+# access check wrong".
+#
+# Check that we correctly handle privileges for various combinations
+# of INVOKER and DEFINER-security views using each other.
+DROP DATABASE IF EXISTS mysqltest1;
+CREATE DATABASE mysqltest1;
+USE mysqltest1;
+CREATE TABLE t1 (i INT);
+CREATE TABLE t2 (j INT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+#
+# 1) DEFINER-security view uses INVOKER-security view (covers
+# scenario originally described in the bug report).
+CREATE SQL SECURITY INVOKER VIEW v1_uses_t1 AS SELECT * FROM t1;
+CREATE SQL SECURITY INVOKER VIEW v1_uses_t2 AS SELECT * FROM t2;
+CREATE USER 'mysqluser1'@'%';
+GRANT CREATE VIEW ON mysqltest1.* TO 'mysqluser1'@'%';
+GRANT SELECT ON t1 TO 'mysqluser1'@'%';
+# To be able create 'v2_uses_t2' we also need select on t2.
+GRANT SELECT ON t2 TO 'mysqluser1'@'%';
+GRANT SELECT ON v1_uses_t1 TO 'mysqluser1'@'%';
+GRANT SELECT ON v1_uses_t2 TO 'mysqluser1'@'%';
+#
+# Connection 'mysqluser1'.
+CREATE SQL SECURITY DEFINER VIEW v2_uses_t1 AS SELECT * FROM v1_uses_t1;
+CREATE SQL SECURITY DEFINER VIEW v2_uses_t2 AS SELECT * FROM v1_uses_t2;
+#
+# Connection 'default'.
+CREATE USER 'mysqluser2'@'%';
+GRANT SELECT ON v2_uses_t1 TO 'mysqluser2'@'%';
+GRANT SELECT ON v2_uses_t2 TO 'mysqluser2'@'%';
+GRANT SELECT ON t2 TO 'mysqluser2'@'%';
+GRANT CREATE VIEW ON mysqltest1.* TO 'mysqluser2'@'%';
+# Make 'mysqluser1' unable to access t2.
+REVOKE SELECT ON t2 FROM 'mysqluser1'@'%';
+#
+# Connection 'mysqluser2'.
+# The below statement should succeed thanks to suid nature of v2_uses_t1.
+SELECT * FROM v2_uses_t1;
+i
+1
+# The below statement should fail due to suid nature of v2_uses_t2.
+SELECT * FROM v2_uses_t2;
+ERROR HY000: View 'mysqltest1.v2_uses_t2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+#
+# 2) INVOKER-security view uses INVOKER-security view.
+#
+# Connection 'default'.
+DROP VIEW v2_uses_t1, v2_uses_t2;
+CREATE SQL SECURITY INVOKER VIEW v2_uses_t1 AS SELECT * FROM v1_uses_t1;
+CREATE SQL SECURITY INVOKER VIEW v2_uses_t2 AS SELECT * FROM v1_uses_t2;
+GRANT SELECT ON v2_uses_t1 TO 'mysqluser1'@'%';
+GRANT SELECT ON v2_uses_t2 TO 'mysqluser1'@'%';
+GRANT SELECT ON v1_uses_t1 TO 'mysqluser2'@'%';
+GRANT SELECT ON v1_uses_t2 TO 'mysqluser2'@'%';
+#
+# Connection 'mysqluser1'.
+# For both versions of 'v2' 'mysqluser1' privileges should be used.
+SELECT * FROM v2_uses_t1;
+i
+1
+SELECT * FROM v2_uses_t2;
+ERROR HY000: View 'mysqltest1.v2_uses_t2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+#
+# Connection 'mysqluser2'.
+# And now for both versions of 'v2' 'mysqluser2' privileges should
+# be used.
+SELECT * FROM v2_uses_t1;
+ERROR HY000: View 'mysqltest1.v2_uses_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+SELECT * FROM v2_uses_t2;
+j
+2
+#
+# 3) INVOKER-security view uses DEFINER-security view.
+#
+# Connection 'default'.
+DROP VIEW v1_uses_t1, v1_uses_t2;
+# To be able create 'v1_uses_t2' we also need select on t2.
+GRANT SELECT ON t2 TO 'mysqluser1'@'%';
+#
+# Connection 'mysqluser1'.
+CREATE SQL SECURITY DEFINER VIEW v1_uses_t1 AS SELECT * FROM t1;
+CREATE SQL SECURITY DEFINER VIEW v1_uses_t2 AS SELECT * FROM t2;
+#
+# Connection 'default'.
+# Make 'mysqluser1' unable to access t2.
+REVOKE SELECT ON t2 FROM 'mysqluser1'@'%';
+#
+# Connection 'mysqluser2'.
+# Due to suid nature of v1_uses_t1 and v1_uses_t2 the first
+# select should succeed and the second select should fail.
+SELECT * FROM v2_uses_t1;
+i
+1
+SELECT * FROM v2_uses_t2;
+ERROR HY000: View 'mysqltest1.v2_uses_t2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+#
+# 4) DEFINER-security view uses DEFINER-security view.
+#
+# Connection 'default'.
+DROP VIEW v2_uses_t1, v2_uses_t2;
+# To be able create 'v2_uses_t2' we also need select on t2.
+GRANT SELECT ON t2 TO 'mysqluser1'@'%';
+#
+# Connection 'mysqluser2'.
+CREATE SQL SECURITY DEFINER VIEW v2_uses_t1 AS SELECT * FROM v1_uses_t1;
+CREATE SQL SECURITY DEFINER VIEW v2_uses_t2 AS SELECT * FROM v1_uses_t2;
+#
+# Connection 'default'.
+# Make 'mysqluser1' unable to access t2.
+REVOKE SELECT ON t2 FROM 'mysqluser1'@'%';
+#
+# Connection 'mysqluser2'.
+# Again privileges of creator of innermost views should apply.
+SELECT * FROM v2_uses_t1;
+i
+1
+SELECT * FROM v2_uses_t2;
+ERROR HY000: View 'mysqltest1.v2_uses_t2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+USE test;
+DROP DATABASE mysqltest1;
+DROP USER 'mysqluser1'@'%';
+DROP USER 'mysqluser2'@'%';
diff --git a/mysql-test/suite/bugs/t/bug57108.test b/mysql-test/suite/bugs/t/bug57108.test
index 1006a7b30f1..56acd7fe7bd 100644
--- a/mysql-test/suite/bugs/t/bug57108.test
+++ b/mysql-test/suite/bugs/t/bug57108.test
@@ -5,7 +5,7 @@
# switched directory after starting the server and am using a relative
# --defaults-file.
--replace_regex /\.dll/.so/
-eval INSTALL PLUGIN example SONAME $HA_EXAMPLE_SO;
+eval INSTALL PLUGIN example SONAME '$EXAMPLE_PLUGIN';
--query_vertical SELECT @@global.connect_timeout AS connect_timeout, @@global.local_infile AS local_infile
diff --git a/mysql-test/suite/perfschema/r/server_init.result b/mysql-test/suite/perfschema/r/server_init.result
index b6f1d4828c3..26104197686 100644
--- a/mysql-test/suite/perfschema/r/server_init.result
+++ b/mysql-test/suite/perfschema/r/server_init.result
@@ -31,10 +31,6 @@ select count(name) from mutex_instances
where name like "wait/synch/mutex/mysys/THR_LOCK_charset";
count(name)
1
-select count(name) from mutex_instances
-where name like "wait/synch/mutex/mysys/THR_LOCK_time";
-count(name)
-1
select count(name) from cond_instances
where name like "wait/synch/cond/mysys/THR_COND_threads";
count(name)
diff --git a/mysql-test/suite/perfschema/t/server_init.test b/mysql-test/suite/perfschema/t/server_init.test
index 33eeeb7edb2..95d8be0e864 100644
--- a/mysql-test/suite/perfschema/t/server_init.test
+++ b/mysql-test/suite/perfschema/t/server_init.test
@@ -52,9 +52,6 @@ select count(name) from mutex_instances
select count(name) from mutex_instances
where name like "wait/synch/mutex/mysys/THR_LOCK_charset";
-select count(name) from mutex_instances
- where name like "wait/synch/mutex/mysys/THR_LOCK_time";
-
# There are no global rwlock in mysys
# Verify that these global conditions have been properly initilized in mysys
diff --git a/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result b/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result
index ccef60d6323..ef901476784 100644
--- a/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result
+++ b/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result
@@ -16,7 +16,7 @@ RESET SLAVE;
*** Reset slave affect ***
SET @@global.slave_net_timeout=30;
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=5;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=5;
RESET SLAVE;
SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
Variable_name Value
@@ -24,7 +24,7 @@ Slave_heartbeat_period 15.000
*** Default value if slave_net_timeout changed ***
SET @@global.slave_net_timeout=50;
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root';
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20;
SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
Variable_name Value
Slave_heartbeat_period 25.000
@@ -39,14 +39,14 @@ SET @@global.slave_net_timeout=@restore_slave_net_timeout;
RESET SLAVE;
*** Warning if updated slave_heartbeat_timeout > slave_net_timeout ***
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=SLAVE_NET_TIMEOUT;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=SLAVE_NET_TIMEOUT;
Warnings:
Warning 1704 The requested value for the heartbeat period exceeds the value of `slave_net_timeout' seconds. A sensible value for the period should be less than the timeout.
RESET SLAVE;
*** CHANGE MASTER statement only updates slave_heartbeat_period ***
SET @@global.slave_net_timeout=20;
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=5;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=5;
SHOW VARIABLES LIKE 'slave_net_timeout';
Variable_name Value
slave_net_timeout 20
@@ -67,7 +67,7 @@ RESET SLAVE;
SET @@global.slave_net_timeout=500;
SET @@global.slave_net_timeout=200;
RESET SLAVE;
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root';
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20;
include/start_slave.inc
SHOW VARIABLES LIKE 'slave_net_timeout';
Variable_name Value
@@ -82,7 +82,7 @@ SET @@global.slave_net_timeout=@restore_slave_net_timeout;
*** Start/stop slave ***
SET @@global.slave_net_timeout=100;
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=20;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=20;
include/start_slave.inc
SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
Variable_name Value
@@ -94,7 +94,7 @@ Slave_heartbeat_period 20.000
*** Reload slave ***
SET @@global.slave_net_timeout=50;
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=30;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=30;
include/rpl_restart_server.inc [server_number=2]
SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
Variable_name Value
@@ -102,7 +102,7 @@ Slave_heartbeat_period 30.000
SET @restore_slave_net_timeout=@@global.slave_net_timeout;
*** Disable heartbeat ***
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=0;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=0;
SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
Variable_name Value
Slave_heartbeat_period 0.000
@@ -129,12 +129,12 @@ Result
0
*** Min slave_heartbeat_timeout ***
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=0.001;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=0.001;
SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
Variable_name Value
Slave_heartbeat_period 0.001
RESET SLAVE;
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=0.0009;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=0.0009;
Warnings:
Warning 1703 The requested value for the heartbeat period is less than 1 millisecond. The value is reset to 0, meaning that heartbeating will effectively be disabled.
SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
@@ -143,36 +143,36 @@ Slave_heartbeat_period 0.000
RESET SLAVE;
*** Max slave_heartbeat_timeout ***
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=4294967;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=4294967;
Warnings:
Warning 1704 The requested value for the heartbeat period exceeds the value of `slave_net_timeout' seconds. A sensible value for the period should be less than the timeout.
SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
Variable_name Value
Slave_heartbeat_period 4294967.000
RESET SLAVE;
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=4294968;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=4294968;
ERROR HY000: The requested value for the heartbeat period is either negative or exceeds the maximum allowed (4294967 seconds).
RESET SLAVE;
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=8589935;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=8589935;
ERROR HY000: The requested value for the heartbeat period is either negative or exceeds the maximum allowed (4294967 seconds).
RESET SLAVE;
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=4294967296;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=4294967296;
ERROR HY000: The requested value for the heartbeat period is either negative or exceeds the maximum allowed (4294967 seconds).
RESET SLAVE;
*** Misc incorrect values ***
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD='-1';
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD='-1';
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''-1'' at line 1
RESET SLAVE;
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD='123abc';
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD='123abc';
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''123abc'' at line 1
RESET SLAVE;
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD='';
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD='';
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '''' at line 1
RESET SLAVE;
*** Running slave ***
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=0.1;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=0.1;
include/start_slave.inc
Heartbeat event received
@@ -218,7 +218,7 @@ BEGIN
UPDATE test.t1 SET a = a + 1 WHERE a < 10;
END|
RESET SLAVE;
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=5;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=5;
include/start_slave.inc
SET @@global.event_scheduler=1;
Number of received heartbeat events: 0
@@ -231,7 +231,7 @@ RESET SLAVE;
DROP TABLE t1;
DROP TABLE t1;
RESET MASTER;
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=0.5;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=0.5;
include/start_slave.inc
Heartbeat events are received while rotation of relay logs (1 means 'yes'): 1
@@ -240,7 +240,7 @@ SET @@global.slave_compressed_protocol=1;
include/stop_slave.inc
RESET SLAVE;
SET @@global.slave_compressed_protocol=1;
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=0.1;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=0.1;
include/start_slave.inc
Heartbeat event received
SET @@global.slave_compressed_protocol=0;
@@ -249,7 +249,7 @@ SET @@global.slave_compressed_protocol=0;
*** Reset master ***
STOP SLAVE;
RESET SLAVE;
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=0.1;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=0.1;
include/start_slave.inc
RESET MASTER;
Heartbeat events are received after reset of master (1 means 'yes'): 1
@@ -257,7 +257,7 @@ Heartbeat events are received after reset of master (1 means 'yes'): 1
*** Reload master ***
STOP SLAVE;
RESET SLAVE;
-CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=0.1, MASTER_CONNECT_RETRY = 5;
+CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=MASTER_PORT, MASTER_USER='root', MASTER_CONNECT_RETRY=20, MASTER_HEARTBEAT_PERIOD=0.1;
include/start_slave.inc
Heartbeat event received
include/rpl_restart_server.inc [server_number=1]
diff --git a/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test b/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test
index 94667485dfe..a89a1847bc6 100644
--- a/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test
+++ b/mysql-test/suite/rpl/t/rpl_heartbeat_basic.test
@@ -18,6 +18,9 @@
--source include/have_binlog_format_mixed.inc
--echo
+# Set number of retries to connect to master
+let $connect_retry= 20;
+
--echo *** Preparing ***
--connection slave
--source include/stop_slave.inc
@@ -57,7 +60,7 @@ RESET SLAVE;
SET @@global.slave_net_timeout=30;
--enable_warnings
--replace_result $MASTER_MYPORT MASTER_PORT
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=5;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=5;
RESET SLAVE;
SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
--echo
@@ -68,7 +71,7 @@ SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
SET @@global.slave_net_timeout=50;
--enable_warnings
--replace_result $MASTER_MYPORT MASTER_PORT
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root';
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry;
SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
SET @@global.slave_net_timeout=@restore_slave_net_timeout;
RESET SLAVE;
@@ -88,7 +91,7 @@ RESET SLAVE;
let $slave_net_timeout= query_get_value(SHOW VARIABLES LIKE 'slave_net_timeout', Value, 1);
inc $slave_net_timeout;
--replace_result $MASTER_MYPORT MASTER_PORT $slave_net_timeout SLAVE_NET_TIMEOUT
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=$slave_net_timeout;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=$slave_net_timeout;
RESET SLAVE;
--echo
@@ -98,7 +101,7 @@ RESET SLAVE;
SET @@global.slave_net_timeout=20;
--enable_warnings
--replace_result $MASTER_MYPORT MASTER_PORT
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=5;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=5;
SHOW VARIABLES LIKE 'slave_net_timeout';
SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
SET @@global.slave_net_timeout=2*@@global.slave_net_timeout;
@@ -118,7 +121,7 @@ SET @@global.slave_net_timeout=500;
SET @@global.slave_net_timeout=200;
RESET SLAVE;
--replace_result $MASTER_MYPORT MASTER_PORT
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root';
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry;
--source include/start_slave.inc
--connection master
--sync_slave_with_master
@@ -138,7 +141,7 @@ SET @@global.slave_net_timeout=@restore_slave_net_timeout;
SET @@global.slave_net_timeout=100;
--enable_warnings
--replace_result $MASTER_MYPORT MASTER_PORT
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=20;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=20;
--source include/start_slave.inc
--connection master
--sync_slave_with_master
@@ -154,7 +157,7 @@ SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
SET @@global.slave_net_timeout=50;
--enable_warnings
--replace_result $MASTER_MYPORT MASTER_PORT
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=30;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=30;
--let $rpl_server_number= 2
--source include/rpl_restart_server.inc
SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
@@ -164,7 +167,7 @@ SET @restore_slave_net_timeout=@@global.slave_net_timeout;
# Disable heartbeat
--echo *** Disable heartbeat ***
--replace_result $MASTER_MYPORT MASTER_PORT
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=0;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0;
SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
SHOW STATUS LIKE 'slave_received_heartbeats';
--source include/start_slave.inc
@@ -188,48 +191,48 @@ let $slave_heartbeat_timeout= query_get_value(SHOW GLOBAL STATUS LIKE 'slave_hea
--echo *** Min slave_heartbeat_timeout ***
--replace_result $MASTER_MYPORT MASTER_PORT
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=0.001;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0.001;
SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
RESET SLAVE;
--replace_result $MASTER_MYPORT MASTER_PORT
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=0.0009;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0.0009;
SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
RESET SLAVE;
--echo
--echo *** Max slave_heartbeat_timeout ***
--replace_result $MASTER_MYPORT MASTER_PORT
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=4294967;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=4294967;
SHOW GLOBAL STATUS LIKE 'slave_heartbeat_period';
RESET SLAVE;
--replace_result $MASTER_MYPORT MASTER_PORT
--error ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=4294968;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=4294968;
RESET SLAVE;
# Check double size of max allowed value for master_heartbeat_period
--replace_result $MASTER_MYPORT MASTER_PORT
--error ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=8589935;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=8589935;
RESET SLAVE;
# Check 2^32
--replace_result $MASTER_MYPORT MASTER_PORT
--error ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=4294967296;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=4294967296;
RESET SLAVE;
--echo
--echo *** Misc incorrect values ***
--replace_result $MASTER_MYPORT MASTER_PORT
--error ER_PARSE_ERROR
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD='-1';
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD='-1';
RESET SLAVE;
--replace_result $MASTER_MYPORT MASTER_PORT
--error ER_PARSE_ERROR
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD='123abc';
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD='123abc';
RESET SLAVE;
--replace_result $MASTER_MYPORT MASTER_PORT
--error ER_PARSE_ERROR
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD='';
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD='';
RESET SLAVE;
--echo
@@ -240,7 +243,7 @@ RESET SLAVE;
# Check received heartbeat events for running slave
--echo *** Running slave ***
--replace_result $MASTER_MYPORT MASTER_PORT
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=0.1;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0.1;
--source include/start_slave.inc
--connection master
--sync_slave_with_master
@@ -342,7 +345,7 @@ DELIMITER ;|
--connection slave
RESET SLAVE;
--replace_result $MASTER_MYPORT MASTER_PORT
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=5;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=5;
--source include/start_slave.inc
--connection master
# Enable scheduler
@@ -374,7 +377,7 @@ DROP TABLE t1;
RESET MASTER;
--connection slave
--replace_result $MASTER_MYPORT MASTER_PORT
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=0.5;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0.5;
let $slave_param_comparison= =;
--source include/start_slave.inc
let $rcvd_heartbeats_before= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1);
@@ -401,7 +404,7 @@ SET @@global.slave_compressed_protocol=1;
RESET SLAVE;
SET @@global.slave_compressed_protocol=1;
--replace_result $MASTER_MYPORT MASTER_PORT
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=0.1;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0.1;
--source include/start_slave.inc
let $status_var_value= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1);
let $status_var= slave_received_heartbeats;
@@ -420,7 +423,7 @@ SET @@global.slave_compressed_protocol=0;
STOP SLAVE;
RESET SLAVE;
--replace_result $MASTER_MYPORT MASTER_PORT
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=0.1;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0.1;
--source include/start_slave.inc
let $rcvd_heartbeats_before= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1);
--connection master
@@ -439,7 +442,7 @@ let $result= query_get_value(SELECT ($rcvd_heartbeats_after - $rcvd_heartbeats_b
STOP SLAVE;
RESET SLAVE;
--replace_result $MASTER_MYPORT MASTER_PORT
-eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=0.1, MASTER_CONNECT_RETRY = 5;
+eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=0.1;
--source include/start_slave.inc
# Wait until slave_received_heartbeats will be incremented
let $status_var_value= query_get_value(SHOW STATUS LIKE 'slave_received_heartbeats', Value, 1);
@@ -474,7 +477,7 @@ let $status_var_comparsion= >;
#let $slave_binlog= query_get_value(SHOW MASTER STATUS, File, 1);
--connection master
#--replace_result $SLAVE_MYPORT SLAVE_PORT $slave_binlog SLAVE_BINLOG
-#eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$SLAVE_MYPORT, MASTER_USER='root', MASTER_HEARTBEAT_PERIOD=1, MASTER_LOG_FILE='$slave_binlog';
+#eval CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=$SLAVE_MYPORT, MASTER_USER='root', MASTER_CONNECT_RETRY=$connect_retry, MASTER_HEARTBEAT_PERIOD=1, MASTER_LOG_FILE='$slave_binlog';
--source include/start_slave.inc
# Insert data on master and on slave and make sure that it replicated for both directions
diff --git a/mysql-test/t/bug46261.test b/mysql-test/t/bug46261.test
index 67bdc995850..e0eae9b86fb 100644
--- a/mysql-test/t/bug46261.test
+++ b/mysql-test/t/bug46261.test
@@ -7,7 +7,7 @@
--replace_regex /\.dll/.so/
--error ER_OPTION_PREVENTS_STATEMENT
-eval INSTALL PLUGIN example SONAME $HA_EXAMPLE_SO;
+eval INSTALL PLUGIN example SONAME '$EXAMPLE_PLUGIN';
--replace_regex /\.dll/.so/
--error ER_OPTION_PREVENTS_STATEMENT
diff --git a/mysql-test/t/fulltext_plugin.test b/mysql-test/t/fulltext_plugin.test
index 25e4302ef0d..b591a7949e5 100644
--- a/mysql-test/t/fulltext_plugin.test
+++ b/mysql-test/t/fulltext_plugin.test
@@ -4,7 +4,7 @@
# BUG#39746 - Debug flag breaks struct definition (server crash)
#
--replace_regex /\.dll/.so/
-eval INSTALL PLUGIN simple_parser SONAME $MYPLUGLIB_SO;
+eval INSTALL PLUGIN simple_parser SONAME '$SIMPLE_PARSER';
CREATE TABLE t1(a TEXT, b TEXT, FULLTEXT(a) WITH PARSER simple_parser);
ALTER TABLE t1 ADD FULLTEXT(b) WITH PARSER simple_parser;
DROP TABLE t1;
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index aff99d7e303..9a9a8110a74 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -1370,6 +1370,17 @@ DROP TABLE t1;
SELECT '1' IN ('1', SUBSTRING(-9223372036854775809, 1));
SELECT CONVERT(('' IN (REVERSE(CAST(('') AS DECIMAL)), '')), CHAR(3));
+--echo #
+--echo # Bug#58165: "my_empty_string" gets modified and causes LOAD DATA to fail
+--echo # and other crashes
+--echo #
+CREATE TABLE t1 ( a TEXT );
+SELECT 'aaaaaaaaaaaaaa' INTO OUTFILE 'bug58165.txt';
+SELECT insert( substring_index( 'a', 'a', 'b' ), 1, 0, 'x' );
+LOAD DATA INFILE 'bug58165.txt' INTO TABLE t1;
+SELECT * FROM t1;
+DROP TABLE t1;
+
--echo End of 5.1 tests
--echo Start of 5.4 tests
diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test
index 4aad3f80b68..6c0fdda1cea 100644
--- a/mysql-test/t/gis.test
+++ b/mysql-test/t/gis.test
@@ -747,6 +747,16 @@ SET @a=0x00000000030000000000000000000000000000000000144000000000000014400000000
SET @a=POLYFROMWKB(@a);
+#
+# Bug #57321 crashes and valgrind errors from spatial types
+#
+
+create table t1(a polygon NOT NULL)engine=myisam;
+insert into t1 values (geomfromtext("point(0 1)"));
+insert into t1 values (geomfromtext("point(1 0)"));
+select * from (select polygon(t1.a) as p from t1 order by t1.a) d;
+drop table t1;
+
--echo End of 5.1 tests
#
diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test
index 3251ff292b6..72d27d3571a 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/join_outer.test
@@ -1010,4 +1010,86 @@ GROUP BY t2.f1, t2.f2;
DROP TABLE t1,t2;
+--echo #
+--echo # Bug#57034 incorrect OUTER JOIN result when joined on unique key
+--echo #
+
+CREATE TABLE t1 (pk INT PRIMARY KEY,
+ col_int INT,
+ col_int_unique INT UNIQUE KEY);
+INSERT INTO t1 VALUES (1,NULL,2), (2,0,0);
+
+CREATE TABLE t2 (pk INT PRIMARY KEY,
+ col_int INT,
+ col_int_unique INT UNIQUE KEY);
+INSERT INTO t2 VALUES (1,0,1), (2,0,2);
+
+EXPLAIN
+SELECT * FROM t1 LEFT JOIN t2
+ ON t1.col_int_unique = t2.col_int_unique AND t1.col_int = t2.col_int
+ WHERE t1.pk=1;
+
+SELECT * FROM t1 LEFT JOIN t2
+ ON t1.col_int_unique = t2.col_int_unique AND t1.col_int = t2.col_int
+ WHERE t1.pk=1;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug#48046 Server incorrectly processing JOINs on NULL values
+--echo #
+
+# bug#48046 is a duplicate of bug#57034
+
+CREATE TABLE `BB` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `time_key` time DEFAULT NULL,
+ `varchar_key` varchar(1) DEFAULT NULL,
+ `varchar_nokey` varchar(1) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `time_key` (`time_key`),
+ KEY `varchar_key` (`varchar_key`)
+) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
+
+INSERT INTO `BB` VALUES (10,'18:27:58',NULL,NULL);
+
+SELECT table1.time_key AS field1, table2.pk
+FROM BB table1 LEFT JOIN BB table2
+ ON table2.varchar_nokey = table1.varchar_key
+ HAVING field1;
+
+DROP TABLE BB;
+
+--echo #
+--echo # Bug#49600 Server incorrectly processing RIGHT JOIN with
+--echo # constant WHERE clause and no index
+--echo #
+
+# bug#49600 is a duplicate of bug#57034
+
+CREATE TABLE `BB` (
+ `col_datetime_key` datetime DEFAULT NULL,
+ `col_varchar_key` varchar(1) DEFAULT NULL,
+ `col_varchar_nokey` varchar(1) DEFAULT NULL,
+ KEY `col_datetime_key` (`col_datetime_key`),
+ KEY `col_varchar_key` (`col_varchar_key`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+INSERT INTO `BB` VALUES ('1900-01-01 00:00:00',NULL,NULL);
+
+SELECT table1.col_datetime_key
+FROM BB table1 RIGHT JOIN BB table2
+ ON table2 .col_varchar_nokey = table1.col_varchar_key
+ WHERE 7;
+
+# Disable keys, and we get incorrect result for the same query
+ALTER TABLE BB DISABLE KEYS;
+
+SELECT table1.col_datetime_key
+FROM BB table1 RIGHT JOIN BB table2
+ ON table2 .col_varchar_nokey = table1.col_varchar_key
+ WHERE 7;
+
+DROP TABLE BB;
+
--echo End of 5.1 tests
diff --git a/mysql-test/t/mysqlbinlog_row_big.test b/mysql-test/t/mysqlbinlog_row_big.test
index 75f3b90269f..ffd1b79af34 100644
--- a/mysql-test/t/mysqlbinlog_row_big.test
+++ b/mysql-test/t/mysqlbinlog_row_big.test
@@ -79,8 +79,8 @@ eval CREATE TABLE t1 (
--echo # Insert some big rows.
--echo #
---echo 256MB
-INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 16777216));
+--echo 64MB
+INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 4194304));
--echo 32MB
INSERT INTO t1 VALUES (REPEAT('ManyMegaByteBlck', 2097152));
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index 7108b9f9878..9ff92496653 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -859,6 +859,12 @@ insert into t1 values ('`select 42`');
let $a= `select * from t1`;
# This should output `select 42`, not evaluate it again to 42
echo $a;
+insert into t1 values ('$dollar');
+# These should also output the string without evaluating it.
+let $a= query_get_value(select * from t1 order by a, a, 1);
+echo $a;
+let $a= query_get_value(select * from t1 order by a, a, 2);
+echo $a;
drop table t1;
--error 1
diff --git a/mysql-test/t/plugin.test b/mysql-test/t/plugin.test
index 0bf86b47dd7..117eaf1e19b 100644
--- a/mysql-test/t/plugin.test
+++ b/mysql-test/t/plugin.test
@@ -5,15 +5,15 @@ CREATE TABLE t1(a int) ENGINE=EXAMPLE;
DROP TABLE t1;
--replace_regex /\.dll/.so/
-eval INSTALL PLUGIN example SONAME $HA_EXAMPLE_SO;
+eval INSTALL PLUGIN example SONAME '$EXAMPLE_PLUGIN';
--replace_regex /\.dll/.so/
--error 1125
-eval INSTALL PLUGIN EXAMPLE SONAME $HA_EXAMPLE_SO;
+eval INSTALL PLUGIN EXAMPLE SONAME '$EXAMPLE_PLUGIN';
UNINSTALL PLUGIN example;
--replace_regex /\.dll/.so/
-eval INSTALL PLUGIN example SONAME $HA_EXAMPLE_SO;
+eval INSTALL PLUGIN example SONAME '$EXAMPLE_PLUGIN';
CREATE TABLE t1(a int) ENGINE=EXAMPLE;
@@ -41,7 +41,7 @@ UNINSTALL PLUGIN non_exist;
--echo # to impossible int val
--echo #
--replace_regex /\.dll/.so/
-eval INSTALL PLUGIN example SONAME $HA_EXAMPLE_SO;
+eval INSTALL PLUGIN example SONAME '$EXAMPLE_PLUGIN';
SET GLOBAL example_enum_var= e1;
SET GLOBAL example_enum_var= e2;
@@ -56,7 +56,7 @@ UNINSTALL PLUGIN example;
# Bug #32757 hang with sql_mode set when setting some global variables
#
--replace_regex /\.dll/.so/
-eval INSTALL PLUGIN example SONAME $HA_EXAMPLE_SO;
+eval INSTALL PLUGIN example SONAME '$EXAMPLE_PLUGIN';
select @@session.sql_mode into @old_sql_mode;
diff --git a/mysql-test/t/plugin_auth_qa_2-master.opt b/mysql-test/t/plugin_auth_qa_2-master.opt
index c29153ac95b..354907b9366 100644
--- a/mysql-test/t/plugin_auth_qa_2-master.opt
+++ b/mysql-test/t/plugin_auth_qa_2-master.opt
@@ -1,2 +1,2 @@
-$PLUGIN_AUTH_OPT
-$PLUGIN_AUTH_INTERFACE
+$PLUGIN_AUTH_INTERFACE_OPT
+$PLUGIN_AUTH_INTERFACE_LOAD
diff --git a/mysql-test/t/plugin_auth_qa_3-master.opt b/mysql-test/t/plugin_auth_qa_3-master.opt
index 5cc2af0a358..e1754862a4d 100644
--- a/mysql-test/t/plugin_auth_qa_3-master.opt
+++ b/mysql-test/t/plugin_auth_qa_3-master.opt
@@ -1,2 +1,2 @@
-$PLUGIN_AUTH_OPT
-$PLUGIN_AUTH_SERVER
+$PLUGIN_AUTH_SERVER_OPT
+$PLUGIN_AUTH_SERVER_LOAD
diff --git a/mysql-test/t/plugin_not_embedded.test b/mysql-test/t/plugin_not_embedded.test
index 40024efcaad..a2b7b8a0fe4 100644
--- a/mysql-test/t/plugin_not_embedded.test
+++ b/mysql-test/t/plugin_not_embedded.test
@@ -8,7 +8,7 @@
GRANT INSERT ON mysql.plugin TO bug51770@localhost;
connect(con1,localhost,bug51770,,);
--replace_regex /\.dll/.so/
-eval INSTALL PLUGIN example SONAME $HA_EXAMPLE_SO;
+eval INSTALL PLUGIN example SONAME '$EXAMPLE_PLUGIN';
--error ER_TABLEACCESS_DENIED_ERROR
UNINSTALL PLUGIN example;
connection default;
@@ -25,7 +25,7 @@ DROP USER bug51770@localhost;
# The bug consisted of not recognizing / on Windows, so checking / on
# all platforms should cover this case.
-let $path = `select CONCAT_WS('/', '..', $HA_EXAMPLE_SO)`;
+let $path = `select CONCAT_WS('/', '..', '$EXAMPLE_PLUGIN')`;
--replace_regex /\.dll/.so/
--error ER_UDF_NO_PATHS
eval INSTALL PLUGIN example SONAME '$path';
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index 3ed7213e8d7..043b03e4686 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -4123,6 +4123,76 @@ SELECT 1 FROM t1 ORDER BY a COLLATE latin1_german2_ci;
DROP TABLE t1;
+
+--echo #
+--echo # Bug #58422: Incorrect result when OUTER JOIN'ing
+--echo # with an empty table
+--echo #
+
+CREATE TABLE t_empty(pk INT PRIMARY KEY, i INT) ENGINE = MYISAM;
+CREATE TABLE t1(pk INT PRIMARY KEY, i INT) ENGINE = MYISAM;
+INSERT INTO t1 VALUES (1,1), (2,2), (3,3);
+CREATE TABLE t2(pk INT PRIMARY KEY, i INT) ENGINE = MYISAM;
+INSERT INTO t2 VALUES (1,1), (2,2), (3,3);
+
+EXPLAIN
+SELECT *
+ FROM
+ t1
+ LEFT OUTER JOIN
+ (t2 INNER JOIN t_empty ON TRUE)
+ ON t1.pk=t2.pk
+ WHERE t2.pk <> 2;
+
+SELECT *
+ FROM
+ t1
+ LEFT OUTER JOIN
+ (t2 INNER JOIN t_empty ON TRUE)
+ ON t1.pk=t2.pk
+ WHERE t2.pk <> 2;
+
+
+EXPLAIN
+SELECT *
+ FROM
+ t1
+ LEFT OUTER JOIN
+ (t2 CROSS JOIN t_empty)
+ ON t1.pk=t2.pk
+ WHERE t2.pk <> 2;
+
+SELECT *
+ FROM
+ t1
+ LEFT OUTER JOIN
+ (t2 CROSS JOIN t_empty)
+ ON t1.pk=t2.pk
+ WHERE t2.pk <> 2;
+
+
+EXPLAIN
+SELECT *
+ FROM
+ t1
+ LEFT OUTER JOIN
+ (t2 INNER JOIN t_empty ON t_empty.i=t2.i)
+ ON t1.pk=t2.pk
+ WHERE t2.pk <> 2;
+
+SELECT *
+ FROM
+ t1
+ LEFT OUTER JOIN
+ (t2 INNER JOIN t_empty ON t_empty.i=t2.i)
+ ON t1.pk=t2.pk
+ WHERE t2.pk <> 2;
+
+
+
+DROP TABLE t1,t2,t_empty;
+
+
--echo End of 5.1 tests
--echo #
diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test
index dfac6f93b7d..76423b11b99 100644
--- a/mysql-test/t/type_timestamp.test
+++ b/mysql-test/t/type_timestamp.test
@@ -377,3 +377,21 @@ SELECT a FROM t1;
DROP TABLE t1;
--echo End of Bug#50888
+
+--echo #
+--echo # Bug59330: Incorrect result when comparing an aggregate
+--echo # function with TIMESTAMP
+--echo #
+CREATE TABLE t1 (dt DATETIME, ts TIMESTAMP);
+INSERT INTO t1 VALUES('2011-01-06 12:34:30', '2011-01-06 12:34:30');
+SELECT MAX(dt), MAX(ts) FROM t1;
+SELECT MAX(ts) < '2010-01-01 00:00:00' FROM t1;
+SELECT MAX(dt) < '2010-01-01 00:00:00' FROM t1;
+SELECT MAX(ts) > '2010-01-01 00:00:00' FROM t1;
+SELECT MAX(dt) > '2010-01-01 00:00:00' FROM t1;
+SELECT MAX(ts) = '2011-01-06 12:34:30' FROM t1;
+SELECT MAX(dt) = '2011-01-06 12:34:30' FROM t1;
+DROP TABLE t1;
+
+--echo End of 5.5 tests
+
diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test
index 3ccef94d7ea..5896e25feda 100644
--- a/mysql-test/t/view_grant.test
+++ b/mysql-test/t/view_grant.test
@@ -1503,8 +1503,6 @@ SHOW CREATE VIEW v1;
DROP TABLE t1;
DROP VIEW v1;
-# Wait till we reached the initial number of concurrent sessions
---source include/wait_until_count_sessions.inc
--echo #
--echo # Bug #46019: ERROR 1356 When selecting from within another
@@ -1546,3 +1544,145 @@ CREATE DEFINER=`unknown`@`unknown` SQL SECURITY DEFINER VIEW v1 AS SELECT 1;
--error ER_NO_SUCH_USER
LOCK TABLES v1 READ;
DROP VIEW v1;
+
+
+--echo #
+--echo # Bug #58499 "DEFINER-security view selecting from INVOKER-security view
+--echo # access check wrong".
+--echo #
+--echo # Check that we correctly handle privileges for various combinations
+--echo # of INVOKER and DEFINER-security views using each other.
+--disable_warnings
+DROP DATABASE IF EXISTS mysqltest1;
+--enable_warnings
+CREATE DATABASE mysqltest1;
+USE mysqltest1;
+CREATE TABLE t1 (i INT);
+CREATE TABLE t2 (j INT);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+--echo #
+--echo # 1) DEFINER-security view uses INVOKER-security view (covers
+--echo # scenario originally described in the bug report).
+CREATE SQL SECURITY INVOKER VIEW v1_uses_t1 AS SELECT * FROM t1;
+CREATE SQL SECURITY INVOKER VIEW v1_uses_t2 AS SELECT * FROM t2;
+CREATE USER 'mysqluser1'@'%';
+GRANT CREATE VIEW ON mysqltest1.* TO 'mysqluser1'@'%';
+GRANT SELECT ON t1 TO 'mysqluser1'@'%';
+--echo # To be able create 'v2_uses_t2' we also need select on t2.
+GRANT SELECT ON t2 TO 'mysqluser1'@'%';
+GRANT SELECT ON v1_uses_t1 TO 'mysqluser1'@'%';
+GRANT SELECT ON v1_uses_t2 TO 'mysqluser1'@'%';
+--echo #
+--echo # Connection 'mysqluser1'.
+--connect (mysqluser1, localhost, mysqluser1,,mysqltest1)
+CREATE SQL SECURITY DEFINER VIEW v2_uses_t1 AS SELECT * FROM v1_uses_t1;
+CREATE SQL SECURITY DEFINER VIEW v2_uses_t2 AS SELECT * FROM v1_uses_t2;
+--echo #
+--echo # Connection 'default'.
+--connection default
+CREATE USER 'mysqluser2'@'%';
+GRANT SELECT ON v2_uses_t1 TO 'mysqluser2'@'%';
+GRANT SELECT ON v2_uses_t2 TO 'mysqluser2'@'%';
+GRANT SELECT ON t2 TO 'mysqluser2'@'%';
+GRANT CREATE VIEW ON mysqltest1.* TO 'mysqluser2'@'%';
+--echo # Make 'mysqluser1' unable to access t2.
+REVOKE SELECT ON t2 FROM 'mysqluser1'@'%';
+--echo #
+--echo # Connection 'mysqluser2'.
+--connect (mysqluser2, localhost, mysqluser2,,mysqltest1)
+--echo # The below statement should succeed thanks to suid nature of v2_uses_t1.
+SELECT * FROM v2_uses_t1;
+--echo # The below statement should fail due to suid nature of v2_uses_t2.
+--error ER_VIEW_INVALID
+SELECT * FROM v2_uses_t2;
+--echo #
+--echo # 2) INVOKER-security view uses INVOKER-security view.
+--echo #
+--echo # Connection 'default'.
+--connection default
+DROP VIEW v2_uses_t1, v2_uses_t2;
+CREATE SQL SECURITY INVOKER VIEW v2_uses_t1 AS SELECT * FROM v1_uses_t1;
+CREATE SQL SECURITY INVOKER VIEW v2_uses_t2 AS SELECT * FROM v1_uses_t2;
+GRANT SELECT ON v2_uses_t1 TO 'mysqluser1'@'%';
+GRANT SELECT ON v2_uses_t2 TO 'mysqluser1'@'%';
+GRANT SELECT ON v1_uses_t1 TO 'mysqluser2'@'%';
+GRANT SELECT ON v1_uses_t2 TO 'mysqluser2'@'%';
+--echo #
+--echo # Connection 'mysqluser1'.
+--connection mysqluser1
+--echo # For both versions of 'v2' 'mysqluser1' privileges should be used.
+SELECT * FROM v2_uses_t1;
+--error ER_VIEW_INVALID
+SELECT * FROM v2_uses_t2;
+--echo #
+--echo # Connection 'mysqluser2'.
+--connection mysqluser2
+--echo # And now for both versions of 'v2' 'mysqluser2' privileges should
+--echo # be used.
+--error ER_VIEW_INVALID
+SELECT * FROM v2_uses_t1;
+SELECT * FROM v2_uses_t2;
+--echo #
+--echo # 3) INVOKER-security view uses DEFINER-security view.
+--echo #
+--echo # Connection 'default'.
+--connection default
+DROP VIEW v1_uses_t1, v1_uses_t2;
+--echo # To be able create 'v1_uses_t2' we also need select on t2.
+GRANT SELECT ON t2 TO 'mysqluser1'@'%';
+--echo #
+--echo # Connection 'mysqluser1'.
+--connection mysqluser1
+CREATE SQL SECURITY DEFINER VIEW v1_uses_t1 AS SELECT * FROM t1;
+CREATE SQL SECURITY DEFINER VIEW v1_uses_t2 AS SELECT * FROM t2;
+--echo #
+--echo # Connection 'default'.
+--connection default
+--echo # Make 'mysqluser1' unable to access t2.
+REVOKE SELECT ON t2 FROM 'mysqluser1'@'%';
+--echo #
+--echo # Connection 'mysqluser2'.
+--connection mysqluser2
+--echo # Due to suid nature of v1_uses_t1 and v1_uses_t2 the first
+--echo # select should succeed and the second select should fail.
+SELECT * FROM v2_uses_t1;
+--error ER_VIEW_INVALID
+SELECT * FROM v2_uses_t2;
+--echo #
+--echo # 4) DEFINER-security view uses DEFINER-security view.
+--echo #
+--echo # Connection 'default'.
+--connection default
+DROP VIEW v2_uses_t1, v2_uses_t2;
+--echo # To be able create 'v2_uses_t2' we also need select on t2.
+GRANT SELECT ON t2 TO 'mysqluser1'@'%';
+--echo #
+--echo # Connection 'mysqluser2'.
+--connection mysqluser2
+CREATE SQL SECURITY DEFINER VIEW v2_uses_t1 AS SELECT * FROM v1_uses_t1;
+CREATE SQL SECURITY DEFINER VIEW v2_uses_t2 AS SELECT * FROM v1_uses_t2;
+--echo #
+--echo # Connection 'default'.
+--connection default
+--echo # Make 'mysqluser1' unable to access t2.
+REVOKE SELECT ON t2 FROM 'mysqluser1'@'%';
+--echo #
+--echo # Connection 'mysqluser2'.
+--connection mysqluser2
+--echo # Again privileges of creator of innermost views should apply.
+SELECT * FROM v2_uses_t1;
+--error ER_VIEW_INVALID
+SELECT * FROM v2_uses_t2;
+
+--disconnect mysqluser1
+--disconnect mysqluser2
+--connection default
+USE test;
+DROP DATABASE mysqltest1;
+DROP USER 'mysqluser1'@'%';
+DROP USER 'mysqluser2'@'%';
+
+
+# Wait till we reached the initial number of concurrent sessions
+--source include/wait_until_count_sessions.inc
diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c
index 614f49fc425..01b3b912aae 100644
--- a/mysys/my_getsystime.c
+++ b/mysys/my_getsystime.c
@@ -25,13 +25,25 @@
#include "mysys_priv.h"
#include "my_static.h"
+/**
+ Get high-resolution time.
+
+ @remark For windows platforms we need the frequency value of
+ the CPU. This is initialized in my_init.c through
+ QueryPerformanceFrequency(). If the Windows platform
+ doesn't support QueryPerformanceFrequency(), zero is
+ returned.
+
+ @retval current high-resolution time.
+*/
+
ulonglong my_getsystime()
{
#ifdef HAVE_CLOCK_GETTIME
struct timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100;
-#elif defined(__WIN__)
+#elif defined(_WIN32)
LARGE_INTEGER t_cnt;
if (query_performance_frequency)
{
@@ -50,22 +62,17 @@ ulonglong my_getsystime()
}
-/*
- Return current time
+/**
+ Return current time.
- SYNOPSIS
- my_time()
- flags If MY_WME is set, write error if time call fails
+ @param flags If MY_WME is set, write error if time call fails.
+ @retval current time.
*/
-time_t my_time(myf flags __attribute__((unused)))
+time_t my_time(myf flags)
{
time_t t;
-#ifdef HAVE_GETHRTIME
- (void) my_micro_time_and_time(&t);
- return t;
-#else
/* The following loop is here beacuse time() may fail on some systems */
while ((t= time(0)) == (time_t) -1)
{
@@ -73,39 +80,26 @@ time_t my_time(myf flags __attribute__((unused)))
fprintf(stderr, "%s: Warning: time() call failed\n", my_progname);
}
return t;
-#endif
}
-/*
- Return time in micro seconds
-
- SYNOPSIS
- my_micro_time()
-
- NOTES
- This function is to be used to measure performance in micro seconds.
- As it's not defined whats the start time for the clock, this function
- us only useful to measure time between two moments.
+/**
+ Return time in microseconds.
- For windows platforms we need the frequency value of the CUP. This is
- initalized in my_init.c through QueryPerformanceFrequency().
+ @remark This function is to be used to measure performance in
+ micro seconds. As it's not defined whats the start time
+ for the clock, this function us only useful to measure
+ time between two moments.
- If Windows platform doesn't support QueryPerformanceFrequency() we will
- obtain the time via GetClockCount, which only supports milliseconds.
-
- RETURN
- Value in microseconds from some undefined point in time
+ @retval Value in microseconds from some undefined point in time.
*/
ulonglong my_micro_time()
{
-#if defined(__WIN__)
+#ifdef _WIN32
ulonglong newtime;
GetSystemTimeAsFileTime((FILETIME*)&newtime);
return (newtime/10);
-#elif defined(HAVE_GETHRTIME)
- return gethrtime()/1000;
#else
ulonglong newtime;
struct timeval t;
@@ -116,69 +110,37 @@ ulonglong my_micro_time()
{}
newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec;
return newtime;
-#endif /* defined(__WIN__) */
+#endif
}
-/*
+/**
Return time in seconds and timer in microseconds (not different start!)
- SYNOPSIS
- my_micro_time_and_time()
- time_arg Will be set to seconds since epoch (00:00:00 UTC,
- January 1, 1970)
+ @param time_arg Will be set to seconds since epoch.
- NOTES
- This function is to be useful when we need both the time and microtime.
- For example in MySQL this is used to get the query time start of a query
- and to measure the time of a query (for the slow query log)
+ @remark This function is to be useful when we need both the time and
+ microtime. For example in MySQL this is used to get the query
+ time start of a query and to measure the time of a query (for
+ the slow query log)
- IMPLEMENTATION
- Value of time is as in time() call.
- Value of microtime is same as my_micro_time(), which may be totally
- unrealated to time()
+ @remark The time source is the same as for my_micro_time(), meaning
+ that time values returned by both functions can be intermixed
+ in meaningful ways (i.e. for comparison purposes).
- RETURN
- Value in microseconds from some undefined point in time
+ @retval Value in microseconds from some undefined point in time.
*/
-#define DELTA_FOR_SECONDS 500000000LL /* Half a second */
-
/* Difference between GetSystemTimeAsFileTime() and now() */
#define OFFSET_TO_EPOCH 116444736000000000ULL
ulonglong my_micro_time_and_time(time_t *time_arg)
{
-#if defined(__WIN__)
+#ifdef _WIN32
ulonglong newtime;
GetSystemTimeAsFileTime((FILETIME*)&newtime);
*time_arg= (time_t) ((newtime - OFFSET_TO_EPOCH) / 10000000);
return (newtime/10);
-#elif defined(HAVE_GETHRTIME)
- /*
- Solaris has a very slow time() call. We optimize this by using the very
- fast gethrtime() call and only calling time() every 1/2 second
- */
- static hrtime_t prev_gethrtime= 0;
- static time_t cur_time= 0;
- hrtime_t cur_gethrtime;
-
- mysql_mutex_lock(&THR_LOCK_time);
- cur_gethrtime= gethrtime();
- /*
- Due to bugs in the Solaris (x86) implementation of gethrtime(),
- the time returned by it might not be monotonic. Don't use the
- cached time(2) value if this is a case.
- */
- if ((prev_gethrtime > cur_gethrtime) ||
- ((cur_gethrtime - prev_gethrtime) > DELTA_FOR_SECONDS))
- {
- cur_time= time(0);
- prev_gethrtime= cur_gethrtime;
- }
- *time_arg= cur_time;
- mysql_mutex_unlock(&THR_LOCK_time);
- return cur_gethrtime/1000;
#else
ulonglong newtime;
struct timeval t;
@@ -190,37 +152,31 @@ ulonglong my_micro_time_and_time(time_t *time_arg)
*time_arg= t.tv_sec;
newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec;
return newtime;
-#endif /* defined(__WIN__) */
+#endif
}
-/*
- Returns current time
+/**
+ Returns current time.
- SYNOPSIS
- my_time_possible_from_micro()
- microtime Value from very recent my_micro_time()
+ @param microtime Value from very recent my_micro_time().
- NOTES
- This function returns the current time. The microtime argument is only used
- if my_micro_time() uses a function that can safely be converted to the
- current time.
+ @remark This function returns the current time. The microtime argument
+ is only used if my_micro_time() uses a function that can safely
+ be converted to the current time.
- RETURN
- current time
+ @retval current time.
*/
time_t my_time_possible_from_micro(ulonglong microtime __attribute__((unused)))
{
-#if defined(__WIN__)
+#ifdef _WIN32
time_t t;
while ((t= time(0)) == (time_t) -1)
{}
return t;
-#elif defined(HAVE_GETHRTIME)
- return my_time(0); /* Cached time */
#else
return (time_t) (microtime / 1000000);
-#endif /* defined(__WIN__) */
+#endif
}
diff --git a/mysys/my_init.c b/mysys/my_init.c
index f5a2d9ac4bd..9a17d0d6916 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -510,7 +510,7 @@ PSI_mutex_key key_BITMAP_mutex, key_IO_CACHE_append_buffer_lock,
key_my_thread_var_mutex, key_THR_LOCK_charset, key_THR_LOCK_heap,
key_THR_LOCK_isam, key_THR_LOCK_lock, key_THR_LOCK_malloc,
key_THR_LOCK_mutex, key_THR_LOCK_myisam, key_THR_LOCK_net,
- key_THR_LOCK_open, key_THR_LOCK_threads, key_THR_LOCK_time,
+ key_THR_LOCK_open, key_THR_LOCK_threads,
key_TMPDIR_mutex, key_THR_LOCK_myisam_mmap;
static PSI_mutex_info all_mysys_mutexes[]=
@@ -540,7 +540,6 @@ static PSI_mutex_info all_mysys_mutexes[]=
{ &key_THR_LOCK_net, "THR_LOCK_net", PSI_FLAG_GLOBAL},
{ &key_THR_LOCK_open, "THR_LOCK_open", PSI_FLAG_GLOBAL},
{ &key_THR_LOCK_threads, "THR_LOCK_threads", PSI_FLAG_GLOBAL},
- { &key_THR_LOCK_time, "THR_LOCK_time", PSI_FLAG_GLOBAL},
{ &key_TMPDIR_mutex, "TMPDIR_mutex", PSI_FLAG_GLOBAL},
{ &key_THR_LOCK_myisam_mmap, "THR_LOCK_myisam_mmap", PSI_FLAG_GLOBAL}
};
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index c4b56cde850..a672d8af818 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -25,7 +25,7 @@
pthread_key(struct st_my_thread_var*, THR_KEY_mysys);
mysql_mutex_t THR_LOCK_malloc, THR_LOCK_open,
THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_myisam, THR_LOCK_heap,
- THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, THR_LOCK_time,
+ THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads,
THR_LOCK_myisam_mmap;
mysql_cond_t THR_COND_threads;
@@ -219,7 +219,6 @@ my_bool my_thread_global_init(void)
mysql_mutex_init(key_THR_LOCK_myisam_mmap, &THR_LOCK_myisam_mmap, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_THR_LOCK_heap, &THR_LOCK_heap, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_THR_LOCK_net, &THR_LOCK_net, MY_MUTEX_INIT_FAST);
- mysql_mutex_init(key_THR_LOCK_time, &THR_LOCK_time, MY_MUTEX_INIT_FAST);
mysql_cond_init(key_THR_COND_threads, &THR_COND_threads, NULL);
#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
@@ -288,7 +287,6 @@ void my_thread_global_end(void)
mysql_mutex_destroy(&THR_LOCK_myisam_mmap);
mysql_mutex_destroy(&THR_LOCK_heap);
mysql_mutex_destroy(&THR_LOCK_net);
- mysql_mutex_destroy(&THR_LOCK_time);
mysql_mutex_destroy(&THR_LOCK_charset);
if (all_threads_killed)
{
diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h
index 4e642b7e3d3..e760ea808b7 100644
--- a/mysys/mysys_priv.h
+++ b/mysys/mysys_priv.h
@@ -45,7 +45,7 @@ extern PSI_mutex_key key_BITMAP_mutex, key_IO_CACHE_append_buffer_lock,
key_my_thread_var_mutex, key_THR_LOCK_charset, key_THR_LOCK_heap,
key_THR_LOCK_isam, key_THR_LOCK_lock, key_THR_LOCK_malloc,
key_THR_LOCK_mutex, key_THR_LOCK_myisam, key_THR_LOCK_net,
- key_THR_LOCK_open, key_THR_LOCK_threads, key_THR_LOCK_time,
+ key_THR_LOCK_open, key_THR_LOCK_threads,
key_TMPDIR_mutex, key_THR_LOCK_myisam_mmap;
extern PSI_cond_key key_COND_alarm, key_IO_CACHE_SHARE_cond,
@@ -60,7 +60,7 @@ extern PSI_thread_key key_thread_alarm;
extern mysql_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_keycache;
extern mysql_mutex_t THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_net;
-extern mysql_mutex_t THR_LOCK_charset, THR_LOCK_time;
+extern mysql_mutex_t THR_LOCK_charset;
#include <mysql/psi/mysql_file.h>
diff --git a/sql/item.cc b/sql/item.cc
index 18a88d64470..c7787d65c22 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -7370,8 +7370,7 @@ Item_cache* Item_cache::get_cache(const Item *item, const Item_result type)
return new Item_cache_decimal();
case STRING_RESULT:
/* Not all functions that return DATE/TIME are actually DATE/TIME funcs. */
- if ((item->field_type() == MYSQL_TYPE_DATE ||
- item->field_type() == MYSQL_TYPE_DATETIME ||
+ if ((item->is_datetime() ||
item->field_type() == MYSQL_TYPE_TIME) &&
(const_cast<Item*>(item))->result_as_longlong())
return new Item_cache_datetime(item->field_type());
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index fe8ff3a74d0..ac13ca8a8c5 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -5643,15 +5643,15 @@ longlong Item_equal::val_int()
return 0;
List_iterator_fast<Item_field> it(fields);
Item *item= const_item ? const_item : it++;
+ eval_item->store_value(item);
if ((null_value= item->null_value))
return 0;
- eval_item->store_value(item);
while ((item_field= it++))
{
/* Skip fields of non-const tables. They haven't been read yet */
if (item_field->field->table->const_table)
{
- if ((null_value= item_field->null_value) || eval_item->cmp(item_field))
+ if (eval_item->cmp(item_field) || (null_value= item_field->null_value))
return 0;
}
}
diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h
index 84034841ad5..6145f72b665 100644
--- a/sql/item_geofunc.h
+++ b/sql/item_geofunc.h
@@ -181,6 +181,7 @@ public:
String *val_str(String *);
void fix_length_and_dec()
{
+ Item_geometry_func::fix_length_and_dec();
for (unsigned int i= 0; i < arg_count; ++i)
{
if (args[i]->fixed && args[i]->field_type() != MYSQL_TYPE_GEOMETRY)
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 2a93bcd0153..65eb2bb527b 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -56,6 +56,9 @@ C_MODE_START
#include "../mysys/my_static.h" // For soundex_map
C_MODE_END
+/**
+ @todo Remove this. It is not safe to use a shared String object.
+ */
String my_empty_string("",default_charset_info);
/*
@@ -642,7 +645,7 @@ String *Item_func_des_encrypt::val_str(String *str)
if ((null_value= args[0]->null_value))
return 0; // ENCRYPT(NULL) == NULL
if ((res_length=res->length()) == 0)
- return &my_empty_string;
+ return make_empty_result();
if (arg_count == 1)
{
/* Protect against someone doing FLUSH DES_KEY_FILE */
@@ -832,7 +835,7 @@ String *Item_func_concat_ws::val_str(String *str)
}
if (i == arg_count)
- return &my_empty_string;
+ return make_empty_result();
for (i++; i < arg_count ; i++)
{
@@ -978,7 +981,7 @@ String *Item_func_reverse::val_str(String *str)
return 0;
/* An empty string is a special case as the string pointer may be null */
if (!res->length())
- return &my_empty_string;
+ return make_empty_result();
if (tmp_value.alloced_length() < res->length() &&
tmp_value.realloc(res->length()))
{
@@ -1311,8 +1314,7 @@ String *Item_func_left::val_str(String *str)
/* if "unsigned_flag" is set, we have a *huge* positive number. */
if ((length <= 0) && (!args[1]->unsigned_flag))
- return &my_empty_string;
-
+ return make_empty_result();
if ((res->length() <= (ulonglong) length) ||
(res->length() <= (char_pos= res->charpos((int) length))))
return res;
@@ -1357,7 +1359,7 @@ String *Item_func_right::val_str(String *str)
/* if "unsigned_flag" is set, we have a *huge* positive number. */
if ((length <= 0) && (!args[1]->unsigned_flag))
- return &my_empty_string; /* purecov: inspected */
+ return make_empty_result(); /* purecov: inspected */
if (res->length() <= (ulonglong) length)
return res; /* purecov: inspected */
@@ -1397,7 +1399,7 @@ String *Item_func_substr::val_str(String *str)
/* Negative or zero length, will return empty string. */
if ((arg_count == 3) && (length <= 0) &&
(length == 0 || !args[2]->unsigned_flag))
- return &my_empty_string;
+ return make_empty_result();
/* Assumes that the maximum length of a String is < INT_MAX32. */
/* Set here so that rest of code sees out-of-bound value as such. */
@@ -1408,12 +1410,12 @@ String *Item_func_substr::val_str(String *str)
/* Assumes that the maximum length of a String is < INT_MAX32. */
if ((!args[1]->unsigned_flag && (start < INT_MIN32 || start > INT_MAX32)) ||
(args[1]->unsigned_flag && ((ulonglong) start > INT_MAX32)))
- return &my_empty_string;
+ return make_empty_result();
start= ((start < 0) ? res->numchars() + start : start - 1);
start= res->charpos((int) start);
if ((start < 0) || ((uint) start + 1 > res->length()))
- return &my_empty_string;
+ return make_empty_result();
length= res->charpos((int) length, (uint32) start);
tmp_length= res->length() - start;
@@ -1476,7 +1478,7 @@ String *Item_func_substr_index::val_str(String *str)
null_value=0;
uint delimiter_length= delimiter->length();
if (!res->length() || !delimiter_length || !count)
- return &my_empty_string; // Wrong parameters
+ return make_empty_result(); // Wrong parameters
res->set_charset(collation.collation);
@@ -1826,7 +1828,7 @@ String *Item_func_password::val_str_ascii(String *str)
if ((null_value=args[0]->null_value))
return 0;
if (res->length() == 0)
- return &my_empty_string;
+ return make_empty_result();
my_make_scrambled_password(tmp_value, res->ptr(), res->length());
str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH, &my_charset_latin1);
return str;
@@ -1850,7 +1852,7 @@ String *Item_func_old_password::val_str_ascii(String *str)
if ((null_value=args[0]->null_value))
return 0;
if (res->length() == 0)
- return &my_empty_string;
+ return make_empty_result();
my_make_scrambled_password_323(tmp_value, res->ptr(), res->length());
str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH_323, &my_charset_latin1);
return str;
@@ -1878,8 +1880,7 @@ String *Item_func_encrypt::val_str(String *str)
if ((null_value=args[0]->null_value))
return 0;
if (res->length() == 0)
- return &my_empty_string;
-
+ return make_empty_result();
if (arg_count == 1)
{ // generate random salt
time_t timestamp=current_thd->query_start();
@@ -2141,7 +2142,7 @@ String *Item_func_soundex::val_str(String *str)
for ( ; ; ) /* Skip pre-space */
{
if ((rc= cs->cset->mb_wc(cs, &wc, (uchar*) from, (uchar*) end)) <= 0)
- return &my_empty_string; /* EOL or invalid byte sequence */
+ return make_empty_result(); /* EOL or invalid byte sequence */
if (rc == 1 && cs->ctype)
{
@@ -2166,7 +2167,7 @@ String *Item_func_soundex::val_str(String *str)
{
/* Extra safety - should not really happen */
DBUG_ASSERT(false);
- return &my_empty_string;
+ return make_empty_result();
}
to+= rc;
break;
@@ -2507,7 +2508,7 @@ String *Item_func_make_set::val_str(String *str)
else
{
if (tmp_str.copy(*res)) // Don't use 'str'
- return &my_empty_string;
+ return make_empty_result();
result= &tmp_str;
}
}
@@ -2517,11 +2518,11 @@ String *Item_func_make_set::val_str(String *str)
{ // Copy data to tmp_str
if (tmp_str.alloc(result->length()+res->length()+1) ||
tmp_str.copy(*result))
- return &my_empty_string;
+ return make_empty_result();
result= &tmp_str;
}
if (tmp_str.append(STRING_WITH_LEN(","), &my_charset_bin) || tmp_str.append(*res))
- return &my_empty_string;
+ return make_empty_result();
}
}
}
@@ -2666,7 +2667,7 @@ String *Item_func_repeat::val_str(String *str)
null_value= 0;
if (count <= 0 && (count == 0 || !args[1]->unsigned_flag))
- return &my_empty_string;
+ return make_empty_result();
/* Assumes that the maximum length of a String is < INT_MAX32. */
/* Bounds check on count: If this is triggered, we will error. */
@@ -2948,7 +2949,7 @@ String *Item_func_conv::val_str(String *str)
ptr= longlong2str(dec, ans, to_base);
if (str->copy(ans, (uint32) (ptr-ans), default_charset()))
- return &my_empty_string;
+ return make_empty_result();
return str;
}
@@ -3115,7 +3116,7 @@ String *Item_func_hex::val_str_ascii(String *str)
return 0;
ptr= longlong2str(dec,ans,16);
if (str->copy(ans,(uint32) (ptr-ans), &my_charset_numeric))
- return &my_empty_string; // End of memory
+ return make_empty_result(); // End of memory
return str;
}
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index d76e139883c..626926213e6 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -27,6 +27,16 @@ class MY_LOCALE;
class Item_str_func :public Item_func
{
+protected:
+ /**
+ Sets the result value of the function an empty string, using the current
+ character set. No memory is allocated.
+ @retval A pointer to the str_value member.
+ */
+ String *make_empty_result() {
+ str_value.set("", 0, collation.collation);
+ return &str_value;
+ }
public:
Item_str_func() :Item_func() { decimals=NOT_FIXED_DEC; }
Item_str_func(Item *a) :Item_func(a) {decimals=NOT_FIXED_DEC; }
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 91ce31636b4..fdce2510df4 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -6480,7 +6480,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
OPTIMIZER_SWITCH_ENGINE_CONDITION_PUSHDOWN)
{
COND *push_cond=
- make_cond_for_table(tmp, current_map, current_map);
+ make_cond_for_table(tmp, tab->table->map, tab->table->map);
if (push_cond)
{
/* Push condition to handler */
@@ -12040,7 +12040,7 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
/* Mark for EXPLAIN that the row was not found */
pos->records_read=0.0;
pos->ref_depend_map= 0;
- if (!table->maybe_null || error > 0)
+ if (!table->pos_in_table_list->outer_join || error > 0)
DBUG_RETURN(error);
}
}
@@ -12061,7 +12061,7 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
/* Mark for EXPLAIN that the row was not found */
pos->records_read=0.0;
pos->ref_depend_map= 0;
- if (!table->maybe_null || error > 0)
+ if (!table->pos_in_table_list->outer_join || error > 0)
DBUG_RETURN(error);
}
}
@@ -13099,7 +13099,7 @@ make_cond_for_table(COND *cond, table_map tables, table_map used_table)
new_cond->argument_list()->push_back(fix);
}
/*
- Item_cond_and do not need fix_fields for execution, its parameters
+ Item_cond_or do not need fix_fields for execution, its parameters
are fixed or do not need fix_fields, too
*/
new_cond->quick_fix_field();
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 4b7dab243d2..d19b876a82f 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -51,11 +51,33 @@ bool String::real_alloc(uint32 length)
}
-/*
-** Check that string is big enough. Set string[alloc_length] to 0
-** (for C functions)
-*/
+/**
+ Allocates a new buffer on the heap for this String.
+
+ - If the String's internal buffer is privately owned and heap allocated,
+ one of the following is performed.
+
+ - If the requested length is greater than what fits in the buffer, a new
+ buffer is allocated, data moved and the old buffer freed.
+
+ - If the requested length is less or equal to what fits in the buffer, a
+ null character is inserted at the appropriate position.
+ - If the String does not keep a private buffer on the heap, such a buffer
+ will be allocated and the string copied accoring to its length, as found
+ in String::length().
+
+ For C compatibility, the new string buffer is null terminated.
+
+ @param alloc_length The requested string size in characters, excluding any
+ null terminator.
+
+ @retval false Either the copy operation is complete or, if the size of the
+ new buffer is smaller than the currently allocated buffer (if one exists),
+ no allocation occured.
+
+ @retval true An error occured when attempting to allocate memory.
+*/
bool String::realloc(uint32 alloc_length)
{
uint32 len=ALIGN_SIZE(alloc_length+1);
@@ -128,6 +150,17 @@ bool String::copy()
return FALSE;
}
+/**
+ Copies the internal buffer from str. If this String has a private heap
+ allocated buffer where new data does not fit, a new buffer is allocated
+ before copying and the old buffer freed. Character set information is also
+ copied.
+
+ @param str The string whose internal buffer is to be copied.
+
+ @retval false Success.
+ @retval true Memory allocation failed.
+*/
bool String::copy(const String &str)
{
if (alloc(str.str_length))
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 3642a96de35..dcd9975f399 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -148,6 +148,16 @@ public:
Alloced_length=0;
str_charset=str.str_charset;
}
+
+
+ /**
+ Points the internal buffer to the supplied one. The old buffer is freed.
+ @param str Pointer to the new buffer.
+ @param arg_length Length of the new buffer in characters, excluding any
+ null character.
+ @param cs Character set to use for interpreting string data.
+ @note The new buffer will not be null terminated.
+ */
inline void set(char *str,uint32 arg_length, CHARSET_INFO *cs)
{
free();
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index f569c679776..9b4543bf636 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1270,6 +1270,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
TABLE_LIST *view_tables= lex->query_tables;
TABLE_LIST *view_tables_tail= 0;
TABLE_LIST *tbl;
+ Security_context *security_ctx;
/*
Check rights to run commands (EXPLAIN SELECT & SHOW CREATE) which show
@@ -1416,26 +1417,39 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
if (table->view_suid)
{
/*
- Prepare a security context to check underlying objects of the view
+ For suid views prepare a security context for checking underlying
+ objects of the view.
*/
if (!(table->view_sctx= (Security_context *)
thd->stmt_arena->alloc(sizeof(Security_context))))
goto err;
- /* Assign the context to the tables referenced in the view */
- if (view_tables)
- {
- DBUG_ASSERT(view_tables_tail);
- for (tbl= view_tables; tbl != view_tables_tail->next_global;
- tbl= tbl->next_global)
- tbl->security_ctx= table->view_sctx;
- }
- /* assign security context to SELECT name resolution contexts of view */
- for(SELECT_LEX *sl= lex->all_selects_list;
- sl;
- sl= sl->next_select_in_list())
- sl->context.security_ctx= table->view_sctx;
+ security_ctx= table->view_sctx;
+ }
+ else
+ {
+ /*
+ For non-suid views inherit security context from view's table list.
+ This allows properly handle situation when non-suid view is used
+ from within suid view.
+ */
+ security_ctx= table->security_ctx;
+ }
+
+ /* Assign the context to the tables referenced in the view */
+ if (view_tables)
+ {
+ DBUG_ASSERT(view_tables_tail);
+ for (tbl= view_tables; tbl != view_tables_tail->next_global;
+ tbl= tbl->next_global)
+ tbl->security_ctx= security_ctx;
}
+ /* assign security context to SELECT name resolution contexts of view */
+ for(SELECT_LEX *sl= lex->all_selects_list;
+ sl;
+ sl= sl->next_select_in_list())
+ sl->context.security_ctx= security_ctx;
+
/*
Setup an error processor to hide error messages issued by stored
routines referenced in the view