summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2017-07-20 08:56:09 +0300
committerJan Lindström <jan.lindstrom@mariadb.com>2017-07-20 08:56:09 +0300
commita481de30bb972f055cff088a84a211c1acd5be38 (patch)
tree680d500eddf7b51bd2086218a01a42b28efa1f51
parente8a2a751212a04e835b2b03408132ecbbab52410 (diff)
parent59fca5806af65c8379a993f9e604cb0b20a76e2b (diff)
downloadmariadb-git-a481de30bb972f055cff088a84a211c1acd5be38.tar.gz
Merge tag 'mariadb-5.5.57' into 5.5-galera
-rw-r--r--client/mysql.cc98
-rw-r--r--client/mysqltest.cc34
-rw-r--r--cmake/cpack_rpm.cmake7
-rw-r--r--cmake/ssl.cmake7
-rw-r--r--debian/compat2
-rw-r--r--include/my_global.h6
-rw-r--r--include/my_sys.h2
-rw-r--r--include/mysql_com.h2
-rw-r--r--libmysql/libmysql.c3
-rwxr-xr-xmysql-test/mysql-test-run.pl5
-rw-r--r--mysql-test/r/binary_to_hex.result117
-rw-r--r--mysql-test/r/count_distinct.result12
-rw-r--r--mysql-test/r/derived_view.result59
-rw-r--r--mysql-test/r/group_by.result27
-rw-r--r--mysql-test/r/join_outer.result95
-rw-r--r--mysql-test/r/join_outer_jcl6.result95
-rw-r--r--mysql-test/r/limit_rows_examined.result5
-rw-r--r--mysql-test/r/loadxml.result16
-rw-r--r--mysql-test/r/mysql.result58
-rw-r--r--mysql-test/r/mysqltest.result5
-rw-r--r--mysql-test/r/read_only.result2
-rw-r--r--mysql-test/r/subselect.result30
-rw-r--r--mysql-test/r/subselect_mat.result88
-rw-r--r--mysql-test/r/subselect_mat_cost_bugs.result102
-rw-r--r--mysql-test/r/subselect_no_mat.result30
-rw-r--r--mysql-test/r/subselect_no_opts.result30
-rw-r--r--mysql-test/r/subselect_no_scache.result30
-rw-r--r--mysql-test/r/subselect_no_semijoin.result30
-rw-r--r--mysql-test/r/subselect_nulls.result6
-rw-r--r--mysql-test/r/subselect_sj.result95
-rw-r--r--mysql-test/r/subselect_sj2_mat.result45
-rw-r--r--mysql-test/r/subselect_sj_jcl6.result95
-rw-r--r--mysql-test/r/subselect_sj_mat.result88
-rw-r--r--mysql-test/r/union.result18
-rw-r--r--mysql-test/r/view.result14
-rw-r--r--mysql-test/std_data/loadxml.dat8
-rw-r--r--mysql-test/suite/parts/r/longname.result33
-rw-r--r--mysql-test/suite/parts/r/quoting.result6
-rw-r--r--mysql-test/suite/parts/t/longname.test29
-rw-r--r--mysql-test/suite/parts/t/quoting.test10
-rw-r--r--mysql-test/suite/perfschema/include/have_timer_cycle.inc4
-rw-r--r--mysql-test/suite/perfschema/r/privilege.result8
-rw-r--r--mysql-test/suite/perfschema/t/dml_performance_timers.test1
-rw-r--r--mysql-test/suite/perfschema/t/dml_setup_timers.test1
-rw-r--r--mysql-test/suite/perfschema/t/privilege.test14
-rw-r--r--mysql-test/suite/rpl/r/rpl_mdev-11092.result17
-rw-r--r--mysql-test/suite/rpl/r/rpl_reset_slave_fail.result29
-rw-r--r--mysql-test/suite/rpl/t/rpl_mdev-11092.opt1
-rw-r--r--mysql-test/suite/rpl/t/rpl_mdev-11092.test53
-rw-r--r--mysql-test/suite/rpl/t/rpl_reset_slave_fail.test91
-rw-r--r--mysql-test/t/binary_to_hex.test76
-rw-r--r--mysql-test/t/bootstrap.test6
-rw-r--r--mysql-test/t/count_distinct.test16
-rw-r--r--mysql-test/t/derived_view.test50
-rw-r--r--mysql-test/t/group_by.test38
-rw-r--r--mysql-test/t/join_outer.test82
-rw-r--r--mysql-test/t/mysql.test30
-rw-r--r--mysql-test/t/mysqltest.test8
-rw-r--r--mysql-test/t/read_only.test3
-rw-r--r--mysql-test/t/subselect.test35
-rw-r--r--mysql-test/t/subselect_mat_cost_bugs.test99
-rw-r--r--mysql-test/t/subselect_nulls.test6
-rw-r--r--mysql-test/t/subselect_sj.test72
-rw-r--r--mysql-test/t/subselect_sj2_mat.test40
-rw-r--r--mysql-test/t/subselect_sj_mat.test207
-rw-r--r--mysql-test/t/union.test15
-rw-r--r--mysql-test/t/view.test16
-rw-r--r--mysys/my_fopen.c2
-rw-r--r--mysys/my_rdtsc.c25
-rw-r--r--mysys/my_symlink.c2
-rw-r--r--mysys/mysys_priv.h11
-rw-r--r--mysys/stacktrace.c2
-rw-r--r--plugin/semisync/semisync_master.cc6
-rw-r--r--scripts/CMakeLists.txt11
-rw-r--r--[-rwxr-xr-x]scripts/dheadgen.pl8
-rw-r--r--scripts/mysql_config.pl.in4
-rw-r--r--scripts/mysql_convert_table_format.sh5
-rw-r--r--scripts/mysql_find_rows.sh5
-rw-r--r--scripts/mysql_fix_extensions.sh5
-rw-r--r--scripts/mysql_install_db.pl.in4
-rw-r--r--scripts/mysql_secure_installation.pl.in7
-rw-r--r--scripts/mysql_setpermission.sh5
-rw-r--r--scripts/mysql_zap.sh5
-rw-r--r--scripts/mysqlaccess.sh19
-rw-r--r--scripts/mysqld_multi.sh22
-rw-r--r--scripts/mysqldumpslow.sh5
-rw-r--r--scripts/mysqlhotcopy.sh4
-rw-r--r--sql/ha_partition.cc195
-rw-r--r--sql/item.cc12
-rw-r--r--sql/item_func.h29
-rw-r--r--sql/item_subselect.cc29
-rw-r--r--sql/item_subselect.h10
-rw-r--r--sql/item_sum.h1
-rw-r--r--sql/item_timefunc.cc2
-rw-r--r--sql/log.cc7
-rw-r--r--sql/net_serv.cc2
-rw-r--r--sql/opt_subselect.cc114
-rw-r--r--sql/opt_sum.cc9
-rw-r--r--sql/records.cc1
-rw-r--r--sql/rpl_handler.cc2
-rw-r--r--sql/rpl_mi.cc11
-rw-r--r--sql/rpl_rli.cc52
-rw-r--r--sql/rpl_rli.h12
-rw-r--r--sql/slave.cc6
-rw-r--r--sql/sql_class.cc4
-rw-r--r--sql/sql_derived.cc4
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_lex.h5
-rw-r--r--sql/sql_load.cc2
-rw-r--r--sql/sql_parse.cc31
-rw-r--r--sql/sql_partition.cc158
-rw-r--r--sql/sql_partition.h12
-rw-r--r--sql/sql_plugin.cc20
-rw-r--r--sql/sql_priv.h2
-rw-r--r--sql/sql_repl.cc5
-rw-r--r--sql/sql_select.cc107
-rw-r--r--sql/sql_select.h8
-rw-r--r--sql/sql_union.cc18
-rw-r--r--sql/sys_vars.cc4
-rw-r--r--sql/threadpool_unix.cc14
-rw-r--r--sql/uniques.cc14
-rw-r--r--storage/archive/ha_archive.cc1
-rw-r--r--storage/innobase/buf/buf0buf.c6
-rw-r--r--storage/maria/ma_check.c4
-rw-r--r--storage/maria/ma_loghandler.c29
-rw-r--r--storage/maria/ma_pagecache.c1
-rw-r--r--storage/maria/ma_recovery.c4
-rw-r--r--storage/myisam/mi_check.c4
-rw-r--r--storage/myisam/mysql-test/storage_engine/parts/disabled.def0
-rw-r--r--storage/xtradb/btr/btr0btr.c2
-rw-r--r--storage/xtradb/buf/buf0buf.c6
-rw-r--r--storage/xtradb/dict/dict0crea.c4
-rw-r--r--storage/xtradb/fsp/fsp0fsp.c7
-rw-r--r--storage/xtradb/handler/i_s.cc24
-rw-r--r--storage/xtradb/include/btr0cur.h13
-rw-r--r--storage/xtradb/include/btr0sea.h7
-rw-r--r--storage/xtradb/include/buf0buddy.ic2
-rw-r--r--storage/xtradb/include/buf0buf.h3
-rw-r--r--storage/xtradb/include/dict0dict.h16
-rw-r--r--storage/xtradb/include/dyn0dyn.h18
-rw-r--r--storage/xtradb/include/dyn0dyn.ic2
-rw-r--r--storage/xtradb/include/log0online.h20
-rw-r--r--storage/xtradb/include/mach0data.h16
-rw-r--r--storage/xtradb/include/mtr0mtr.h5
-rw-r--r--storage/xtradb/include/os0file.h5
-rw-r--r--storage/xtradb/include/page0page.h18
-rw-r--r--storage/xtradb/include/page0zip.h5
-rw-r--r--storage/xtradb/include/rem0rec.h3
-rw-r--r--storage/xtradb/include/row0upd.h5
-rw-r--r--storage/xtradb/include/trx0trx.h4
-rw-r--r--storage/xtradb/include/univ.i4
-rw-r--r--storage/xtradb/log/log0online.c148
-rw-r--r--storage/xtradb/mach/mach0data.c44
-rw-r--r--storage/xtradb/os/os0file.c49
-rw-r--r--storage/xtradb/rem/rem0rec.c2
-rw-r--r--storage/xtradb/row/row0merge.c4
-rw-r--r--storage/xtradb/row/row0purge.c2
-rw-r--r--storage/xtradb/srv/srv0srv.c9
-rw-r--r--storage/xtradb/srv/srv0start.c2
-rw-r--r--storage/xtradb/trx/trx0roll.c4
160 files changed, 3408 insertions, 616 deletions
diff --git a/client/mysql.cc b/client/mysql.cc
index 57cb0a918a7..9c76e30d96f 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -149,7 +149,7 @@ static my_bool ignore_errors=0,wait_flag=0,quick=0,
default_pager_set= 0, opt_sigint_ignore= 0,
auto_vertical_output= 0,
show_warnings= 0, executing_query= 0,
- ignore_spaces= 0, opt_progress_reports;
+ ignore_spaces= 0, opt_binhex= 0, opt_progress_reports;
static my_bool debug_info_flag, debug_check_flag, batch_abort_on_error;
static my_bool column_types_flag;
static my_bool preserve_comments= 0;
@@ -1460,6 +1460,8 @@ static struct my_option my_long_options[] =
{"batch", 'B',
"Don't use history file. Disable interactive behavior. (Enables --silent.)",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"binary-as-hex", 'b', "Print binary data as hex", &opt_binhex, &opt_binhex,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory for character set files.", &charsets_dir,
&charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -2287,8 +2289,10 @@ static bool add_line(String &buffer, char *line, ulong line_length,
continue;
}
#endif
- if (!*ml_comment && inchar == '\\' &&
- !(*in_string &&
+ if (!*ml_comment && inchar == '\\' && *in_string != '`' &&
+ !(*in_string == '"' &&
+ (mysql.server_status & SERVER_STATUS_ANSI_QUOTES)) &&
+ !(*in_string &&
(mysql.server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)))
{
// Found possbile one character command like \c
@@ -2850,7 +2854,7 @@ You can turn off this feature to get a quicker startup with -A\n\n");
mysql_free_result(fields);
break;
}
- field_names[i][num_fields*2]= '\0';
+ field_names[i][num_fields*2]= NULL;
j=0;
while ((sql_field=mysql_fetch_field(fields)))
{
@@ -3283,7 +3287,8 @@ com_go(String *buffer,char *line __attribute__((unused)))
print_table_data_html(result);
else if (opt_xml)
print_table_data_xml(result);
- else if (vertical || (auto_vertical_output && (terminal_width < get_result_width(result))))
+ else if (vertical || (auto_vertical_output &&
+ (terminal_width < get_result_width(result))))
print_table_data_vertically(result);
else if (opt_silent && verbose <= 2 && !output_tables)
print_tab_data(result);
@@ -3502,6 +3507,41 @@ print_field_types(MYSQL_RES *result)
}
+/* Used to determine if we should invoke print_as_hex for this field */
+
+static bool
+is_binary_field(MYSQL_FIELD *field)
+{
+ if ((field->charsetnr == 63) &&
+ (field->type == MYSQL_TYPE_BIT ||
+ field->type == MYSQL_TYPE_BLOB ||
+ field->type == MYSQL_TYPE_LONG_BLOB ||
+ field->type == MYSQL_TYPE_MEDIUM_BLOB ||
+ field->type == MYSQL_TYPE_TINY_BLOB ||
+ field->type == MYSQL_TYPE_VAR_STRING ||
+ field->type == MYSQL_TYPE_STRING ||
+ field->type == MYSQL_TYPE_VARCHAR ||
+ field->type == MYSQL_TYPE_GEOMETRY))
+ return 1;
+ return 0;
+}
+
+
+/* Print binary value as hex literal (0x ...) */
+
+static void
+print_as_hex(FILE *output_file, const char *str, ulong len, ulong total_bytes_to_send)
+{
+ const char *ptr= str, *end= ptr+len;
+ ulong i;
+ fprintf(output_file, "0x");
+ for(; ptr < end; ptr++)
+ fprintf(output_file, "%02X", *((uchar*)ptr));
+ for (i= 2*len+2; i < total_bytes_to_send; i++)
+ tee_putc((int)' ', output_file);
+}
+
+
static void
print_table_data(MYSQL_RES *result)
{
@@ -3528,6 +3568,8 @@ print_table_data(MYSQL_RES *result)
length=max(length,field->max_length);
if (length < 4 && !IS_NOT_NULL(field->flags))
length=4; // Room for "NULL"
+ if (opt_binhex && is_binary_field(field))
+ length= 2 + length * 2;
field->max_length=length;
num_flag[mysql_field_tell(result) - 1]= IS_NUM(field->type);
separator.fill(separator.length()+length+2,'-');
@@ -3595,9 +3637,11 @@ print_table_data(MYSQL_RES *result)
many extra padding-characters we should send with the printing function.
*/
visible_length= charset_info->cset->numcells(charset_info, buffer, buffer + data_length);
- extra_padding= data_length - visible_length;
+ extra_padding= (uint) (data_length - visible_length);
- if (field_max_length > MAX_COLUMN_LENGTH)
+ if (opt_binhex && is_binary_field(field))
+ print_as_hex(PAGER, cur[off], lengths[off], field_max_length);
+ else if (field_max_length > MAX_COLUMN_LENGTH)
tee_print_sized_data(buffer, data_length, MAX_COLUMN_LENGTH+extra_padding, FALSE);
else
{
@@ -3730,11 +3774,15 @@ print_table_data_html(MYSQL_RES *result)
if (interrupted_query)
break;
ulong *lengths=mysql_fetch_lengths(result);
+ field= mysql_fetch_fields(result);
(void) tee_fputs("<TR>", PAGER);
for (uint i=0; i < mysql_num_fields(result); i++)
{
(void) tee_fputs("<TD>", PAGER);
- xmlencode_print(cur[i], lengths[i]);
+ if (opt_binhex && is_binary_field(&field[i]))
+ print_as_hex(PAGER, cur[i], lengths[i], lengths[i]);
+ else
+ xmlencode_print(cur[i], lengths[i]);
(void) tee_fputs("</TD>", PAGER);
}
(void) tee_fputs("</TR>", PAGER);
@@ -3770,7 +3818,10 @@ print_table_data_xml(MYSQL_RES *result)
if (cur[i])
{
tee_fprintf(PAGER, "\">");
- xmlencode_print(cur[i], lengths[i]);
+ if (opt_binhex && is_binary_field(&fields[i]))
+ print_as_hex(PAGER, cur[i], lengths[i], lengths[i]);
+ else
+ xmlencode_print(cur[i], lengths[i]);
tee_fprintf(PAGER, "</field>\n");
}
else
@@ -3817,23 +3868,28 @@ print_table_data_vertically(MYSQL_RES *result)
{
unsigned int i;
const char *p;
-
+ if (opt_binhex && is_binary_field(field))
+ fprintf(PAGER, "0x");
for (i= 0, p= cur[off]; i < lengths[off]; i+= 1, p+= 1)
{
- if (*p == '\0')
- tee_putc((int)' ', PAGER);
+ if (opt_binhex && is_binary_field(field))
+ fprintf(PAGER, "%02X", *((uchar*)p));
else
- tee_putc((int)*p, PAGER);
+ {
+ if (*p == '\0')
+ tee_putc((int)' ', PAGER);
+ else
+ tee_putc((int)*p, PAGER);
+ }
}
tee_putc('\n', PAGER);
}
- else
+ else
tee_fprintf(PAGER, "NULL\n");
}
}
}
-
/* print_warnings should be called right after executing a statement */
static void print_warnings()
@@ -3970,11 +4026,19 @@ print_tab_data(MYSQL_RES *result)
while ((cur = mysql_fetch_row(result)))
{
lengths=mysql_fetch_lengths(result);
- safe_put_field(cur[0],lengths[0]);
+ field= mysql_fetch_fields(result);
+ if (opt_binhex && is_binary_field(&field[0]))
+ print_as_hex(PAGER, cur[0], lengths[0], lengths[0]);
+ else
+ safe_put_field(cur[0],lengths[0]);
+
for (uint off=1 ; off < mysql_num_fields(result); off++)
{
(void) tee_fputs("\t", PAGER);
- safe_put_field(cur[off], lengths[off]);
+ if (opt_binhex && field && is_binary_field(&field[off]))
+ print_as_hex(PAGER, cur[off], lengths[off], lengths[off]);
+ else
+ safe_put_field(cur[off], lengths[off]);
}
(void) tee_fputs("\n", PAGER);
}
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index b22959677d0..98e35136b2a 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -1698,12 +1698,22 @@ int cat_file(DYNAMIC_STRING* ds, const char* filename)
{
int fd;
size_t len;
- char buff[16384];
+ char *buff;
if ((fd= my_open(filename, O_RDONLY, MYF(0))) < 0)
return 1;
- while((len= my_read(fd, (uchar*)&buff,
- sizeof(buff)-1, MYF(0))) > 0)
+
+ len= (size_t) my_seek(fd, 0, SEEK_END, MYF(0));
+ my_seek(fd, 0, SEEK_SET, MYF(0));
+ if (len == (size_t)MY_FILEPOS_ERROR ||
+ !(buff= (char*)my_malloc(len + 1, MYF(0))))
+ {
+ my_close(fd, MYF(0));
+ return 1;
+ }
+ len= my_read(fd, (uchar*)buff, len, MYF(0));
+ my_close(fd, MYF(0));
+
{
char *p= buff, *start= buff,*end=buff+len;
while (p < end)
@@ -1726,7 +1736,7 @@ int cat_file(DYNAMIC_STRING* ds, const char* filename)
*p= 0;
replace_dynstr_append_mem(ds, start, p-start);
}
- my_close(fd, MYF(0));
+ my_free(buff);
return 0;
}
@@ -6476,6 +6486,16 @@ my_bool end_of_query(int c)
}
+static inline bool is_escape_char(char c, char in_string)
+{
+ if (c != '\\' || in_string == '`') return false;
+ if (!cur_con) return true;
+ uint server_status= cur_con->mysql->server_status;
+ if (server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES) return false;
+ return !(server_status & SERVER_STATUS_ANSI_QUOTES && in_string == '"');
+}
+
+
/*
Read one "line" from the file
@@ -6502,7 +6522,7 @@ my_bool end_of_query(int c)
int read_line(char *buf, int size)
{
- char c, UNINIT_VAR(last_quote), last_char= 0;
+ char c, last_quote=0, last_char= 0;
char *p= buf, *buf_end= buf + size - 1;
int skip_char= 0;
my_bool have_slash= FALSE;
@@ -6584,7 +6604,7 @@ int read_line(char *buf, int size)
state= R_Q;
}
}
- have_slash= (c == '\\');
+ have_slash= is_escape_char(c, last_quote);
break;
case R_COMMENT:
@@ -6654,7 +6674,7 @@ int read_line(char *buf, int size)
case R_Q:
if (c == last_quote)
state= R_NORMAL;
- else if (c == '\\')
+ else if (is_escape_char(c, last_quote))
state= R_SLASH_IN_Q;
break;
diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake
index 519b3db7594..c6f62b3b8d4 100644
--- a/cmake/cpack_rpm.cmake
+++ b/cmake/cpack_rpm.cmake
@@ -25,7 +25,12 @@ SET(CPACK_COMPONENT_COMPAT_GROUP "compat")
SET(CPACK_COMPONENTS_ALL Server ManPagesServer IniFiles Server_Scripts
SupportFiles Readme Test)
SET(CPACK_RPM_PACKAGE_NAME "MariaDB-Galera")
-SET(CPACK_PACKAGE_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${VERSION}-${RPM}-${CMAKE_SYSTEM_PROCESSOR}")
+IF(CMAKE_VERSION VERSION_LESS "3.6.0")
+ SET(CPACK_PACKAGE_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${VERSION}-${RPM}-${CMAKE_SYSTEM_PROCESSOR}")
+ELSE()
+ SET(CPACK_RPM_FILE_NAME "RPM-DEFAULT")
+ SET(CPACK_RPM_DEBUGINFO_PACKAGE ON)
+ENDIF()
SET(CPACK_RPM_PACKAGE_RELEASE "1%{?dist}")
SET(CPACK_RPM_PACKAGE_LICENSE "GPLv2")
diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake
index 43665d04a88..6f7bd92c777 100644
--- a/cmake/ssl.cmake
+++ b/cmake/ssl.cmake
@@ -1,4 +1,5 @@
-# Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2012, Oracle and/or its affiliates.
+# Copyright (c) 2011, 2017, MariaDB Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -11,7 +12,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
MACRO (CHANGE_SSL_SETTINGS string)
SET(WITH_SSL ${string} CACHE STRING "Options are: no bundled yes(prefer os library if present otherwise use bundled) system(use os library)" FORCE)
@@ -87,7 +88,7 @@ MACRO (MYSQL_CHECK_SSL)
CHANGE_SSL_SETTINGS("system")
ELSE()
IF(WITH_SSL STREQUAL "system")
- MESSAGE(SEND_ERROR "Cannot find appropriate system libraries for SSL. Use WITH_SSL=bundled to enable SSL support")
+ MESSAGE(SEND_ERROR "Cannot find appropriate system libraries for SSL. Use WITH_SSL=bundled to enable SSL support")
ENDIF()
MYSQL_USE_BUNDLED_SSL()
ENDIF()
diff --git a/debian/compat b/debian/compat
index 7ed6ff82de6..ec635144f60 100644
--- a/debian/compat
+++ b/debian/compat
@@ -1 +1 @@
-5
+9
diff --git a/include/my_global.h b/include/my_global.h
index 0c15478439f..cf140cf54ce 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -1,5 +1,6 @@
/*
Copyright (c) 2001, 2013, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2017, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -421,9 +422,8 @@ extern "C" int madvise(void *addr, size_t len, int behav);
#define SIGNAL_HANDLER_RESET_ON_DELIVERY
#endif
-#ifndef STDERR_FILENO
-#define STDERR_FILENO fileno(stderr)
-#endif
+/* don't assume that STDERR_FILENO is 2, mysqld can freopen */
+#undef STDERR_FILENO
/*
Deprecated workaround for false-positive uninitialized variables
diff --git a/include/my_sys.h b/include/my_sys.h
index 27940683dad..cd74fdf427b 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2010, 2016, Monty Program Ab.
+ Copyright (c) 2010, 2017, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 0d57b178937..df9681e02a4 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -296,6 +296,8 @@ enum enum_server_command
*/
#define SERVER_PS_OUT_PARAMS 4096
+#define SERVER_STATUS_ANSI_QUOTES 32768
+
/**
Server status flags that must be cleared when starting
execution of a new SQL statement.
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 1df5f0b6d2c..1a736ee7800 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates
- Copyright (c) 2009, 2014, Monty Program Ab
+ Copyright (c) 2009, 2017, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -4913,4 +4913,3 @@ ulong STDCALL mysql_net_field_length(uchar **packet)
{
return net_field_length(packet);
}
-
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 22ccb7447fc..197127b56ab 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -2,7 +2,7 @@
# -*- cperl -*-
# Copyright (c) 2004, 2014, Oracle and/or its affiliates.
-# Copyright (c) 2009, 2014, Monty Program Ab
+# Copyright (c) 2009, 2017, MariaDB Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -6194,7 +6194,8 @@ sub valgrind_arguments {
mtr_add_arg($args, "--num-callers=16");
mtr_add_arg($args, "--suppressions=%s/valgrind.supp", $glob_mysql_test_dir)
if -f "$glob_mysql_test_dir/valgrind.supp";
- my $temp= `ldd $ENV{MTR_BINDIR}/sql/mysqld | grep 'libjemalloc'`;
+ my $exe_mysqld= find_mysqld($bindir) || "";
+ my $temp= `ldd $exe_mysqld | grep 'libjemalloc'`;
if ($temp)
{
mtr_add_arg($args, "--soname-synonyms=somalloc=libjemalloc*");
diff --git a/mysql-test/r/binary_to_hex.result b/mysql-test/r/binary_to_hex.result
new file mode 100644
index 00000000000..a6b68834da8
--- /dev/null
+++ b/mysql-test/r/binary_to_hex.result
@@ -0,0 +1,117 @@
+USE test;
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (c1 TINYBLOB,
+c2 BLOB,
+c3 MEDIUMBLOB,
+c4 LONGBLOB,
+c5 TEXT,
+c6 BIT(1),
+c7 CHAR,
+c8 VARCHAR(10),
+c9 GEOMETRY) CHARACTER SET = binary;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` tinyblob,
+ `c2` blob,
+ `c3` mediumblob,
+ `c4` longblob,
+ `c5` blob,
+ `c6` bit(1) DEFAULT NULL,
+ `c7` binary(1) DEFAULT NULL,
+ `c8` varbinary(10) DEFAULT NULL,
+ `c9` geometry DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=binary
+INSERT INTO t1 VALUES ('tinyblob-text readable', 'blob-text readable',
+'mediumblob-text readable', 'longblob-text readable',
+'text readable', b'1', 'c', 'variable',
+POINT(1, 1));
+CREATE TABLE t2(id int, `col1` binary(10),`col2` blob);
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) DEFAULT NULL,
+ `col1` binary(10) DEFAULT NULL,
+ `col2` blob
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t2 VALUES (1, X'AB1234', X'123ABC'), (2, X'DE1234', X'123DEF');
+#Print the table contents when binary-as-hex option is off.
+SELECT * FROM t1;
+c1 c2 c3 c4 c5 c6 c7 c8 c9
+tinyblob-text readable blob-text readable mediumblob-text readable longblob-text readable text readable # c variable #
+SELECT * FROM t2;
+id col1 col2
+1 # #
+2 # #
+#Print the table contents after turning on the binary-as-hex option
+
+#Print the table contents in tab format
+
+c1 c2 c3 c4 c5 c6 c7 c8 c9
+0x74696E79626C6F622D74657874207265616461626C65 0x626C6F622D74657874207265616461626C65 0x6D656469756D626C6F622D74657874207265616461626C65 0x6C6F6E67626C6F622D74657874207265616461626C65 0x74657874207265616461626C65 0x01 0x63 0x7661726961626C65 0x000000000101000000000000000000F03F000000000000F03F
+id col1 col2
+1 0xAB123400000000000000 0x123ABC
+2 0xDE123400000000000000 0x123DEF
+
+#Print the table contents in table format
+
++------------------------------------------------+----------------------------------------+----------------------------------------------------+------------------------------------------------+------------------------------+------------+------------+--------------------+------------------------------------------------------+
+| c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 |
++------------------------------------------------+----------------------------------------+----------------------------------------------------+------------------------------------------------+------------------------------+------------+------------+--------------------+------------------------------------------------------+
+| 0x74696E79626C6F622D74657874207265616461626C65 | 0x626C6F622D74657874207265616461626C65 | 0x6D656469756D626C6F622D74657874207265616461626C65 | 0x6C6F6E67626C6F622D74657874207265616461626C65 | 0x74657874207265616461626C65 | 0x01 | 0x63 | 0x7661726961626C65 | 0x000000000101000000000000000000F03F000000000000F03F |
++------------------------------------------------+----------------------------------------+----------------------------------------------------+------------------------------------------------+------------------------------+------------+------------+--------------------+------------------------------------------------------+
++------+------------------------+------------+
+| id | col1 | col2 |
++------+------------------------+------------+
+| 1 | 0xAB123400000000000000 | 0x123ABC |
++------+------------------------+------------+
+
+#Print the table contents vertically
+
+*************************** 1. row ***************************
+c1: 0x74696E79626C6F622D74657874207265616461626C65
+c2: 0x626C6F622D74657874207265616461626C65
+c3: 0x6D656469756D626C6F622D74657874207265616461626C65
+c4: 0x6C6F6E67626C6F622D74657874207265616461626C65
+c5: 0x74657874207265616461626C65
+c6: 0x01
+c7: 0x63
+c8: 0x7661726961626C65
+c9: 0x000000000101000000000000000000F03F000000000000F03F
+
+#Print the table contents in xml format
+
+<?xml version="1.0"?>
+
+<resultset statement="SELECT * FROM t1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <row>
+ <field name="c1">0x74696E79626C6F622D74657874207265616461626C65</field>
+ <field name="c2">0x626C6F622D74657874207265616461626C65</field>
+ <field name="c3">0x6D656469756D626C6F622D74657874207265616461626C65</field>
+ <field name="c4">0x6C6F6E67626C6F622D74657874207265616461626C65</field>
+ <field name="c5">0x74657874207265616461626C65</field>
+ <field name="c6">0x01</field>
+ <field name="c7">0x63</field>
+ <field name="c8">0x7661726961626C65</field>
+ <field name="c9">0x000000000101000000000000000000F03F000000000000F03F</field>
+ </row>
+</resultset>
+<?xml version="1.0"?>
+
+<resultset statement="SELECT * FROM t2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <row>
+ <field name="id">1</field>
+ <field name="col1">0xAB123400000000000000</field>
+ <field name="col2">0x123ABC</field>
+ </row>
+
+ <row>
+ <field name="id">2</field>
+ <field name="col1">0xDE123400000000000000</field>
+ <field name="col2">0x123DEF</field>
+ </row>
+</resultset>
+
+#Print the table contents in html format
+
+<TABLE BORDER=1><TR><TH>c1</TH><TH>c2</TH><TH>c3</TH><TH>c4</TH><TH>c5</TH><TH>c6</TH><TH>c7</TH><TH>c8</TH><TH>c9</TH></TR><TR><TD>0x74696E79626C6F622D74657874207265616461626C65</TD><TD>0x626C6F622D74657874207265616461626C65</TD><TD>0x6D656469756D626C6F622D74657874207265616461626C65</TD><TD>0x6C6F6E67626C6F622D74657874207265616461626C65</TD><TD>0x74657874207265616461626C65</TD><TD>0x01</TD><TD>0x63</TD><TD>0x7661726961626C65</TD><TD>0x000000000101000000000000000000F03F000000000000F03F</TD></TR></TABLE><TABLE BORDER=1><TR><TH>id</TH><TH>col1</TH><TH>col2</TH></TR><TR><TD>1</TD><TD>0xAB123400000000000000</TD><TD>0x123ABC</TD></TR><TR><TD>2</TD><TD>0xDE123400000000000000</TD><TD>0x123DEF</TD></TR></TABLE>DROP TABLE t1, t2;
diff --git a/mysql-test/r/count_distinct.result b/mysql-test/r/count_distinct.result
index 3b65dd0e608..d55a232c715 100644
--- a/mysql-test/r/count_distinct.result
+++ b/mysql-test/r/count_distinct.result
@@ -94,3 +94,15 @@ count(distinct i)
2
drop table t1;
drop view v1;
+create table t1 (user_id char(64) character set utf8);
+insert t1 values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17);
+set @@tmp_table_size = 1024;
+select count(distinct user_id) from t1;
+count(distinct user_id)
+17
+alter table t1 modify user_id char(128) character set utf8;
+select count(distinct user_id) from t1;
+count(distinct user_id)
+17
+drop table t1;
+set @@tmp_table_size = default;
diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result
index d993086299e..f7062473a3f 100644
--- a/mysql-test/r/derived_view.result
+++ b/mysql-test/r/derived_view.result
@@ -2579,5 +2579,64 @@ Handler_read_rnd_deleted 0
Handler_read_rnd_next 27
deallocate prepare stmt1;
drop table t1,t2;
+#
+# Bug mdev-12670: mergeable derived / view with subqueries
+# subject to semi-join optimizations
+# (actually this is a 5.3 bug.)
+#
+create table t1 (a int) engine=myisam;
+insert into t1 values (5),(3),(2),(7),(2),(5),(1);
+create table t2 (b int, index idx(b)) engine=myisam;
+insert into t2 values (2),(3),(2),(1),(3),(4);
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+analyze table t1,t2;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+test.t2 analyze status OK
+explain select a from t1 where a in (select b from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
+1 PRIMARY t2 ref idx idx 5 test.t1.a 140 Using index; FirstMatch(t1)
+explain select * from (select a from t1 where a in (select b from t2)) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t2 ref idx idx 5 test.t1.a 140 Using index; FirstMatch(t1)
+create view v1 as select a from t1 where a in (select b from t2);
+explain select * from v1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where
+1 SIMPLE t2 ref idx idx 5 test.t1.a 140 Using index; FirstMatch(t1)
+drop view v1;
+drop table t1,t2;
+#
+# Bug mdev-12812: mergeable derived / view with subqueries
+# NOT subject to semi-join optimizations
+#
+CREATE TABLE t1 (c1 varchar(3)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('foo'),('foo');
+CREATE TABLE t2 (c2 varchar(3)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('bar'),('qux'),('foo');
+SELECT STRAIGHT_JOIN *
+FROM ( SELECT * FROM t1 WHERE c1 IN ( SELECT c2 FROM t2 ) ) AS sq;
+c1
+foo
+foo
+EXPLAIN EXTENDED SELECT STRAIGHT_JOIN *
+FROM ( SELECT * FROM t1 WHERE c1 IN ( SELECT c2 FROM t2 ) ) AS sq;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select straight_join `test`.`t1`.`c1` AS `c1` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`c1`,<exists>(select `test`.`t2`.`c2` from `test`.`t2` where (<cache>(`test`.`t1`.`c1`) = `test`.`t2`.`c2`)))
+DROP TABLE t1, t2;
set optimizer_switch=@exit_optimizer_switch;
set join_cache_level=@exit_join_cache_level;
diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result
index 262bb2ebd84..b948c9a6f88 100644
--- a/mysql-test/r/group_by.result
+++ b/mysql-test/r/group_by.result
@@ -2531,3 +2531,30 @@ select a from t1 group by a having a > 1;
a
drop table t1;
set sql_mode= @save_sql_mode;
+create table t1 (f1 int);
+insert into t1 values (5),(9);
+create table t2 (f2 int);
+insert into t2 values (0),(6);
+create table t3 (f3 int);
+insert into t3 values (6),(3);
+create table t4 (f4 int);
+insert into t4 values (1),(0);
+select
+(select min(f1) from t1 where f1 in (select min(f4) from t2)) as field7,
+(select count(*) from t3 where f3 in (select max(f4) from t2 group by field7))
+from t4;
+ERROR 42S22: Reference 'field7' not supported (reference to group function)
+drop table t1, t2, t3, t4;
+create table t1 (i1 int);
+insert into t1 values (1);
+create table t2 (i int);
+insert into t2 values (2);
+select 1 from t1 left join t2 b on b.i = (select max(b.i) from t2);
+1
+1
+drop table t1, t2;
+create table t1 (c1 int, c2 int);
+create table t2 (c1 int, c2 int);
+select t1.c1 as c1, t2.c2 as c1 from t1, t2 where t1.c1 < 20 and t2.c2 > 5 group by t1.c1, t2.c2 having t1.c1 < 3;
+c1 c1
+drop table t1, t2;
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index 5dbb0f1d8b6..5611b61a7b0 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -2245,4 +2245,99 @@ SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a
WHERE b IN (1,2,3) OR b = d;
a b c d
DROP TABLE t1,t2,t3;
+#
+# MDEV-11958: LEFT JOIN with stored routine produces incorrect result
+#
+CREATE TABLE t (x INT);
+INSERT INTO t VALUES(1),(NULL);
+CREATE FUNCTION f (val INT, ret INT) RETURNS INT DETERMINISTIC RETURN IFNULL(val, ret);
+SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
+FROM t t1 LEFT JOIN t t2
+ON t1.x = t2.x
+WHERE IFNULL(t2.x,0)=0;
+x x IFNULL(t2.x,0) f(t2.x,0)
+NULL NULL 0 0
+explain extended
+SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
+FROM t t1 LEFT JOIN t t2
+ON t1.x = t2.x
+WHERE IFNULL(t2.x,0)=0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t2`.`x` AS `x`,ifnull(`test`.`t2`.`x`,0) AS `IFNULL(t2.x,0)`,`f`(`test`.`t2`.`x`,0) AS `f(t2.x,0)` from `test`.`t` `t1` left join `test`.`t` `t2` on((`test`.`t2`.`x` = `test`.`t1`.`x`)) where (ifnull(`test`.`t2`.`x`,0) = 0)
+SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
+FROM t t1 LEFT JOIN t t2
+ON t1.x = t2.x
+WHERE f(t2.x,0)=0;
+x x IFNULL(t2.x,0) f(t2.x,0)
+NULL NULL 0 0
+explain extended
+SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
+FROM t t1 LEFT JOIN t t2
+ON t1.x = t2.x
+WHERE f(t2.x,0)=0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t2`.`x` AS `x`,ifnull(`test`.`t2`.`x`,0) AS `IFNULL(t2.x,0)`,`f`(`test`.`t2`.`x`,0) AS `f(t2.x,0)` from `test`.`t` `t1` left join `test`.`t` `t2` on((`test`.`t2`.`x` = `test`.`t1`.`x`)) where (`f`(`test`.`t2`.`x`,0) = 0)
+drop function f;
+drop table t;
+CREATE TABLE t1 (
+col1 DECIMAL(33,5) NULL DEFAULT NULL,
+col2 DECIMAL(33,5) NULL DEFAULT NULL
+);
+CREATE TABLE t2 (
+col1 DECIMAL(33,5) NULL DEFAULT NULL,
+col2 DECIMAL(33,5) NULL DEFAULT NULL,
+col3 DECIMAL(33,5) NULL DEFAULT NULL
+);
+INSERT INTO t1 VALUES (2, 1.1), (2, 2.1);
+INSERT INTO t2 VALUES (3, 3.1, 4), (1, 1, NULL);
+CREATE FUNCTION f1 ( p_num DECIMAL(45,15), p_return DECIMAL(45,15))
+RETURNS decimal(33,5)
+LANGUAGE SQL
+DETERMINISTIC
+CONTAINS SQL
+SQL SECURITY INVOKER
+BEGIN
+IF p_num IS NULL THEN
+RETURN p_return;
+ELSE
+RETURN p_num;
+END IF;
+END |
+SELECT t1.col1, t2.col1, t2.col3
+FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
+WHERE IFNULL(t2.col3,0) = 0;
+col1 col1 col3
+2.00000 NULL NULL
+2.00000 NULL NULL
+EXPLAIN EXTENDED SELECT t1.col1, t2.col1, t2.col3
+FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
+WHERE IFNULL(t2.col3,0) = 0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`col1` AS `col1`,`test`.`t2`.`col1` AS `col1`,`test`.`t2`.`col3` AS `col3` from `test`.`t1` left join `test`.`t2` on((`test`.`t2`.`col2` = `test`.`t1`.`col1`)) where (ifnull(`test`.`t2`.`col3`,0) = 0)
+SELECT t1.col1, t2.col1, t2.col3
+FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
+WHERE f1(t2.col3,0) = 0;
+col1 col1 col3
+2.00000 NULL NULL
+2.00000 NULL NULL
+EXPLAIN EXTENDED SELECT t1.col1, t2.col1, t2.col3
+FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
+WHERE f1(t2.col3,0) = 0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`col1` AS `col1`,`test`.`t2`.`col1` AS `col1`,`test`.`t2`.`col3` AS `col3` from `test`.`t1` left join `test`.`t2` on((`test`.`t2`.`col2` = `test`.`t1`.`col1`)) where (`f1`(`test`.`t2`.`col3`,0) = 0)
+DROP FUNCTION f1;
+DROP TABLE t1,t2;
+# end of 5.5 tests
SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result
index bdc4be0cb8c..8a1ccc7d5e5 100644
--- a/mysql-test/r/join_outer_jcl6.result
+++ b/mysql-test/r/join_outer_jcl6.result
@@ -2256,6 +2256,101 @@ SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a
WHERE b IN (1,2,3) OR b = d;
a b c d
DROP TABLE t1,t2,t3;
+#
+# MDEV-11958: LEFT JOIN with stored routine produces incorrect result
+#
+CREATE TABLE t (x INT);
+INSERT INTO t VALUES(1),(NULL);
+CREATE FUNCTION f (val INT, ret INT) RETURNS INT DETERMINISTIC RETURN IFNULL(val, ret);
+SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
+FROM t t1 LEFT JOIN t t2
+ON t1.x = t2.x
+WHERE IFNULL(t2.x,0)=0;
+x x IFNULL(t2.x,0) f(t2.x,0)
+NULL NULL 0 0
+explain extended
+SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
+FROM t t1 LEFT JOIN t t2
+ON t1.x = t2.x
+WHERE IFNULL(t2.x,0)=0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t2`.`x` AS `x`,ifnull(`test`.`t2`.`x`,0) AS `IFNULL(t2.x,0)`,`f`(`test`.`t2`.`x`,0) AS `f(t2.x,0)` from `test`.`t` `t1` left join `test`.`t` `t2` on((`test`.`t2`.`x` = `test`.`t1`.`x`)) where (ifnull(`test`.`t2`.`x`,0) = 0)
+SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
+FROM t t1 LEFT JOIN t t2
+ON t1.x = t2.x
+WHERE f(t2.x,0)=0;
+x x IFNULL(t2.x,0) f(t2.x,0)
+NULL NULL 0 0
+explain extended
+SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
+FROM t t1 LEFT JOIN t t2
+ON t1.x = t2.x
+WHERE f(t2.x,0)=0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t2`.`x` AS `x`,ifnull(`test`.`t2`.`x`,0) AS `IFNULL(t2.x,0)`,`f`(`test`.`t2`.`x`,0) AS `f(t2.x,0)` from `test`.`t` `t1` left join `test`.`t` `t2` on((`test`.`t2`.`x` = `test`.`t1`.`x`)) where (`f`(`test`.`t2`.`x`,0) = 0)
+drop function f;
+drop table t;
+CREATE TABLE t1 (
+col1 DECIMAL(33,5) NULL DEFAULT NULL,
+col2 DECIMAL(33,5) NULL DEFAULT NULL
+);
+CREATE TABLE t2 (
+col1 DECIMAL(33,5) NULL DEFAULT NULL,
+col2 DECIMAL(33,5) NULL DEFAULT NULL,
+col3 DECIMAL(33,5) NULL DEFAULT NULL
+);
+INSERT INTO t1 VALUES (2, 1.1), (2, 2.1);
+INSERT INTO t2 VALUES (3, 3.1, 4), (1, 1, NULL);
+CREATE FUNCTION f1 ( p_num DECIMAL(45,15), p_return DECIMAL(45,15))
+RETURNS decimal(33,5)
+LANGUAGE SQL
+DETERMINISTIC
+CONTAINS SQL
+SQL SECURITY INVOKER
+BEGIN
+IF p_num IS NULL THEN
+RETURN p_return;
+ELSE
+RETURN p_num;
+END IF;
+END |
+SELECT t1.col1, t2.col1, t2.col3
+FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
+WHERE IFNULL(t2.col3,0) = 0;
+col1 col1 col3
+2.00000 NULL NULL
+2.00000 NULL NULL
+EXPLAIN EXTENDED SELECT t1.col1, t2.col1, t2.col3
+FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
+WHERE IFNULL(t2.col3,0) = 0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col1` AS `col1`,`test`.`t2`.`col1` AS `col1`,`test`.`t2`.`col3` AS `col3` from `test`.`t1` left join `test`.`t2` on((`test`.`t2`.`col2` = `test`.`t1`.`col1`)) where (ifnull(`test`.`t2`.`col3`,0) = 0)
+SELECT t1.col1, t2.col1, t2.col3
+FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
+WHERE f1(t2.col3,0) = 0;
+col1 col1 col3
+2.00000 NULL NULL
+2.00000 NULL NULL
+EXPLAIN EXTENDED SELECT t1.col1, t2.col1, t2.col3
+FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
+WHERE f1(t2.col3,0) = 0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`col1` AS `col1`,`test`.`t2`.`col1` AS `col1`,`test`.`t2`.`col3` AS `col3` from `test`.`t1` left join `test`.`t2` on((`test`.`t2`.`col2` = `test`.`t1`.`col1`)) where (`f1`(`test`.`t2`.`col3`,0) = 0)
+DROP FUNCTION f1;
+DROP TABLE t1,t2;
+# end of 5.5 tests
SET optimizer_switch=@save_optimizer_switch;
set join_cache_level=default;
show variables like 'join_cache_level';
diff --git a/mysql-test/r/limit_rows_examined.result b/mysql-test/r/limit_rows_examined.result
index a51798a5883..4e13e04f961 100644
--- a/mysql-test/r/limit_rows_examined.result
+++ b/mysql-test/r/limit_rows_examined.result
@@ -426,7 +426,7 @@ c1
bb
cc
Warnings:
-Warning 1931 Query execution was interrupted. The query examined at least 18 rows, which exceeds LIMIT ROWS EXAMINED (16). The query result may be incomplete.
+Warning 1931 Query execution was interrupted. The query examined at least 17 rows, which exceeds LIMIT ROWS EXAMINED (16). The query result may be incomplete.
select * from v1 LIMIT ROWS EXAMINED 11;
c1
bb
@@ -439,7 +439,8 @@ from (select * from t1
where c1 IN (select * from t2 where c2 > ' ' LIMIT ROWS EXAMINED 0)) as tmp
LIMIT ROWS EXAMINED 11;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4
+1 SIMPLE <subquery3> eq_ref distinct_key distinct_key 2 func 1
3 MATERIALIZED t2 ALL NULL NULL NULL NULL 4 Using where
select *
from (select * from t1
diff --git a/mysql-test/r/loadxml.result b/mysql-test/r/loadxml.result
index 1128caf9122..250037f60b8 100644
--- a/mysql-test/r/loadxml.result
+++ b/mysql-test/r/loadxml.result
@@ -5,10 +5,10 @@ load xml infile '../../std_data/loadxml.dat' into table t1
rows identified by '<row>';
select * from t1 order by a;
a b
-1 b1
-2 b2
-3 b3
-11 b11
+1 b1
+2 b2
+3 b3
+11 b11
111 b111
112 b112 & < > " ' &unknown; -- check entities
212 b212
@@ -81,17 +81,17 @@ LOAD XML INFILE '../../std_data/loadxml.dat' INTO TABLE t1
ROWS IDENTIFIED BY '<row>' (a,@b) SET b=concat('!',@b);
SELECT * FROM t1 ORDER BY a;
a b
-1 !b1
-11 !b11
+1 ! b1
+11 ! b11
111 !b111
112 !b112 & < > " ' &unknown; -- check entities
-2 !b2
+2 ! b2
212 !b212
213 !b213
214 !b214
215 !b215
216 !&bb b;
-3 !b3
+3 ! b3
DROP TABLE t1;
#
# Bug#16171518 LOAD XML DOES NOT HANDLE EMPTY ELEMENTS
diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result
index dd0129df0d9..8a24128daa2 100644
--- a/mysql-test/r/mysql.result
+++ b/mysql-test/r/mysql.result
@@ -529,3 +529,61 @@ a
+-------------------+
End of tests
+create table `a1\``b1` (a int);
+show tables;
+Tables_in_test
+a1\`b1
+insert `a1\``b1` values (1),(2);
+show create table `a1\``b1`;
+Table Create Table
+a1\`b1 CREATE TABLE `a1\``b1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `a1\``b1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO `a1\``b1` VALUES (1),(2);
+insert `a1\``b1` values (4),(5);
+show create table `a1\``b1`;
+Table Create Table
+a1\`b1 CREATE TABLE `a1\``b1` (
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from `a1\``b1`;
+a
+1
+2
+drop table `a1\``b1`;
+set sql_mode=ansi_quotes;
+create table "a1\""b1" (a int);
+show tables;
+Tables_in_test
+a1\"b1
+insert "a1\""b1" values (1),(2);
+show create table "a1\""b1";
+Table Create Table
+a1\"b1 CREATE TABLE "a1\""b1" (
+ "a" int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE "a1\""b1" (
+ "a" int(11) DEFAULT NULL
+);
+/*!40101 SET character_set_client = @saved_cs_client */;
+INSERT INTO "a1\""b1" VALUES (1),(2);
+insert "a1\""b1" values (4),(5);
+show create table "a1\""b1";
+Table Create Table
+a1\"b1 CREATE TABLE "a1\""b1" (
+ "a" int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from "a1\""b1";
+a
+1
+2
+drop table "a1\""b1";
+set sql_mode=default;
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index 0ebef585974..9800aed6368 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -957,4 +957,9 @@ con1
con2
con2
-closed_connection-
+set sql_mode=no_backslash_escapes;
+select "foo\""bar";
+foo\"bar
+foo\"bar
+set sql_mode=default;
End of tests
diff --git a/mysql-test/r/read_only.result b/mysql-test/r/read_only.result
index 1ffe2b86f70..807dc426696 100644
--- a/mysql-test/r/read_only.result
+++ b/mysql-test/r/read_only.result
@@ -30,6 +30,8 @@ create temporary table t3 (a int);
create temporary table t4 (a int) select * from t3;
insert into t3 values(1);
insert into t4 select * from t3;
+create table t3 (a int);
+ERROR HY000: The MariaDB server is running with the --read-only option so it cannot execute this statement
update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a;
ERROR HY000: The MariaDB server is running with the --read-only option so it cannot execute this statement
update t1,t3 set t3.a=t1.a+1 where t1.a=t3.a;
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 789cfe2fdca..8fc9cd38728 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -7116,3 +7116,33 @@ SELECT * FROM t1 WHERE f2 <= SOME ( SELECT f1 FROM t1 );
f1 f2
foo bar
DROP TABLE t1;
+#
+# MDEV-10146: Wrong result (or questionable result and behavior)
+# with aggregate function in uncorrelated SELECT subquery
+#
+CREATE TABLE t1 (f1 INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (f2 int);
+INSERT INTO t2 VALUES (3);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+( SELECT MAX(f1) FROM t2 )
+2
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+( SELECT MAX(f1) FROM t2 )
+2
+INSERT INTO t2 VALUES (4);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+drop view v1;
+drop table t1,t2;
+CREATE TABLE t1 (f1 INT, KEY(f1)) ENGINE=MyISAM;
+INSERT t1 VALUES (4),(8);
+CREATE TABLE t2 (f2 INT, KEY(f2)) ENGINE=MyISAM;
+INSERT t2 VALUES (6),(9);
+SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
+(SELECT MAX(sq.f2) FROM t1)
+NULL
+drop table t1, t2;
diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result
index ffa37b025eb..d4dc519227b 100644
--- a/mysql-test/r/subselect_mat.result
+++ b/mysql-test/r/subselect_mat.result
@@ -2272,6 +2272,94 @@ pk f1 sq
5 3 5
set optimizer_switch= @save_optimizer_switch;
DROP TABLE t1,t2;
+#
+# mdev-12838: scan of materialized of semi-join subquery in join
+#
+set @save_optimizer_switch=@@optimizer_switch;
+CREATE TABLE t1 (
+dispatch_group varchar(32),
+assignment_group varchar(32),
+sys_id char(32),
+PRIMARY KEY (sys_id),
+KEY idx1 (dispatch_group),
+KEY idx2 (assignment_group)
+) ENGINE=MyISAM;
+CREATE TABLE t2 (
+ugroup varchar(32),
+user varchar(32),
+sys_id char(32),
+PRIMARY KEY (sys_id),
+KEY idx3 (ugroup),
+KEY idx4 (user)
+) ENGINE=MyISAM;
+CREATE TABLE t3 (
+type mediumtext,
+sys_id char(32),
+PRIMARY KEY (sys_id)
+) ENGINE=MyISAM;
+set optimizer_switch='materialization=off';
+explain SELECT t1.assignment_group
+FROM t1, t3
+WHERE t1.assignment_group = t3.sys_id AND
+t1.dispatch_group IN
+(SELECT t2.ugroup
+FROM t2, t3 t3_i
+WHERE t2.ugroup = t3_i.sys_id AND
+t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
+t2.user = '86826bf03710200044e0bfc8bcbe5d79');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where; Start temporary
+1 PRIMARY t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where
+1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t3_i.sys_id 2 Using index condition; Using where; End temporary
+1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index
+SELECT t1.assignment_group
+FROM t1, t3
+WHERE t1.assignment_group = t3.sys_id AND
+t1.dispatch_group IN
+(SELECT t2.ugroup
+FROM t2, t3 t3_i
+WHERE t2.ugroup = t3_i.sys_id AND
+t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
+t2.user = '86826bf03710200044e0bfc8bcbe5d79');
+assignment_group
+df50316637232000158bbfc8bcbe5d23
+e08fad2637232000158bbfc8bcbe5d39
+ec70316637232000158bbfc8bcbe5d60
+7b10fd2637232000158bbfc8bcbe5d30
+ebb4620037332000158bbfc8bcbe5d89
+set optimizer_switch='materialization=on';
+explain SELECT t1.assignment_group
+FROM t1, t3
+WHERE t1.assignment_group = t3.sys_id AND
+t1.dispatch_group IN
+(SELECT t2.ugroup
+FROM t2, t3 t3_i
+WHERE t2.ugroup = t3_i.sys_id AND
+t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
+t2.user = '86826bf03710200044e0bfc8bcbe5d79');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
+1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t2.ugroup 2 Using where
+1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index
+2 MATERIALIZED t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where
+2 MATERIALIZED t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where
+SELECT t1.assignment_group
+FROM t1, t3
+WHERE t1.assignment_group = t3.sys_id AND
+t1.dispatch_group IN
+(SELECT t2.ugroup
+FROM t2, t3 t3_i
+WHERE t2.ugroup = t3_i.sys_id AND
+t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
+t2.user = '86826bf03710200044e0bfc8bcbe5d79');
+assignment_group
+df50316637232000158bbfc8bcbe5d23
+e08fad2637232000158bbfc8bcbe5d39
+ec70316637232000158bbfc8bcbe5d60
+7b10fd2637232000158bbfc8bcbe5d30
+ebb4620037332000158bbfc8bcbe5d89
+DROP TABLE t1,t2,t3;
+set optimizer_switch=@save_optimizer_switch;
# End of 5.5 tests
set @subselect_mat_test_optimizer_switch_value=null;
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
diff --git a/mysql-test/r/subselect_mat_cost_bugs.result b/mysql-test/r/subselect_mat_cost_bugs.result
index 24640154c59..57b0526c6a3 100644
--- a/mysql-test/r/subselect_mat_cost_bugs.result
+++ b/mysql-test/r/subselect_mat_cost_bugs.result
@@ -379,6 +379,7 @@ drop table t3, t4, t5;
#
# LP BUG#858038 The result of a query with NOT IN subquery depends on the state of the optimizer switch
#
+set @optimizer_switch_save= @@optimizer_switch;
create table t1 (c1 char(2) not null, c2 char(2));
create table t2 (c3 char(2), c4 char(2));
insert into t1 values ('a1', 'b1');
@@ -400,3 +401,104 @@ id select_type table type possible_keys key key_len ref rows Extra
select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
c1 c2
drop table t1, t2;
+set optimizer_switch= @optimizer_switch_save;
+#
+# MDEV-12673: cost-based choice between materialization and in-to-exists
+#
+CREATE TABLE t1 (
+pk1 int, a1 varchar(3), b1 varchar(3), PRIMARY KEY (pk1), KEY(a1), KEY(b1)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,'foo','bar'),(2,'bar','foo');
+CREATE TABLE t2 (pk2 INT PRIMARY KEY, a2 VARCHAR(3), KEY(a2)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,'abc'),(2,'xyz'),(3,'foo');
+SELECT 'qux' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 );
+'qux' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 )
+0
+SELECT 'bar' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 );
+'bar' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 )
+1
+EXPLAIN
+SELECT 'bar' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY t2 const PRIMARY,a2 PRIMARY 4 const 1
+2 SUBQUERY t1 ref a1,b1 b1 6 const 1 Using where
+DROP TABLE t1,t2;
+CREATE TABLE t1 (i1 INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (i2 int, c2 varchar(3), KEY(i2,c2)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,'abc'),(2,'foo');
+CREATE TABLE t3 (pk3 int PRIMARY KEY, c3 varchar(3)) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (1,'foo'),(2,'bar');
+SELECT * FROM t1 WHERE i1 NOT IN (
+SELECT i2 FROM t2 RIGHT JOIN t3 ON (c3 = c2) WHERE pk3 = i1
+);
+i1
+1
+EXPLAIN
+SELECT * FROM t1 WHERE i1 NOT IN (
+SELECT i2 FROM t2 RIGHT JOIN t3 ON (c3 = c2) WHERE pk3 = i1
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t3 const PRIMARY PRIMARY 4 const 1
+2 DEPENDENT SUBQUERY t2 index NULL i2 11 NULL 2 Using where; Using index
+DROP TABLE t1,t2,t3;
+#
+# MDEV-7599: in-to-exists chosen after min/max optimization
+#
+set @optimizer_switch_save= @@optimizer_switch;
+CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT, c INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,6),(2,4), (8,9);
+SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
+b c
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 MATERIALIZED t1 index NULL a 5 NULL 2 100.00 Using index
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where (not(<expr_cache><`test`.`t2`.`b`>(<in_optimizer>(`test`.`t2`.`b`,`test`.`t2`.`b` in ( <materialize> (select min(`test`.`t1`.`a`) from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`c` = `test`.`t2`.`b`) ), <primary_index_lookup>(`test`.`t2`.`b` in <temporary table> on distinct_key where ((`test`.`t2`.`b` = `<subquery2>`.`MIN(a)`))))))))
+set optimizer_switch= 'materialization=off';
+SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
+b c
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 DEPENDENT SUBQUERY t1 index NULL a 5 NULL 2 100.00 Using index
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where (not(<expr_cache><`test`.`t2`.`b`>(<in_optimizer>(`test`.`t2`.`b`,<exists>(select min(`test`.`t1`.`a`) from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`c` = `test`.`t2`.`b`) having trigcond((<cache>(`test`.`t2`.`b`) = <ref_null_helper>(min(`test`.`t1`.`a`)))))))))
+set optimizer_switch= @optimizer_switch_save;
+DROP TABLE t1,t2;
+CREATE TABLE t1 (f1 varchar(10)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('foo'),('bar');
+CREATE TABLE t2 (f2 varchar(10), key(f2)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('baz'),('qux');
+CREATE TABLE t3 (f3 varchar(10)) ENGINE=MyISAM;
+INSERT INTO t3 VALUES ('abc'),('def');
+SELECT * FROM t1
+WHERE f1 = ALL( SELECT MAX(t2a.f2)
+FROM t2 AS t2a INNER JOIN t2 t2b INNER JOIN t3
+ON (f3 = t2b.f2) );
+f1
+DROP TABLE t1,t2,t3;
+#
+# MDEV-12963: min/max optimization optimizing away all tables employed
+# for uncorrelated IN subquery used in a disjunct of WHERE
+#
+create table t1 (a int, index idx(a)) engine=myisam;
+insert into t1 values (4),(7),(1),(3),(9);
+select * from t1 where a in (select max(a) from t1 where a < 4) or a > 5;
+a
+3
+7
+9
+explain
+select * from t1 where a in (select max(a) from t1 where a < 4) or a > 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index idx idx 5 NULL 5 Using where; Using index
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+drop table t1;
diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result
index c729c17f94f..a71df97e6bc 100644
--- a/mysql-test/r/subselect_no_mat.result
+++ b/mysql-test/r/subselect_no_mat.result
@@ -7113,6 +7113,36 @@ SELECT * FROM t1 WHERE f2 <= SOME ( SELECT f1 FROM t1 );
f1 f2
foo bar
DROP TABLE t1;
+#
+# MDEV-10146: Wrong result (or questionable result and behavior)
+# with aggregate function in uncorrelated SELECT subquery
+#
+CREATE TABLE t1 (f1 INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (f2 int);
+INSERT INTO t2 VALUES (3);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+( SELECT MAX(f1) FROM t2 )
+2
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+( SELECT MAX(f1) FROM t2 )
+2
+INSERT INTO t2 VALUES (4);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+drop view v1;
+drop table t1,t2;
+CREATE TABLE t1 (f1 INT, KEY(f1)) ENGINE=MyISAM;
+INSERT t1 VALUES (4),(8);
+CREATE TABLE t2 (f2 INT, KEY(f2)) ENGINE=MyISAM;
+INSERT t2 VALUES (6),(9);
+SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
+(SELECT MAX(sq.f2) FROM t1)
+NULL
+drop table t1, t2;
set optimizer_switch=default;
select @@optimizer_switch like '%materialization=on%';
@@optimizer_switch like '%materialization=on%'
diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result
index dc308ea77e5..2f8c67fa167 100644
--- a/mysql-test/r/subselect_no_opts.result
+++ b/mysql-test/r/subselect_no_opts.result
@@ -7111,4 +7111,34 @@ SELECT * FROM t1 WHERE f2 <= SOME ( SELECT f1 FROM t1 );
f1 f2
foo bar
DROP TABLE t1;
+#
+# MDEV-10146: Wrong result (or questionable result and behavior)
+# with aggregate function in uncorrelated SELECT subquery
+#
+CREATE TABLE t1 (f1 INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (f2 int);
+INSERT INTO t2 VALUES (3);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+( SELECT MAX(f1) FROM t2 )
+2
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+( SELECT MAX(f1) FROM t2 )
+2
+INSERT INTO t2 VALUES (4);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+drop view v1;
+drop table t1,t2;
+CREATE TABLE t1 (f1 INT, KEY(f1)) ENGINE=MyISAM;
+INSERT t1 VALUES (4),(8);
+CREATE TABLE t2 (f2 INT, KEY(f2)) ENGINE=MyISAM;
+INSERT t2 VALUES (6),(9);
+SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
+(SELECT MAX(sq.f2) FROM t1)
+NULL
+drop table t1, t2;
set @optimizer_switch_for_subselect_test=null;
diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result
index e7c85c10f2d..8dda0a4fd36 100644
--- a/mysql-test/r/subselect_no_scache.result
+++ b/mysql-test/r/subselect_no_scache.result
@@ -7122,6 +7122,36 @@ SELECT * FROM t1 WHERE f2 <= SOME ( SELECT f1 FROM t1 );
f1 f2
foo bar
DROP TABLE t1;
+#
+# MDEV-10146: Wrong result (or questionable result and behavior)
+# with aggregate function in uncorrelated SELECT subquery
+#
+CREATE TABLE t1 (f1 INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (f2 int);
+INSERT INTO t2 VALUES (3);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+( SELECT MAX(f1) FROM t2 )
+2
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+( SELECT MAX(f1) FROM t2 )
+2
+INSERT INTO t2 VALUES (4);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+drop view v1;
+drop table t1,t2;
+CREATE TABLE t1 (f1 INT, KEY(f1)) ENGINE=MyISAM;
+INSERT t1 VALUES (4),(8);
+CREATE TABLE t2 (f2 INT, KEY(f2)) ENGINE=MyISAM;
+INSERT t2 VALUES (6),(9);
+SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
+(SELECT MAX(sq.f2) FROM t1)
+NULL
+drop table t1, t2;
set optimizer_switch=default;
select @@optimizer_switch like '%subquery_cache=on%';
@@optimizer_switch like '%subquery_cache=on%'
diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result
index b6261f05098..339e2b89786 100644
--- a/mysql-test/r/subselect_no_semijoin.result
+++ b/mysql-test/r/subselect_no_semijoin.result
@@ -7111,5 +7111,35 @@ SELECT * FROM t1 WHERE f2 <= SOME ( SELECT f1 FROM t1 );
f1 f2
foo bar
DROP TABLE t1;
+#
+# MDEV-10146: Wrong result (or questionable result and behavior)
+# with aggregate function in uncorrelated SELECT subquery
+#
+CREATE TABLE t1 (f1 INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (f2 int);
+INSERT INTO t2 VALUES (3);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+( SELECT MAX(f1) FROM t2 )
+2
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+( SELECT MAX(f1) FROM t2 )
+2
+INSERT INTO t2 VALUES (4);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+drop view v1;
+drop table t1,t2;
+CREATE TABLE t1 (f1 INT, KEY(f1)) ENGINE=MyISAM;
+INSERT t1 VALUES (4),(8);
+CREATE TABLE t2 (f2 INT, KEY(f2)) ENGINE=MyISAM;
+INSERT t2 VALUES (6),(9);
+SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
+(SELECT MAX(sq.f2) FROM t1)
+NULL
+drop table t1, t2;
set @optimizer_switch_for_subselect_test=null;
set @join_cache_level_for_subselect_test=NULL;
diff --git a/mysql-test/r/subselect_nulls.result b/mysql-test/r/subselect_nulls.result
index 584c184870d..08982371269 100644
--- a/mysql-test/r/subselect_nulls.result
+++ b/mysql-test/r/subselect_nulls.result
@@ -115,3 +115,9 @@ k d1 d2
set optimizer_switch= @tmp_subselect_nulls;
drop table x1;
drop table x2;
+select (select 1, 2) in (select 3, 4);
+(select 1, 2) in (select 3, 4)
+0
+select (select NULL, NULL) in (select 3, 4);
+(select NULL, NULL) in (select 3, 4)
+NULL
diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result
index 50a70a6614a..74384141998 100644
--- a/mysql-test/r/subselect_sj.result
+++ b/mysql-test/r/subselect_sj.result
@@ -1650,9 +1650,9 @@ CREATE VIEW v1 AS SELECT 1;
EXPLAIN
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived3> system NULL NULL NULL NULL 1
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
-2 MATERIALIZED <derived3> system NULL NULL NULL NULL 1
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
a a
@@ -3060,4 +3060,97 @@ project_number
aaa
drop table t1, t2, t3;
set optimizer_switch= @tmp_mdev6859;
+#
+# MDEV-12675: subquery subject to semi-join optimizations
+# in ON expression of INNER JOIN
+#
+set @tmp_mdev12675=@@optimizer_switch;
+set optimizer_switch=default;
+create table t1 (a int) engine=myisam;
+insert into t1 values (5),(3),(2),(7),(2),(5),(1);
+create table t2 (b int, index idx(b)) engine=myisam;
+insert into t2 values (2),(3),(2),(1),(3),(4);
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+analyze table t1,t2;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+test.t2 analyze status OK
+explain
+select a from t1, t2 where b between 1 and 2 and a in (select b from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
+1 PRIMARY t2 ref idx idx 5 test.t1.a 256 Using index; FirstMatch(t1)
+1 PRIMARY t2 range idx idx 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
+explain
+select a from t1 join t2 on b between 1 and 2 and a in (select b from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
+1 PRIMARY t2 ref idx idx 5 test.t1.a 256 Using index; FirstMatch(t1)
+1 PRIMARY t2 range idx idx 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
+drop table t1,t2;
+set optimizer_switch= @tmp_mdev12675;
+#
+# MDEV-12817: subquery NOT subject to semi-join optimizations
+# in ON expression of INNER JOIN
+#
+CREATE TABLE t1 (c1 int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (c2 int) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (c3 int) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (5),(6);
+CREATE TABLE t4 (c4 int) ENGINE=MyISAM;
+INSERT INTO t4 VALUES (7),(8);
+SELECT c1
+FROM t1
+LEFT JOIN
+( t2 INNER JOIN t3 ON ( 1 IN ( SELECT c4 FROM t4 ) ) )
+ON (c1 = c3);
+c1
+1
+2
+EXPLAIN EXTENDED SELECT c1
+FROM t1
+LEFT JOIN
+( t2 INNER JOIN t3 ON ( 1 IN ( SELECT c4 FROM t4 ) ) )
+ON (c1 = c3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`c1` AS `c1` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t3`.`c3` = `test`.`t1`.`c1`) and <cache>(<in_optimizer>(1,<exists>(select `test`.`t4`.`c4` from `test`.`t4` where (1 = `test`.`t4`.`c4`)))))) where 1
+# mdev-12820
+SELECT *
+FROM t1
+LEFT JOIN
+( ( SELECT * FROM t2 WHERE c2 IN ( SELECT c3 FROM t3 ) ) AS sq INNER JOIN t4 )
+ON (c1 = c2);
+c1 c2 c4
+1 NULL NULL
+2 NULL NULL
+EXPLAIN EXTENDED SELECT *
+FROM t1
+LEFT JOIN
+( ( SELECT * FROM t2 WHERE c2 IN ( SELECT c3 FROM t3 ) ) AS sq INNER JOIN t4 )
+ON (c1 = c2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00
+3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2`,`test`.`t4`.`c4` AS `c4` from `test`.`t1` left join (`test`.`t2` join `test`.`t4`) on(((`test`.`t2`.`c2` = `test`.`t1`.`c1`) and <in_optimizer>(`test`.`t1`.`c1`,<exists>(select `test`.`t3`.`c3` from `test`.`t3` where (<cache>(`test`.`t2`.`c2`) = `test`.`t3`.`c3`))))) where 1
+DROP TABLE t1,t2,t3,t4;
set optimizer_switch=@subselect_sj_tmp;
diff --git a/mysql-test/r/subselect_sj2_mat.result b/mysql-test/r/subselect_sj2_mat.result
index 4e75aee24a2..835742a3ff4 100644
--- a/mysql-test/r/subselect_sj2_mat.result
+++ b/mysql-test/r/subselect_sj2_mat.result
@@ -1556,3 +1556,48 @@ i1
DROP TABLE t1,t2,t3;
set join_cache_level= @save_join_cache_level;
set optimizer_switch=@save_optimizer_switch;
+#
+# mdev-7791: materialization of a semi-join subquery +
+# RAND() in WHERE
+# (materialized table is accessed last)
+#
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='materialization=on';
+create table t1(i int);
+insert into t1 values (1), (2), (3), (7), (9), (10);
+create table t2(i int);
+insert into t2 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+select * from t1 where (rand() < 0) and i in (select i from t2);
+i
+explain extended
+select * from t1 where (rand() < 0) and i in (select i from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`i` AS `i` from `test`.`t1` semi join (`test`.`t2`) where ((rand() < 0))
+drop table t1,t2;
+set optimizer_switch=@save_optimizer_switch;
+#
+# mdev-12855: materialization of a semi-join subquery + ORDER BY
+#
+CREATE TABLE t1 (f1 varchar(8), KEY(f1)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('qux'),('foo');
+CREATE TABLE t2 (f2 varchar(8)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('bar'),('foo'),('qux');
+SELECT f1 FROM t1
+WHERE f1 IN ( SELECT f2 FROM t2 WHERE f2 > 'bar' )
+HAVING f1 != 'foo'
+ORDER BY f1;
+f1
+qux
+explain SELECT f1 FROM t1
+WHERE f1 IN ( SELECT f2 FROM t2 WHERE f2 > 'bar' )
+HAVING f1 != 'foo'
+ORDER BY f1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index f1 f1 11 NULL 2 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 11 func 1
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where
+DROP TABLE t1,t2;
diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result
index ccf348fa311..47dbdd782b5 100644
--- a/mysql-test/r/subselect_sj_jcl6.result
+++ b/mysql-test/r/subselect_sj_jcl6.result
@@ -1663,9 +1663,9 @@ CREATE VIEW v1 AS SELECT 1;
EXPLAIN
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived3> system NULL NULL NULL NULL 1
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
-2 MATERIALIZED <derived3> system NULL NULL NULL NULL 1
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
a a
@@ -3074,6 +3074,99 @@ project_number
aaa
drop table t1, t2, t3;
set optimizer_switch= @tmp_mdev6859;
+#
+# MDEV-12675: subquery subject to semi-join optimizations
+# in ON expression of INNER JOIN
+#
+set @tmp_mdev12675=@@optimizer_switch;
+set optimizer_switch=default;
+create table t1 (a int) engine=myisam;
+insert into t1 values (5),(3),(2),(7),(2),(5),(1);
+create table t2 (b int, index idx(b)) engine=myisam;
+insert into t2 values (2),(3),(2),(1),(3),(4);
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+analyze table t1,t2;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+test.t2 analyze status OK
+explain
+select a from t1, t2 where b between 1 and 2 and a in (select b from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
+1 PRIMARY t2 ref idx idx 5 test.t1.a 256 Using index; FirstMatch(t1)
+1 PRIMARY t2 range idx idx 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
+explain
+select a from t1 join t2 on b between 1 and 2 and a in (select b from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 7 Using where
+1 PRIMARY t2 ref idx idx 5 test.t1.a 256 Using index; FirstMatch(t1)
+1 PRIMARY t2 range idx idx 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
+drop table t1,t2;
+set optimizer_switch= @tmp_mdev12675;
+#
+# MDEV-12817: subquery NOT subject to semi-join optimizations
+# in ON expression of INNER JOIN
+#
+CREATE TABLE t1 (c1 int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (c2 int) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (3),(4);
+CREATE TABLE t3 (c3 int) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (5),(6);
+CREATE TABLE t4 (c4 int) ENGINE=MyISAM;
+INSERT INTO t4 VALUES (7),(8);
+SELECT c1
+FROM t1
+LEFT JOIN
+( t2 INNER JOIN t3 ON ( 1 IN ( SELECT c4 FROM t4 ) ) )
+ON (c1 = c3);
+c1
+1
+2
+EXPLAIN EXTENDED SELECT c1
+FROM t1
+LEFT JOIN
+( t2 INNER JOIN t3 ON ( 1 IN ( SELECT c4 FROM t4 ) ) )
+ON (c1 = c3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
+2 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`c1` AS `c1` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t3`.`c3` = `test`.`t1`.`c1`) and <cache>(<in_optimizer>(1,<exists>(select `test`.`t4`.`c4` from `test`.`t4` where (1 = `test`.`t4`.`c4`)))))) where 1
+# mdev-12820
+SELECT *
+FROM t1
+LEFT JOIN
+( ( SELECT * FROM t2 WHERE c2 IN ( SELECT c3 FROM t3 ) ) AS sq INNER JOIN t4 )
+ON (c1 = c2);
+c1 c2 c4
+1 NULL NULL
+2 NULL NULL
+EXPLAIN EXTENDED SELECT *
+FROM t1
+LEFT JOIN
+( ( SELECT * FROM t2 WHERE c2 IN ( SELECT c3 FROM t3 ) ) AS sq INNER JOIN t4 )
+ON (c1 = c2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (incremental, BNL join)
+3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2`,`test`.`t4`.`c4` AS `c4` from `test`.`t1` left join (`test`.`t2` join `test`.`t4`) on(((`test`.`t2`.`c2` = `test`.`t1`.`c1`) and <in_optimizer>(`test`.`t1`.`c1`,<exists>(select `test`.`t3`.`c3` from `test`.`t3` where (<cache>(`test`.`t2`.`c2`) = `test`.`t3`.`c3`))))) where 1
+DROP TABLE t1,t2,t3,t4;
set optimizer_switch=@subselect_sj_tmp;
#
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result
index 47f578fb589..cb5012a91c9 100644
--- a/mysql-test/r/subselect_sj_mat.result
+++ b/mysql-test/r/subselect_sj_mat.result
@@ -2312,4 +2312,92 @@ pk f1 sq
5 3 5
set optimizer_switch= @save_optimizer_switch;
DROP TABLE t1,t2;
+#
+# mdev-12838: scan of materialized of semi-join subquery in join
+#
+set @save_optimizer_switch=@@optimizer_switch;
+CREATE TABLE t1 (
+dispatch_group varchar(32),
+assignment_group varchar(32),
+sys_id char(32),
+PRIMARY KEY (sys_id),
+KEY idx1 (dispatch_group),
+KEY idx2 (assignment_group)
+) ENGINE=MyISAM;
+CREATE TABLE t2 (
+ugroup varchar(32),
+user varchar(32),
+sys_id char(32),
+PRIMARY KEY (sys_id),
+KEY idx3 (ugroup),
+KEY idx4 (user)
+) ENGINE=MyISAM;
+CREATE TABLE t3 (
+type mediumtext,
+sys_id char(32),
+PRIMARY KEY (sys_id)
+) ENGINE=MyISAM;
+set optimizer_switch='materialization=off';
+explain SELECT t1.assignment_group
+FROM t1, t3
+WHERE t1.assignment_group = t3.sys_id AND
+t1.dispatch_group IN
+(SELECT t2.ugroup
+FROM t2, t3 t3_i
+WHERE t2.ugroup = t3_i.sys_id AND
+t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
+t2.user = '86826bf03710200044e0bfc8bcbe5d79');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where; Start temporary
+1 PRIMARY t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where
+1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t3_i.sys_id 2 Using index condition; Using where; End temporary
+1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index
+SELECT t1.assignment_group
+FROM t1, t3
+WHERE t1.assignment_group = t3.sys_id AND
+t1.dispatch_group IN
+(SELECT t2.ugroup
+FROM t2, t3 t3_i
+WHERE t2.ugroup = t3_i.sys_id AND
+t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
+t2.user = '86826bf03710200044e0bfc8bcbe5d79');
+assignment_group
+df50316637232000158bbfc8bcbe5d23
+e08fad2637232000158bbfc8bcbe5d39
+ec70316637232000158bbfc8bcbe5d60
+7b10fd2637232000158bbfc8bcbe5d30
+ebb4620037332000158bbfc8bcbe5d89
+set optimizer_switch='materialization=on';
+explain SELECT t1.assignment_group
+FROM t1, t3
+WHERE t1.assignment_group = t3.sys_id AND
+t1.dispatch_group IN
+(SELECT t2.ugroup
+FROM t2, t3 t3_i
+WHERE t2.ugroup = t3_i.sys_id AND
+t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
+t2.user = '86826bf03710200044e0bfc8bcbe5d79');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
+1 PRIMARY t1 ref idx1,idx2 idx1 35 test.t2.ugroup 2 Using where
+1 PRIMARY t3 eq_ref PRIMARY PRIMARY 32 test.t1.assignment_group 1 Using where; Using index
+2 MATERIALIZED t2 ref idx3,idx4 idx4 35 const 2 Using index condition; Using where
+2 MATERIALIZED t3_i eq_ref PRIMARY PRIMARY 32 test.t2.ugroup 1 Using index condition; Using where
+SELECT t1.assignment_group
+FROM t1, t3
+WHERE t1.assignment_group = t3.sys_id AND
+t1.dispatch_group IN
+(SELECT t2.ugroup
+FROM t2, t3 t3_i
+WHERE t2.ugroup = t3_i.sys_id AND
+t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
+t2.user = '86826bf03710200044e0bfc8bcbe5d79');
+assignment_group
+df50316637232000158bbfc8bcbe5d23
+e08fad2637232000158bbfc8bcbe5d39
+ec70316637232000158bbfc8bcbe5d60
+7b10fd2637232000158bbfc8bcbe5d30
+ebb4620037332000158bbfc8bcbe5d89
+DROP TABLE t1,t2,t3;
+set optimizer_switch=@save_optimizer_switch;
# End of 5.5 tests
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index 5a6cd8907e9..fe2339db471 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -1978,3 +1978,21 @@ d
2016-06-04 00:00:00
drop table t1;
End of 5.0 tests
+create table t1 (a int, b int);
+insert into t1 values (1,1),(2,2),(3,3);
+create table t2 (c varchar(30), d varchar(30));
+insert into t1 values ('1','1'),('2','2'),('4','4');
+create table t3 (e int, f int);
+insert into t3 values (1,1),(2,2),(31,31),(32,32);
+select e,f, (e , f) in (select e,b from t1 union select c,d from t2) as sub from t3;
+e f sub
+1 1 1
+2 2 1
+31 31 0
+32 32 0
+select avg(f), (e , f) in (select e,b from t1 union select c,d from t2) as sub from t3 group by sub;
+avg(f) sub
+31.5000 0
+1.5000 1
+drop table t1,t2,t3;
+End of 5.5 tests
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 414de5662f3..0f8e9999730 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -5618,6 +5618,20 @@ Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`e` AS `e`,`test`.`t3`.`f` AS `f` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t2`.`c` = `test`.`t1`.`b`) and (`test`.`t3`.`f` = `test`.`t1`.`a`) and (`test`.`t2`.`d` = `test`.`t3`.`e`) and (`test`.`t1`.`a` is not null) and (`test`.`t1`.`a` is not null) and (`test`.`t1`.`b` is not null))) where (`test`.`t1`.`a` < 5)
drop view v1;
drop table t1,t2,t3;
+#
+# MDEV-11240: Server crashes in check_view_single_update or
+# Assertion `derived->table' failed in mysql_derived_merge_for_insert
+#
+CREATE TABLE t3 (a INT);
+CREATE ALGORITHM = MERGE VIEW v1 AS SELECT t2.a FROM t3 AS t1, t3 AS t2;
+CREATE ALGORITHM = MERGE VIEW v2 AS SELECT * FROM v1;
+PREPARE stmt FROM 'REPLACE INTO v2 SELECT a FROM t3';
+EXECUTE stmt;
+ERROR HY000: Can not insert into join view 'test.v2' without fields list
+EXECUTE stmt;
+ERROR HY000: Can not insert into join view 'test.v2' without fields list
+drop view v1,v2;
+drop table t3;
# -----------------------------------------------------------------
# -- End of 5.5 tests.
# -----------------------------------------------------------------
diff --git a/mysql-test/std_data/loadxml.dat b/mysql-test/std_data/loadxml.dat
index b72fac9da74..d5ccd4a1b13 100644
--- a/mysql-test/std_data/loadxml.dat
+++ b/mysql-test/std_data/loadxml.dat
@@ -9,19 +9,19 @@
<table_data name="t1">
<row>
<field name="a">1</field>
- <field name="b">b1</field>
+ <field name="b"> b1</field>
</row>
<row>
<field name="a">2</field>
- <field name="b">b2</field>
+ <field name="b"> b2</field>
</row>
<row>
<field name="a">3</field>
- <field name="b">b3</field>
+ <field name="b"> b3</field>
</row>
<row>
<field name="a">11</field>
- <field name="b">b11</field>
+ <field name="b"> b11</field>
</row>
<!-- Check field values as tags -->
diff --git a/mysql-test/suite/parts/r/longname.result b/mysql-test/suite/parts/r/longname.result
new file mode 100644
index 00000000000..40097d60d15
--- /dev/null
+++ b/mysql-test/suite/parts/r/longname.result
@@ -0,0 +1,33 @@
+set names utf8;
+create database mysqltest1;
+CREATE TABLE mysqltest1.test_jfg_table_name_with_64_chars_123456789012345678901234567890 (
+id int(10) unsigned NOT NULL,
+id2 int(10) unsigned NOT NULL,
+PRIMARY KEY ( id, id2 )
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
+PARTITION BY RANGE ( id )
+SUBPARTITION BY HASH ( id2 )
+SUBPARTITIONS 2 (
+PARTITION test_jfg_partition_name_with_60_chars_1234567890123456789012 VALUES LESS THAN (1000) ENGINE = InnoDB,
+PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = InnoDB);
+Warnings:
+Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table.
+Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT.
+Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table.
+Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT.
+Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table.
+Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT.
+Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table.
+Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT.
+CREATE TABLE mysqltest1.éééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééé (
+id int(10) unsigned NOT NULL,
+id2 int(10) unsigned NOT NULL,
+PRIMARY KEY ( id, id2 )
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
+PARTITION BY RANGE ( id )
+SUBPARTITION BY HASH ( id2 )
+SUBPARTITIONS 2 (
+PARTITION çççççççççççççççççççççççççççççççççççççççççççççççççççççççççççç VALUES LESS THAN (1000) ENGINE = InnoDB,
+PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = InnoDB);
+ERROR HY000: The path specified for @0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@0n@ is too long.
+drop database mysqltest1;
diff --git a/mysql-test/suite/parts/r/quoting.result b/mysql-test/suite/parts/r/quoting.result
new file mode 100644
index 00000000000..ba6a155e6ac
--- /dev/null
+++ b/mysql-test/suite/parts/r/quoting.result
@@ -0,0 +1,6 @@
+set sql_mode=ansi_quotes;
+create table t1 (i int) partition by range (i) (partition flush values less than maxvalue);
+set sql_mode=default;
+lock tables t1 read local;
+unlock tables;
+drop table t1;
diff --git a/mysql-test/suite/parts/t/longname.test b/mysql-test/suite/parts/t/longname.test
new file mode 100644
index 00000000000..feea5a790f2
--- /dev/null
+++ b/mysql-test/suite/parts/t/longname.test
@@ -0,0 +1,29 @@
+source include/have_innodb.inc;
+source include/have_partition.inc;
+set names utf8;
+
+create database mysqltest1;
+CREATE TABLE mysqltest1.test_jfg_table_name_with_64_chars_123456789012345678901234567890 (
+ id int(10) unsigned NOT NULL,
+ id2 int(10) unsigned NOT NULL,
+ PRIMARY KEY ( id, id2 )
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
+PARTITION BY RANGE ( id )
+ SUBPARTITION BY HASH ( id2 )
+ SUBPARTITIONS 2 (
+ PARTITION test_jfg_partition_name_with_60_chars_1234567890123456789012 VALUES LESS THAN (1000) ENGINE = InnoDB,
+ PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = InnoDB);
+
+--error ER_PATH_LENGTH
+CREATE TABLE mysqltest1.éééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééé (
+ id int(10) unsigned NOT NULL,
+ id2 int(10) unsigned NOT NULL,
+ PRIMARY KEY ( id, id2 )
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
+PARTITION BY RANGE ( id )
+ SUBPARTITION BY HASH ( id2 )
+ SUBPARTITIONS 2 (
+ PARTITION çççççççççççççççççççççççççççççççççççççççççççççççççççççççççççç VALUES LESS THAN (1000) ENGINE = InnoDB,
+ PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = InnoDB);
+
+drop database mysqltest1;
diff --git a/mysql-test/suite/parts/t/quoting.test b/mysql-test/suite/parts/t/quoting.test
new file mode 100644
index 00000000000..297896fd9cf
--- /dev/null
+++ b/mysql-test/suite/parts/t/quoting.test
@@ -0,0 +1,10 @@
+#
+# MDEV-13017 LOCK TABLE fails with irrelevant error while working with tables affected by ANSI_QUOTES
+#
+--source include/have_partition.inc
+set sql_mode=ansi_quotes;
+create table t1 (i int) partition by range (i) (partition flush values less than maxvalue);
+set sql_mode=default;
+lock tables t1 read local;
+unlock tables;
+drop table t1;
diff --git a/mysql-test/suite/perfschema/include/have_timer_cycle.inc b/mysql-test/suite/perfschema/include/have_timer_cycle.inc
new file mode 100644
index 00000000000..b801ea256d6
--- /dev/null
+++ b/mysql-test/suite/perfschema/include/have_timer_cycle.inc
@@ -0,0 +1,4 @@
+if (!`SELECT count(*) FROM performance_schema.performance_timers WHERE timer_name='CYCLE' AND timer_frequency IS NOT NULL`)
+{
+ Skip Need performance timer CYCLE;
+}
diff --git a/mysql-test/suite/perfschema/r/privilege.result b/mysql-test/suite/perfschema/r/privilege.result
index d1831c9c4be..61eade13bbf 100644
--- a/mysql-test/suite/perfschema/r/privilege.result
+++ b/mysql-test/suite/perfschema/r/privilege.result
@@ -554,7 +554,7 @@ ERROR 42000: DROP command denied to user 'pfs_user_4'@'localhost' for table 'eve
#
# Grant access to change tables with the root account
GRANT UPDATE ON performance_schema.setup_consumers TO pfs_user_4;
-GRANT UPDATE ON performance_schema.setup_timers TO pfs_user_4;
+GRANT UPDATE, SELECT ON performance_schema.setup_timers TO pfs_user_4;
GRANT UPDATE, SELECT ON performance_schema.setup_instruments TO pfs_user_4;
GRANT DROP ON performance_schema.events_waits_current TO pfs_user_4;
GRANT DROP ON performance_schema.events_waits_history TO pfs_user_4;
@@ -565,7 +565,7 @@ UPDATE performance_schema.setup_instruments SET enabled = 'YES'
WHERE name LIKE 'wait/synch/mutex/%'
OR name LIKE 'wait/synch/rwlock/%';
UPDATE performance_schema.setup_consumers SET enabled = 'YES';
-UPDATE performance_schema.setup_timers SET timer_name = 'TICK';
+UPDATE performance_schema.setup_timers SET timer_name = 'TICK' WHERE name <> "wait";
TRUNCATE TABLE performance_schema.events_waits_history_long;
TRUNCATE TABLE performance_schema.events_waits_history;
TRUNCATE TABLE performance_schema.events_waits_current;
@@ -575,4 +575,6 @@ DROP USER pfs_user_4;
flush privileges;
UPDATE performance_schema.setup_instruments SET enabled = 'YES', timed = 'YES';
UPDATE performance_schema.setup_consumers SET enabled = 'YES';
-UPDATE performance_schema.setup_timers SET timer_name = 'CYCLE';
+UPDATE performance_schema.setup_timers SET timer_name = 'MICROSECOND' where name="idle";
+UPDATE performance_schema.setup_timers SET timer_name = 'NANOSECOND' where name="stage";
+UPDATE performance_schema.setup_timers SET timer_name = 'NANOSECOND' where name="statement";
diff --git a/mysql-test/suite/perfschema/t/dml_performance_timers.test b/mysql-test/suite/perfschema/t/dml_performance_timers.test
index 2ec37fbe7e9..587c54144aa 100644
--- a/mysql-test/suite/perfschema/t/dml_performance_timers.test
+++ b/mysql-test/suite/perfschema/t/dml_performance_timers.test
@@ -2,6 +2,7 @@
--source include/not_embedded.inc
--source include/have_perfschema.inc
+--source include/have_timer_cycle.inc
--replace_column 2 <frequency> 3 <resolution> 4 <overhead>
select * from performance_schema.performance_timers;
diff --git a/mysql-test/suite/perfschema/t/dml_setup_timers.test b/mysql-test/suite/perfschema/t/dml_setup_timers.test
index 0956ae2cc95..6a6b813ab07 100644
--- a/mysql-test/suite/perfschema/t/dml_setup_timers.test
+++ b/mysql-test/suite/perfschema/t/dml_setup_timers.test
@@ -2,6 +2,7 @@
--source include/not_embedded.inc
--source include/have_perfschema.inc
+--source include/have_timer_cycle.inc
select * from performance_schema.setup_timers;
diff --git a/mysql-test/suite/perfschema/t/privilege.test b/mysql-test/suite/perfschema/t/privilege.test
index 3b4cd1a4d2b..47a68602fa4 100644
--- a/mysql-test/suite/perfschema/t/privilege.test
+++ b/mysql-test/suite/perfschema/t/privilege.test
@@ -291,7 +291,7 @@ TRUNCATE TABLE performance_schema.events_waits_current;
--echo # Grant access to change tables with the root account
GRANT UPDATE ON performance_schema.setup_consumers TO pfs_user_4;
-GRANT UPDATE ON performance_schema.setup_timers TO pfs_user_4;
+GRANT UPDATE, SELECT ON performance_schema.setup_timers TO pfs_user_4;
GRANT UPDATE, SELECT ON performance_schema.setup_instruments TO pfs_user_4;
GRANT DROP ON performance_schema.events_waits_current TO pfs_user_4;
GRANT DROP ON performance_schema.events_waits_history TO pfs_user_4;
@@ -308,7 +308,11 @@ WHERE name LIKE 'wait/synch/mutex/%'
UPDATE performance_schema.setup_consumers SET enabled = 'YES';
-UPDATE performance_schema.setup_timers SET timer_name = 'TICK';
+# We do not touch "wait", to avoid restoring it at the end of the test,
+# as its default value initialized at server startup is ambiguous:
+# it can be CYCLE or NANOSECOND depending on platform
+
+UPDATE performance_schema.setup_timers SET timer_name = 'TICK' WHERE name <> "wait";
TRUNCATE TABLE performance_schema.events_waits_history_long;
TRUNCATE TABLE performance_schema.events_waits_history;
@@ -323,5 +327,9 @@ DROP USER pfs_user_4;
flush privileges;
UPDATE performance_schema.setup_instruments SET enabled = 'YES', timed = 'YES';
UPDATE performance_schema.setup_consumers SET enabled = 'YES';
-UPDATE performance_schema.setup_timers SET timer_name = 'CYCLE';
+# Restore the default values for the timers that we changed.
+# Note, we did not touch "wait", see above.
+UPDATE performance_schema.setup_timers SET timer_name = 'MICROSECOND' where name="idle";
+UPDATE performance_schema.setup_timers SET timer_name = 'NANOSECOND' where name="stage";
+UPDATE performance_schema.setup_timers SET timer_name = 'NANOSECOND' where name="statement";
diff --git a/mysql-test/suite/rpl/r/rpl_mdev-11092.result b/mysql-test/suite/rpl/r/rpl_mdev-11092.result
new file mode 100644
index 00000000000..b2de9e5f573
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_mdev-11092.result
@@ -0,0 +1,17 @@
+include/master-slave.inc
+[connection master]
+call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
+call mtr.add_suppression("Slave SQL: The incident LOST_EVENTS occured on the master. .*");
+SET GLOBAL max_binlog_cache_size = 4096;
+SET GLOBAL binlog_cache_size = 4096;
+SET GLOBAL max_binlog_stmt_cache_size = 4096;
+SET GLOBAL binlog_stmt_cache_size = 4096;
+CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MYISAM;
+ERROR HY000: Writing one row to the row-based binary log failed
+include/wait_for_slave_sql_error_and_skip.inc [errno=1590]
+SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE;
+SET GLOBAL binlog_cache_size= ORIGINAL_VALUE;
+SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE;
+SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE;
+DROP TABLE t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_reset_slave_fail.result b/mysql-test/suite/rpl/r/rpl_reset_slave_fail.result
new file mode 100644
index 00000000000..fdfec62058f
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_reset_slave_fail.result
@@ -0,0 +1,29 @@
+include/master-slave.inc
+[connection master]
+CREATE TABLE t1 (c1 INT);
+INSERT INTO t1 (c1) VALUES (1);
+include/stop_slave_sql.inc
+FLUSH LOGS;
+FLUSH LOGS;
+INSERT INTO t1 (c1) VALUES (2);
+include/sync_slave_io_with_master.inc
+call mtr.add_suppression("File '.*slave-relay-bin.");
+call mtr.add_suppression("Could not open log file");
+call mtr.add_suppression("Failed to open the relay log");
+call mtr.add_suppression("Failed to initialize the master info structure");
+include/rpl_stop_server.inc [server_number=2]
+# Removing file(s)
+include/rpl_start_server.inc [server_number=2]
+START SLAVE;
+ERROR HY000: Could not initialize master info structure; more error messages can be found in the MariaDB error log
+START SLAVE;
+ERROR HY000: Could not initialize master info structure; more error messages can be found in the MariaDB error log
+RESET SLAVE;
+DROP TABLE t1;
+START SLAVE UNTIL MASTER_LOG_FILE= 'MASTER_LOG_FILE', MASTER_LOG_POS= MASTER_LOG_POS;;
+include/wait_for_slave_sql_to_stop.inc
+include/stop_slave_io.inc
+include/start_slave.inc
+include/diff_tables.inc [master:t1, slave:t1]
+DROP TABLE t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_mdev-11092.opt b/mysql-test/suite/rpl/t/rpl_mdev-11092.opt
new file mode 100644
index 00000000000..7f1d270d29f
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_mdev-11092.opt
@@ -0,0 +1 @@
+--binlog_checksum=1 --binlog-annotate-row-events=1
diff --git a/mysql-test/suite/rpl/t/rpl_mdev-11092.test b/mysql-test/suite/rpl/t/rpl_mdev-11092.test
new file mode 100644
index 00000000000..c8b2b7f2ad1
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_mdev-11092.test
@@ -0,0 +1,53 @@
+--source include/have_innodb.inc
+--source include/master-slave.inc
+--source include/not_embedded.inc
+--source include/not_windows.inc
+--source include/have_binlog_format_row.inc
+
+########################################################################################
+call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
+call mtr.add_suppression("Slave SQL: The incident LOST_EVENTS occured on the master. .*");
+
+let $old_max_binlog_cache_size= query_get_value(SHOW VARIABLES LIKE "max_binlog_cache_size", Value, 1);
+let $old_binlog_cache_size= query_get_value(SHOW VARIABLES LIKE "binlog_cache_size", Value, 1);
+let $old_max_binlog_stmt_cache_size= query_get_value(SHOW VARIABLES LIKE "max_binlog_stmt_cache_size", Value, 1);
+let $old_binlog_stmt_cache_size= query_get_value(SHOW VARIABLES LIKE "binlog_stmt_cache_size", Value, 1);
+
+SET GLOBAL max_binlog_cache_size = 4096;
+SET GLOBAL binlog_cache_size = 4096;
+SET GLOBAL max_binlog_stmt_cache_size = 4096;
+SET GLOBAL binlog_stmt_cache_size = 4096;
+disconnect master;
+connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,);
+
+CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MYISAM;
+
+let $data = `select concat('"', repeat('a',2000), '"')`;
+
+connection master;
+
+--disable_query_log
+--error ER_BINLOG_ROW_LOGGING_FAILED
+eval INSERT INTO t1 (a, data) VALUES (2,
+ CONCAT($data, $data, $data, $data, $data, $data));
+--enable_query_log
+
+# Incident event
+# 1590=ER_SLAVE_INCIDENT
+--let $slave_sql_errno= 1590
+--source include/wait_for_slave_sql_error_and_skip.inc
+
+connection master;
+
+--replace_result $old_max_binlog_cache_size ORIGINAL_VALUE
+--eval SET GLOBAL max_binlog_cache_size= $old_max_binlog_cache_size
+--replace_result $old_binlog_cache_size ORIGINAL_VALUE
+--eval SET GLOBAL binlog_cache_size= $old_binlog_cache_size
+--replace_result $old_max_binlog_stmt_cache_size ORIGINAL_VALUE
+--eval SET GLOBAL max_binlog_stmt_cache_size= $old_max_binlog_stmt_cache_size
+--replace_result $old_binlog_stmt_cache_size ORIGINAL_VALUE
+--eval SET GLOBAL binlog_stmt_cache_size= $old_binlog_stmt_cache_size
+
+DROP TABLE t1;
+
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_reset_slave_fail.test b/mysql-test/suite/rpl/t/rpl_reset_slave_fail.test
new file mode 100644
index 00000000000..021dc76d50c
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_reset_slave_fail.test
@@ -0,0 +1,91 @@
+###############################################################################
+# Bug#24901077: RESET SLAVE ALL DOES NOT ALWAYS RESET SLAVE
+#
+# Problem:
+# =======
+# If you have a relay log index file that has ended up with
+# some relay log files that do not exists, then RESET SLAVE
+# ALL is not enough to get back to a clean state.
+###############################################################################
+# Remove all slave-relay-bin.0* files (do not remove slave-relay-bin.index)
+# During server restart rli initialization will fail as there are no
+# relay logs. In case of bug RESET SLAVE will not do the required clean up
+# as rli is not inited and subsequent START SLAVE will fail.
+# Disable "Warning 1612 Being purged log ./slave-relay-bin.0* was not found"
+# because it is different on Unix and Windows systems.
+
+--source include/have_binlog_format_mixed.inc
+--source include/master-slave.inc
+
+--connection master
+CREATE TABLE t1 (c1 INT);
+INSERT INTO t1 (c1) VALUES (1);
+--sync_slave_with_master
+
+--connection slave
+--source include/stop_slave_sql.inc
+--let $MYSQLD_SLAVE_DATADIR= `select @@datadir`
+
+--connection master
+# Generate more relay logs on slave.
+FLUSH LOGS;
+FLUSH LOGS;
+INSERT INTO t1 (c1) VALUES (2);
+
+--source include/sync_slave_io_with_master.inc
+call mtr.add_suppression("File '.*slave-relay-bin.");
+call mtr.add_suppression("Could not open log file");
+call mtr.add_suppression("Failed to open the relay log");
+call mtr.add_suppression("Failed to initialize the master info structure");
+
+# Stop slave
+--let $rpl_server_number= 2
+--source include/rpl_stop_server.inc
+
+# Delete file(s)
+--echo # Removing $remove_pattern file(s)
+--let $remove_pattern= slave-relay-bin.0*
+--remove_files_wildcard $MYSQLD_SLAVE_DATADIR $remove_pattern
+
+# Start slave
+--let $rpl_server_number= 2
+--source include/rpl_start_server.inc
+
+# Start slave must fail because of the removed file(s).
+--error ER_MASTER_INFO
+START SLAVE;
+
+# Try a second time, it must fail again.
+--error ER_MASTER_INFO
+START SLAVE;
+
+# Retrieve master executed position before reset slave.
+--let $master_exec_file= query_get_value("SHOW SLAVE STATUS", Relay_Master_Log_File, 1)
+--let $master_exec_pos= query_get_value("SHOW SLAVE STATUS", Exec_Master_Log_Pos, 1)
+
+# Reset slave.
+# Disable "Warning 1612 Being purged log ./slave-relay-bin.0* was not found"
+# because it is different on Unix and Windows systems.
+--disable_warnings
+RESET SLAVE;
+--enable_warnings
+DROP TABLE t1;
+--replace_result $master_exec_file MASTER_LOG_FILE $master_exec_pos MASTER_LOG_POS
+--eval START SLAVE UNTIL MASTER_LOG_FILE= '$master_exec_file', MASTER_LOG_POS= $master_exec_pos;
+--source include/wait_for_slave_sql_to_stop.inc
+--source include/stop_slave_io.inc
+
+# Start slave.
+--source include/start_slave.inc
+
+--connection master
+--sync_slave_with_master
+# Check consistency.
+--let $diff_tables= master:t1, slave:t1
+--source include/diff_tables.inc
+
+# Cleanup
+--connection master
+DROP TABLE t1;
+--sync_slave_with_master
+--source include/rpl_end.inc
diff --git a/mysql-test/t/binary_to_hex.test b/mysql-test/t/binary_to_hex.test
new file mode 100644
index 00000000000..8312a246d0c
--- /dev/null
+++ b/mysql-test/t/binary_to_hex.test
@@ -0,0 +1,76 @@
+# === Purpose ===
+# The purpose of this test case is to make
+# sure that the binary data in tables is printed
+# as hex when the option binary-as-hex is enabled.
+#
+# === Related bugs and/or worklogs ===
+# Bug #25340722 - PRINT BINARY DATA AS HEX IN THE MYSQL
+# CLIENT (CONTRIBUTION)
+#
+
+# Save the initial number of concurrent sessions
+--source include/count_sessions.inc
+--source include/not_embedded.inc
+
+USE test;
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+
+CREATE TABLE t1 (c1 TINYBLOB,
+ c2 BLOB,
+ c3 MEDIUMBLOB,
+ c4 LONGBLOB,
+ c5 TEXT,
+ c6 BIT(1),
+ c7 CHAR,
+ c8 VARCHAR(10),
+ c9 GEOMETRY) CHARACTER SET = binary;
+
+SHOW CREATE TABLE t1;
+
+INSERT INTO t1 VALUES ('tinyblob-text readable', 'blob-text readable',
+ 'mediumblob-text readable', 'longblob-text readable',
+ 'text readable', b'1', 'c', 'variable',
+ POINT(1, 1));
+
+CREATE TABLE t2(id int, `col1` binary(10),`col2` blob);
+
+SHOW CREATE TABLE t2;
+
+INSERT INTO t2 VALUES (1, X'AB1234', X'123ABC'), (2, X'DE1234', X'123DEF');
+
+--echo #Print the table contents when binary-as-hex option is off.
+--replace_column 6 # 9 #
+SELECT * FROM t1;
+
+--replace_column 2 # 3 #
+SELECT * FROM t2;
+
+--echo #Print the table contents after turning on the binary-as-hex option
+--echo
+--echo #Print the table contents in tab format
+--echo
+--exec $MYSQL test --binary-as-hex -e "SELECT * FROM t1; SELECT * FROM t2;"
+--echo
+--echo #Print the table contents in table format
+--echo
+--exec $MYSQL test --binary-as-hex --table -e "SELECT * FROM t1; SELECT * FROM t2 WHERE col2=0x123ABC;"
+--echo
+--echo #Print the table contents vertically
+--echo
+--exec $MYSQL test --binary-as-hex --vertical -e "SELECT * FROM t1;"
+--echo
+--echo #Print the table contents in xml format
+--echo
+--exec $MYSQL test --binary-as-hex --xml -e "SELECT * FROM t1; SELECT * FROM t2;"
+--echo
+--echo #Print the table contents in html format
+--echo
+--exec $MYSQL test --binary-as-hex --html -e "SELECT * FROM t1; SELECT * FROM t2;"
+
+#Cleanup
+DROP TABLE t1, t2;
+
+# Wait till all disconnects are completed
+ --source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/bootstrap.test b/mysql-test/t/bootstrap.test
index 405c24a6d74..2930d936830 100644
--- a/mysql-test/t/bootstrap.test
+++ b/mysql-test/t/bootstrap.test
@@ -60,4 +60,10 @@ SHOW VARIABLES LIKE 'have_innodb';
SELECT 'bug' as '' FROM INFORMATION_SCHEMA.ENGINES WHERE engine='innodb'
and SUPPORT='YES';
+#
+# MDEV-13063 Server crashes in intern_plugin_lock or assertion `plugin_ptr->ref_count == 1' fails in plugin_init
+#
+--error 1
+--exec $MYSQLD_BOOTSTRAP_CMD --myisam_recover_options=NONE
+
--echo End of 5.5 tests
diff --git a/mysql-test/t/count_distinct.test b/mysql-test/t/count_distinct.test
index 10b4ac6f0e7..a00574b6cba 100644
--- a/mysql-test/t/count_distinct.test
+++ b/mysql-test/t/count_distinct.test
@@ -107,3 +107,19 @@ create view v1 as select * from t1;
select count(distinct i) from v1;
drop table t1;
drop view v1;
+
+#
+# MDEV-12136 SELECT COUNT(DISTINCT) returns the wrong value when tmp_table_size is limited
+#
+create table t1 (user_id char(64) character set utf8);
+insert t1 values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17);
+set @@tmp_table_size = 1024;
+select count(distinct user_id) from t1;
+alter table t1 modify user_id char(128) character set utf8;
+select count(distinct user_id) from t1;
+drop table t1;
+set @@tmp_table_size = default;
+
+#
+# End of 5.5 tests
+#
diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test
index d017f847af9..07fbe4980a5 100644
--- a/mysql-test/t/derived_view.test
+++ b/mysql-test/t/derived_view.test
@@ -1881,6 +1881,56 @@ deallocate prepare stmt1;
drop table t1,t2;
+--echo #
+--echo # Bug mdev-12670: mergeable derived / view with subqueries
+--echo # subject to semi-join optimizations
+--echo # (actually this is a 5.3 bug.)
+--echo #
+
+create table t1 (a int) engine=myisam;
+insert into t1 values (5),(3),(2),(7),(2),(5),(1);
+create table t2 (b int, index idx(b)) engine=myisam;
+insert into t2 values (2),(3),(2),(1),(3),(4);
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+analyze table t1,t2;
+
+explain select a from t1 where a in (select b from t2);
+explain select * from (select a from t1 where a in (select b from t2)) t;
+create view v1 as select a from t1 where a in (select b from t2);
+explain select * from v1;
+
+drop view v1;
+drop table t1,t2;
+
+--echo #
+--echo # Bug mdev-12812: mergeable derived / view with subqueries
+--echo # NOT subject to semi-join optimizations
+--echo #
+
+CREATE TABLE t1 (c1 varchar(3)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('foo'),('foo');
+
+CREATE TABLE t2 (c2 varchar(3)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('bar'),('qux'),('foo');
+
+let $q=
+SELECT STRAIGHT_JOIN *
+ FROM ( SELECT * FROM t1 WHERE c1 IN ( SELECT c2 FROM t2 ) ) AS sq;
+
+eval $q;
+eval EXPLAIN EXTENDED $q;
+
+DROP TABLE t1, t2;
+
# The following command must be the last one the file
set optimizer_switch=@exit_optimizer_switch;
set join_cache_level=@exit_join_cache_level;
diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test
index 4162e9c67a1..80ecfea539b 100644
--- a/mysql-test/t/group_by.test
+++ b/mysql-test/t/group_by.test
@@ -1703,6 +1703,44 @@ select a as x from t1 group by x having x > 1;
select a from t1 group by a having a > 1;
drop table t1;
set sql_mode= @save_sql_mode;
+
+#
+# MDEV-7826 Server crashes in Item_subselect::enumerate_field_refs_processor
+#
+create table t1 (f1 int);
+insert into t1 values (5),(9);
+create table t2 (f2 int);
+insert into t2 values (0),(6);
+create table t3 (f3 int);
+insert into t3 values (6),(3);
+create table t4 (f4 int);
+insert into t4 values (1),(0);
+--error ER_ILLEGAL_REFERENCE
+select
+(select min(f1) from t1 where f1 in (select min(f4) from t2)) as field7,
+(select count(*) from t3 where f3 in (select max(f4) from t2 group by field7))
+from t4;
+drop table t1, t2, t3, t4;
+
+#
+# MDEV-13180 Unused left join causes server crash
+#
+create table t1 (i1 int);
+insert into t1 values (1);
+create table t2 (i int);
+insert into t2 values (2);
+select 1 from t1 left join t2 b on b.i = (select max(b.i) from t2);
+drop table t1, t2;
+
+
+#
+# MDEV-12489 The select stmt may fail due to "having clause is ambiguous" unexpected
+#
+create table t1 (c1 int, c2 int);
+create table t2 (c1 int, c2 int);
+select t1.c1 as c1, t2.c2 as c1 from t1, t2 where t1.c1 < 20 and t2.c2 > 5 group by t1.c1, t2.c2 having t1.c1 < 3;
+drop table t1, t2;
+
#
# End of MariaDB 5.5 tests
#
diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test
index 19c5f64de78..9645d8ad82a 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/join_outer.test
@@ -1801,4 +1801,86 @@ SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a
DROP TABLE t1,t2,t3;
+--echo #
+--echo # MDEV-11958: LEFT JOIN with stored routine produces incorrect result
+--echo #
+
+CREATE TABLE t (x INT);
+INSERT INTO t VALUES(1),(NULL);
+CREATE FUNCTION f (val INT, ret INT) RETURNS INT DETERMINISTIC RETURN IFNULL(val, ret);
+
+SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
+ FROM t t1 LEFT JOIN t t2
+ ON t1.x = t2.x
+ WHERE IFNULL(t2.x,0)=0;
+explain extended
+SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
+ FROM t t1 LEFT JOIN t t2
+ ON t1.x = t2.x
+ WHERE IFNULL(t2.x,0)=0;
+SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
+ FROM t t1 LEFT JOIN t t2
+ ON t1.x = t2.x
+ WHERE f(t2.x,0)=0;
+explain extended
+SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0)
+ FROM t t1 LEFT JOIN t t2
+ ON t1.x = t2.x
+ WHERE f(t2.x,0)=0;
+
+drop function f;
+drop table t;
+CREATE TABLE t1 (
+ col1 DECIMAL(33,5) NULL DEFAULT NULL,
+ col2 DECIMAL(33,5) NULL DEFAULT NULL
+);
+
+CREATE TABLE t2 (
+ col1 DECIMAL(33,5) NULL DEFAULT NULL,
+ col2 DECIMAL(33,5) NULL DEFAULT NULL,
+ col3 DECIMAL(33,5) NULL DEFAULT NULL
+);
+
+INSERT INTO t1 VALUES (2, 1.1), (2, 2.1);
+INSERT INTO t2 VALUES (3, 3.1, 4), (1, 1, NULL);
+
+DELIMITER |;
+
+CREATE FUNCTION f1 ( p_num DECIMAL(45,15), p_return DECIMAL(45,15))
+RETURNS decimal(33,5)
+LANGUAGE SQL
+DETERMINISTIC
+CONTAINS SQL
+SQL SECURITY INVOKER
+BEGIN
+ IF p_num IS NULL THEN
+ RETURN p_return;
+ ELSE
+ RETURN p_num;
+ END IF;
+END |
+
+DELIMITER ;|
+
+let $q1=
+SELECT t1.col1, t2.col1, t2.col3
+FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
+WHERE IFNULL(t2.col3,0) = 0;
+
+eval $q1;
+eval EXPLAIN EXTENDED $q1;
+
+let $q2=
+SELECT t1.col1, t2.col1, t2.col3
+FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2
+WHERE f1(t2.col3,0) = 0;
+eval $q2;
+eval EXPLAIN EXTENDED $q2;
+
+DROP FUNCTION f1;
+
+DROP TABLE t1,t2;
+
+--echo # end of 5.5 tests
+
SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index d59083d66b0..dd964c46420 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -618,3 +618,33 @@ EOF
--echo
--echo End of tests
+
+#
+# MDEV-13187 incorrect backslash parsing in clients
+#
+create table `a1\``b1` (a int);
+show tables;
+insert `a1\``b1` values (1),(2);
+show create table `a1\``b1`;
+--exec $MYSQL_DUMP --compact test
+--exec $MYSQL_DUMP test > $MYSQLTEST_VARDIR/tmp/bug.sql
+insert `a1\``b1` values (4),(5);
+--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/bug.sql
+show create table `a1\``b1`;
+select * from `a1\``b1`;
+drop table `a1\``b1`;
+
+# same with ansi_quotes
+set sql_mode=ansi_quotes;
+create table "a1\""b1" (a int);
+show tables;
+insert "a1\""b1" values (1),(2);
+show create table "a1\""b1";
+--exec $MYSQL_DUMP --compact --compatible=postgres test
+--exec $MYSQL_DUMP --compatible=postgres test > $MYSQLTEST_VARDIR/tmp/bug.sql
+insert "a1\""b1" values (4),(5);
+--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/bug.sql
+show create table "a1\""b1";
+select * from "a1\""b1";
+drop table "a1\""b1";
+set sql_mode=default;
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index 6470ede4f14..afe37926591 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -2942,11 +2942,17 @@ disconnect $x;
# Disconnect the selected connection
disconnect $y;
--echo $CURRENT_CONNECTION
+connection default;
+#
+# MDEV-13187 incorrect backslash parsing in clients
+#
+set sql_mode=no_backslash_escapes;
+select "foo\""bar";
+set sql_mode=default;
--echo End of tests
-connection default;
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/t/read_only.test b/mysql-test/t/read_only.test
index 52349747883..a0bd7b49273 100644
--- a/mysql-test/t/read_only.test
+++ b/mysql-test/t/read_only.test
@@ -80,6 +80,9 @@ insert into t3 values(1);
insert into t4 select * from t3;
+--error ER_OPTION_PREVENTS_STATEMENT
+create table t3 (a int);
+
# a non-temp table updated:
--error ER_OPTION_PREVENTS_STATEMENT
update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index a8ad3ba52a5..50d9517043a 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -5998,3 +5998,38 @@ INSERT INTO t1 VALUES ('foo','bar');
SELECT * FROM t1 WHERE f2 >= SOME ( SELECT f1 FROM t1 );
SELECT * FROM t1 WHERE f2 <= SOME ( SELECT f1 FROM t1 );
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-10146: Wrong result (or questionable result and behavior)
+--echo # with aggregate function in uncorrelated SELECT subquery
+--echo #
+CREATE TABLE t1 (f1 INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+INSERT INTO t1 VALUES (1),(2);
+
+CREATE TABLE t2 (f2 int);
+
+INSERT INTO t2 VALUES (3);
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+
+INSERT INTO t2 VALUES (4);
+
+--error ER_SUBQUERY_NO_1_ROW
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM v1;
+--error ER_SUBQUERY_NO_1_ROW
+SELECT ( SELECT MAX(f1) FROM t2 ) FROM t1;
+
+drop view v1;
+drop table t1,t2;
+
+#
+# MDEV-7828 Assertion `key_read == 0' failed in TABLE::enable_keyread with SELECT SQ and WHERE SQ
+#
+CREATE TABLE t1 (f1 INT, KEY(f1)) ENGINE=MyISAM;
+INSERT t1 VALUES (4),(8);
+CREATE TABLE t2 (f2 INT, KEY(f2)) ENGINE=MyISAM;
+INSERT t2 VALUES (6),(9);
+SELECT (SELECT MAX(sq.f2) FROM t1) FROM (SELECT * FROM t2) AS sq WHERE f2 = 2;
+drop table t1, t2;
diff --git a/mysql-test/t/subselect_mat_cost_bugs.test b/mysql-test/t/subselect_mat_cost_bugs.test
index 8205e94b203..35f2b9588fe 100644
--- a/mysql-test/t/subselect_mat_cost_bugs.test
+++ b/mysql-test/t/subselect_mat_cost_bugs.test
@@ -406,6 +406,8 @@ drop table t3, t4, t5;
--echo # LP BUG#858038 The result of a query with NOT IN subquery depends on the state of the optimizer switch
--echo #
+set @optimizer_switch_save= @@optimizer_switch;
+
create table t1 (c1 char(2) not null, c2 char(2));
create table t2 (c3 char(2), c4 char(2));
@@ -424,3 +426,100 @@ explain select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
drop table t1, t2;
+
+set optimizer_switch= @optimizer_switch_save;
+
+--echo #
+--echo # MDEV-12673: cost-based choice between materialization and in-to-exists
+--echo #
+
+CREATE TABLE t1 (
+ pk1 int, a1 varchar(3), b1 varchar(3), PRIMARY KEY (pk1), KEY(a1), KEY(b1)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,'foo','bar'),(2,'bar','foo');
+
+CREATE TABLE t2 (pk2 INT PRIMARY KEY, a2 VARCHAR(3), KEY(a2)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,'abc'),(2,'xyz'),(3,'foo');
+
+SELECT 'qux' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 );
+SELECT 'bar' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 );
+EXPLAIN
+SELECT 'bar' IN ( SELECT a1 FROM t1 INNER JOIN t2 WHERE a2 = b1 AND pk2 = 3 );
+
+DROP TABLE t1,t2;
+
+CREATE TABLE t1 (i1 INT) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1);
+
+CREATE TABLE t2 (i2 int, c2 varchar(3), KEY(i2,c2)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,'abc'),(2,'foo');
+
+CREATE TABLE t3 (pk3 int PRIMARY KEY, c3 varchar(3)) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (1,'foo'),(2,'bar');
+
+SELECT * FROM t1 WHERE i1 NOT IN (
+ SELECT i2 FROM t2 RIGHT JOIN t3 ON (c3 = c2) WHERE pk3 = i1
+);
+
+EXPLAIN
+SELECT * FROM t1 WHERE i1 NOT IN (
+ SELECT i2 FROM t2 RIGHT JOIN t3 ON (c3 = c2) WHERE pk3 = i1
+);
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # MDEV-7599: in-to-exists chosen after min/max optimization
+--echo #
+
+set @optimizer_switch_save= @@optimizer_switch;
+
+CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+
+CREATE TABLE t2 (b INT, c INT) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (1,6),(2,4), (8,9);
+
+let $q=
+SELECT * FROM t2 WHERE b != ALL (SELECT MIN(a) FROM t1, t2 WHERE t2.c = t2.b);
+
+eval $q;
+eval EXPLAIN EXTENDED $q;
+set optimizer_switch= 'materialization=off';
+eval $q;
+eval EXPLAIN EXTENDED $q;
+set optimizer_switch= @optimizer_switch_save;
+
+DROP TABLE t1,t2;
+
+CREATE TABLE t1 (f1 varchar(10)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('foo'),('bar');
+
+CREATE TABLE t2 (f2 varchar(10), key(f2)) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('baz'),('qux');
+
+CREATE TABLE t3 (f3 varchar(10)) ENGINE=MyISAM;
+INSERT INTO t3 VALUES ('abc'),('def');
+
+SELECT * FROM t1
+ WHERE f1 = ALL( SELECT MAX(t2a.f2)
+ FROM t2 AS t2a INNER JOIN t2 t2b INNER JOIN t3
+ ON (f3 = t2b.f2) );
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # MDEV-12963: min/max optimization optimizing away all tables employed
+--echo # for uncorrelated IN subquery used in a disjunct of WHERE
+--echo #
+
+create table t1 (a int, index idx(a)) engine=myisam;
+insert into t1 values (4),(7),(1),(3),(9);
+
+select * from t1 where a in (select max(a) from t1 where a < 4) or a > 5;
+explain
+select * from t1 where a in (select max(a) from t1 where a < 4) or a > 5;
+
+drop table t1;
+
+
diff --git a/mysql-test/t/subselect_nulls.test b/mysql-test/t/subselect_nulls.test
index 4b08e773b17..3e7b2189ed5 100644
--- a/mysql-test/t/subselect_nulls.test
+++ b/mysql-test/t/subselect_nulls.test
@@ -97,3 +97,9 @@ set optimizer_switch= @tmp_subselect_nulls;
drop table x1;
drop table x2;
+
+#
+# MDEV-7339 Server crashes in Item_func_trig_cond::val_int
+#
+select (select 1, 2) in (select 3, 4);
+select (select NULL, NULL) in (select 3, 4);
diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test
index 51bed53be17..acee1a67d63 100644
--- a/mysql-test/t/subselect_sj.test
+++ b/mysql-test/t/subselect_sj.test
@@ -2769,5 +2769,77 @@ WHERE ( SELECT z.country
drop table t1, t2, t3;
set optimizer_switch= @tmp_mdev6859;
+--echo #
+--echo # MDEV-12675: subquery subject to semi-join optimizations
+--echo # in ON expression of INNER JOIN
+--echo #
+
+set @tmp_mdev12675=@@optimizer_switch;
+set optimizer_switch=default;
+create table t1 (a int) engine=myisam;
+insert into t1 values (5),(3),(2),(7),(2),(5),(1);
+create table t2 (b int, index idx(b)) engine=myisam;
+insert into t2 values (2),(3),(2),(1),(3),(4);
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+insert into t2 select b+10 from t2;
+analyze table t1,t2;
+
+explain
+select a from t1, t2 where b between 1 and 2 and a in (select b from t2);
+explain
+select a from t1 join t2 on b between 1 and 2 and a in (select b from t2);
+
+drop table t1,t2;
+set optimizer_switch= @tmp_mdev12675;
+
+--echo #
+--echo # MDEV-12817: subquery NOT subject to semi-join optimizations
+--echo # in ON expression of INNER JOIN
+--echo #
+
+CREATE TABLE t1 (c1 int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+
+CREATE TABLE t2 (c2 int) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (3),(4);
+
+CREATE TABLE t3 (c3 int) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (5),(6);
+
+CREATE TABLE t4 (c4 int) ENGINE=MyISAM;
+INSERT INTO t4 VALUES (7),(8);
+
+let $q1=
+SELECT c1
+FROM t1
+LEFT JOIN
+( t2 INNER JOIN t3 ON ( 1 IN ( SELECT c4 FROM t4 ) ) )
+ON (c1 = c3);
+
+eval $q1;
+eval EXPLAIN EXTENDED $q1;
+
+let $q2=
+SELECT *
+FROM t1
+LEFT JOIN
+( ( SELECT * FROM t2 WHERE c2 IN ( SELECT c3 FROM t3 ) ) AS sq INNER JOIN t4 )
+ON (c1 = c2);
+
+--echo # mdev-12820
+eval $q2;
+eval EXPLAIN EXTENDED $q2;
+
+DROP TABLE t1,t2,t3,t4;
+
# The following command must be the last one the file
set optimizer_switch=@subselect_sj_tmp;
diff --git a/mysql-test/t/subselect_sj2_mat.test b/mysql-test/t/subselect_sj2_mat.test
index 61d9b09edff..cfb6c8c2819 100644
--- a/mysql-test/t/subselect_sj2_mat.test
+++ b/mysql-test/t/subselect_sj2_mat.test
@@ -263,3 +263,43 @@ DROP TABLE t1,t2,t3;
set join_cache_level= @save_join_cache_level;
set optimizer_switch=@save_optimizer_switch;
+--echo #
+--echo # mdev-7791: materialization of a semi-join subquery +
+--echo # RAND() in WHERE
+--echo # (materialized table is accessed last)
+--echo #
+
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='materialization=on';
+
+create table t1(i int);
+insert into t1 values (1), (2), (3), (7), (9), (10);
+create table t2(i int);
+insert into t2 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
+
+select * from t1 where (rand() < 0) and i in (select i from t2);
+explain extended
+select * from t1 where (rand() < 0) and i in (select i from t2);
+
+drop table t1,t2;
+set optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # mdev-12855: materialization of a semi-join subquery + ORDER BY
+--echo #
+
+CREATE TABLE t1 (f1 varchar(8), KEY(f1)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('qux'),('foo');
+CREATE TABLE t2 (f2 varchar(8)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('bar'),('foo'),('qux');
+
+let $q=
+SELECT f1 FROM t1
+WHERE f1 IN ( SELECT f2 FROM t2 WHERE f2 > 'bar' )
+HAVING f1 != 'foo'
+ORDER BY f1;
+
+eval $q;
+eval explain $q;
+
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test
index cd71ae5c901..90f63bea561 100644
--- a/mysql-test/t/subselect_sj_mat.test
+++ b/mysql-test/t/subselect_sj_mat.test
@@ -1944,4 +1944,211 @@ set optimizer_switch= @save_optimizer_switch;
DROP TABLE t1,t2;
+--echo #
+--echo # mdev-12838: scan of materialized of semi-join subquery in join
+--echo #
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+CREATE TABLE t1 (
+ dispatch_group varchar(32),
+ assignment_group varchar(32),
+ sys_id char(32),
+ PRIMARY KEY (sys_id),
+ KEY idx1 (dispatch_group),
+ KEY idx2 (assignment_group)
+) ENGINE=MyISAM;
+
+CREATE TABLE t2 (
+ ugroup varchar(32),
+ user varchar(32),
+ sys_id char(32),
+ PRIMARY KEY (sys_id),
+ KEY idx3 (ugroup),
+ KEY idx4 (user)
+) ENGINE=MyISAM;
+
+CREATE TABLE t3 (
+ type mediumtext,
+ sys_id char(32),
+ PRIMARY KEY (sys_id)
+) ENGINE=MyISAM;
+
+--disable_query_log
+
+INSERT INTO t1 VALUES
+('e5d9f63237232000158bbfc8bcbe5dbf','f304ae0037332000158bbfc8bcbe5d4f',
+'5398c0e037003000158bbfc8bcbe5dbb'),
+('69d9f63237232000158bbfc8bcbe5dcb','7172ea0037332000158bbfc8bcbe5db6',
+'5c188ca037003000158bbfc8bcbe5dbc'),
+('577ed708d773020058c92cf65e61037a','699708d4d773020058c92cf65e61037c',
+'623a8cd4d773020058c92cf65e6103ea'),
+('96fb652637232000158bbfc8bcbe5db4','df50316637232000158bbfc8bcbe5d23',
+'6835bd6637232000158bbfc8bcbe5d21'),
+('e1d9f63237232000158bbfc8bcbe5db8','96346e0037332000158bbfc8bcbe5daa',
+'697880e037003000158bbfc8bcbe5dcd'),
+('25d9f63237232000158bbfc8bcbe5dbe','f304ae0037332000158bbfc8bcbe5d4f',
+'6a9804e037003000158bbfc8bcbe5d09'),
+('96fb652637232000158bbfc8bcbe5db4','e08fad2637232000158bbfc8bcbe5d39',
+'6d25f96637232000158bbfc8bcbe5d79'),
+('e9d9f63237232000158bbfc8bcbe5dc6','7172ea0037332000158bbfc8bcbe5db6',
+'702880e037003000158bbfc8bcbe5d94'),
+('a5d9f63237232000158bbfc8bcbe5dca','f304ae0037332000158bbfc8bcbe5d4f',
+'7188c0e037003000158bbfc8bcbe5d75'),
+('65d9f63237232000158bbfc8bcbe5dc4','f304ae0037332000158bbfc8bcbe5d4f',
+'778880e037003000158bbfc8bcbe5d9e'),
+('a1d9f63237232000158bbfc8bcbe5dc3','7172ea0037332000158bbfc8bcbe5db6',
+'7d0840e037003000158bbfc8bcbe5dde'),
+('21d9f63237232000158bbfc8bcbe5db7','96346e0037332000158bbfc8bcbe5daa',
+'7f6880e037003000158bbfc8bcbe5da7'),
+('96fb652637232000158bbfc8bcbe5db4','ec70316637232000158bbfc8bcbe5d60',
+'8025f96637232000158bbfc8bcbe5dd0'),
+('3dd9f63237232000158bbfc8bcbe5dcc','7172ea0037332000158bbfc8bcbe5db6',
+'823880e037003000158bbfc8bcbe5ded'),
+('96fb652637232000158bbfc8bcbe5db4','7b10fd2637232000158bbfc8bcbe5d30',
+'9a353d6637232000158bbfc8bcbe5dee'),
+('75d9f63237232000158bbfc8bcbe5dd0','ebb4620037332000158bbfc8bcbe5d89',
+'a558c0e037003000158bbfc8bcbe5d36'),
+('6dd9f63237232000158bbfc8bcbe5db5','96346e0037332000158bbfc8bcbe5daa',
+'bc78cca037003000158bbfc8bcbe5d74'),
+('add9f63237232000158bbfc8bcbe5dc7','7172ea0037332000158bbfc8bcbe5db6',
+'c53804a037003000158bbfc8bcbe5db8'),
+('fdd9f63237232000158bbfc8bcbe5dcd','7864ae0037332000158bbfc8bcbe5db8',
+'cfe740e037003000158bbfc8bcbe5de8'),
+('96fb652637232000158bbfc8bcbe5db4','3120fd2637232000158bbfc8bcbe5d42',
+'e2257d6637232000158bbfc8bcbe5ded'),
+('3c3725e237232000158bbfc8bcbe5da1','96346e0037332000158bbfc8bcbe5daa',
+'ee78c0e037003000158bbfc8bcbe5db5'),
+('a9d9f63237232000158bbfc8bcbe5dc0','7172ea0037332000158bbfc8bcbe5db6',
+'f00888a037003000158bbfc8bcbe5dd3'),
+('29d9f63237232000158bbfc8bcbe5db9','7172ea0037332000158bbfc8bcbe5db6',
+'fa0880e037003000158bbfc8bcbe5d70'),
+('b1d9f63237232000158bbfc8bcbe5dcf','ebb4620037332000158bbfc8bcbe5d89',
+'fa48c0e037003000158bbfc8bcbe5d28');
+
+INSERT INTO t2 VALUES
+('17801ac21b13200050fdfbcd2c0713e8','8e826bf03710200044e0bfc8bcbe5d86',
+'14c19a061b13200050fdfbcd2c07134b'),
+('577ed708d773020058c92cf65e61037a','931644d4d773020058c92cf65e61034c',
+'339888d4d773020058c92cf65e6103aa'),
+('df50316637232000158bbfc8bcbe5d23','92826bf03710200044e0bfc8bcbe5da9',
+'3682f56637232000158bbfc8bcbe5d44'),
+('b4f342b237232000158bbfc8bcbe5def','86826bf03710200044e0bfc8bcbe5d70',
+'38e4c2b237232000158bbfc8bcbe5dea'),
+('7b10fd2637232000158bbfc8bcbe5d30','8a826bf03710200044e0bfc8bcbe5d72',
+'4442b56637232000158bbfc8bcbe5d43'),
+('3120fd2637232000158bbfc8bcbe5d42','82826bf03710200044e0bfc8bcbe5d89',
+'49d2396637232000158bbfc8bcbe5d12'),
+('96fb652637232000158bbfc8bcbe5db4','86826bf03710200044e0bfc8bcbe5d79',
+'4e3ca52637232000158bbfc8bcbe5d3e'),
+('17801ac21b13200050fdfbcd2c0713e8','824fd523bf4320007a6d257b3f073963',
+'58c19a061b13200050fdfbcd2c07134e'),
+('699708d4d773020058c92cf65e61037c','901784d4d773020058c92cf65e6103da',
+'5bc708d4d773020058c92cf65e6103d5'),
+('75d9f63237232000158bbfc8bcbe5dd0','86826bf03710200044e0bfc8bcbe5d79',
+'6b52cb7237232000158bbfc8bcbe5ded'),
+('f253da061b13200050fdfbcd2c0713ab','8e826bf03710200044e0bfc8bcbe5d86',
+'81045e061b13200050fdfbcd2c071373'),
+('7b10fd2637232000158bbfc8bcbe5d30','8e826bf03710200044e0bfc8bcbe5d74',
+'8c42b56637232000158bbfc8bcbe5d3f'),
+('e5d9f63237232000158bbfc8bcbe5dbf','7a826bf03710200044e0bfc8bcbe5df5',
+'a7acfe3237232000158bbfc8bcbe5d78'),
+('8a5055c9c61122780043563ef53438e3','9ee1b13dc6112271007f9d0efdb69cd0',
+'a9aff553c6112276015a8006174bee21'),
+('8a4dde73c6112278017a6a4baf547aa7','9ee1b13dc6112271007f9d0efdb69cd0',
+'a9b2f526c61122760003ae07349d294f'),
+('aaccc971c0a8001500fe1ff4302de101','9ee1b13dc6112271007f9d0efdb69cd0',
+'aacceed3c0a80015009069bba51c4e21'),
+('65d9f63237232000158bbfc8bcbe5dc4','8d56406a0a0a0a6b004070b354aada28',
+'ac1bfa3237232000158bbfc8bcbe5dc3'),
+('b85d44954a3623120004689b2d5dd60a','97000fcc0a0a0a6e0104ca999f619e5b',
+'b77bc032cbb00200d71cb9c0c24c9c45'),
+('220f8e71c61122840197e57c33464f70','8d56406a0a0a0a6b004070b354aada28',
+'b9b74f080a0a0b343ba75b95bdb27056'),
+('e08fad2637232000158bbfc8bcbe5d39','82826bf03710200044e0bfc8bcbe5d80',
+'be02756637232000158bbfc8bcbe5d8b'),
+('ebb4620037332000158bbfc8bcbe5d89','7682abf03710200044e0bfc8bcbe5d25',
+'c0122f4437732000158bbfc8bcbe5d7d'),
+('96fb652637232000158bbfc8bcbe5db4','7a82abf03710200044e0bfc8bcbe5d27',
+'c23ca52637232000158bbfc8bcbe5d3b'),
+('22122b37c611228400f9ff91c857581d','9ee1b13dc6112271007f9d0efdb69cd0',
+'d23bbf5dac14641866947512bde59dc5'),
+('db53a9290a0a0a650091abebccf833c6','9ee1b13dc6112271007f9d0efdb69cd0',
+'db54a0f60a0a0a65002c54dcb72b4f41'),
+('e08fad2637232000158bbfc8bcbe5d39','8e826bf03710200044e0bfc8bcbe5d86',
+'f602756637232000158bbfc8bcbe5d88'),
+('699708d4d773020058c92cf65e61037c','8d59d601d7b3020058c92cf65e6103c2',
+'f718a241d7b3020058c92cf65e610332'),
+('df50316637232000158bbfc8bcbe5d23','9e826bf03710200044e0bfc8bcbe5da6',
+'fe82f56637232000158bbfc8bcbe5d4e'),
+('f972d6061b13200050fdfbcd2c0713e5','780395f0df031100a9e78b6c3df2631f',
+'ff4395f0df031100a9e78b6c3df2637e');
+
+INSERT INTO t3 VALUES
+('87245e061b13200050fdfbcd2c0713cc','7172ea0037332000158bbfc8bcbe5db6'),
+('74af88c6c611227d0066386e74dc853d','74ad1ff3c611227d01d25feac2af603f'),
+('59e22fb137032000158bbfc8bcbe5d52','75d9f63237232000158bbfc8bcbe5dd0'),
+('98906fb137032000158bbfc8bcbe5d65','781da52637232000158bbfc8bcbe5db8'),
+('87245e061b13200050fdfbcd2c0713cc','7864ae0037332000158bbfc8bcbe5db8'),
+('87245e061b13200050fdfbcd2c0713cc','7b10fd2637232000158bbfc8bcbe5d30'),
+('59e22fb137032000158bbfc8bcbe5d52','81a880e037003000158bbfc8bcbe5df8'),
+('74af88c6c611227d0066386e74dc853d','8a4cb6d4c61122780043b1642efcd52b'),
+('1cb8ab9bff500200158bffffffffff62','8a4dde73c6112278017a6a4baf547aa7'),
+('1cb8ab9bff500200158bffffffffff62','8a5055c9c61122780043563ef53438e3'),
+('87245e061b13200050fdfbcd2c0713cc','96346e0037332000158bbfc8bcbe5daa'),
+('59e22fb137032000158bbfc8bcbe5d52','96fb652637232000158bbfc8bcbe5db4'),
+('59e22fb137032000158bbfc8bcbe5d52','a1d9f63237232000158bbfc8bcbe5dc3'),
+('59e22fb137032000158bbfc8bcbe5d52','a5d9f63237232000158bbfc8bcbe5dca'),
+('1cb8ab9bff500200158bffffffffff62','a715cd759f2002002920bde8132e7018'),
+('59e22fb137032000158bbfc8bcbe5d52','a9d9f63237232000158bbfc8bcbe5dc0'),
+('74af88c6c611227d0066386e74dc853d','aacb62e2c0a80015007f67f752c2b12c'),
+('74af88c6c611227d0066386e74dc853d','aaccc971c0a8001500fe1ff4302de101'),
+('59e22fb137032000158bbfc8bcbe5d52','add9f63237232000158bbfc8bcbe5dbb'),
+('59e22fb137032000158bbfc8bcbe5d52','add9f63237232000158bbfc8bcbe5dc7'),
+('59e22fb137032000158bbfc8bcbe5d52','b1d9f63237232000158bbfc8bcbe5dcf'),
+('1cb8ab9bff500200158bffffffffff62','b85d44954a3623120004689b2d5dd60a'),
+('1cb8ab9bff500200158bffffffffff62','b97e89b94a36231201676b73322a0311'),
+('1cb8ab9bff500200158bffffffffff62','cfcbad03d711110050f5edcb9e61038f'),
+('1cb8ab9bff500200158bffffffffff62','d625dccec0a8016700a222a0f7900d06'),
+('1cb8ab9bff500200158bffffffffff62','db53580b0a0a0a6501aa37c294a2ba6b'),
+('1cb8ab9bff500200158bffffffffff62','db53a9290a0a0a650091abebccf833c6'),
+('1cb8ab9bff500200158bffffffffff62','dc0db135c332010016194ffe5bba8f23'),
+('87245e061b13200050fdfbcd2c0713cc','df50316637232000158bbfc8bcbe5d23'),
+('87245e061b13200050fdfbcd2c0713cc','e08fad2637232000158bbfc8bcbe5d39'),
+('59e22fb137032000158bbfc8bcbe5d52','e1d9f63237232000158bbfc8bcbe5db8'),
+('59e22fb137032000158bbfc8bcbe5d52','e5d9f63237232000158bbfc8bcbe5db4'),
+('59e22fb137032000158bbfc8bcbe5d52','e5d9f63237232000158bbfc8bcbe5dbf'),
+('59e22fb137032000158bbfc8bcbe5d52','e9d9f63237232000158bbfc8bcbe5dba'),
+('59e22fb137032000158bbfc8bcbe5d52','e9d9f63237232000158bbfc8bcbe5dc6'),
+('87245e061b13200050fdfbcd2c0713cc','ebb4620037332000158bbfc8bcbe5d89'),
+('87245e061b13200050fdfbcd2c0713cc','ec70316637232000158bbfc8bcbe5d60'),
+('87245e061b13200050fdfbcd2c0713cc','f253da061b13200050fdfbcd2c0713ab'),
+('87245e061b13200050fdfbcd2c0713cc','f304ae0037332000158bbfc8bcbe5d4f'),
+('98906fb137032000158bbfc8bcbe5d65','f972d6061b13200050fdfbcd2c0713e5'),
+('59e22fb137032000158bbfc8bcbe5d52','fdd9f63237232000158bbfc8bcbe5dcd');
+
+--enable_query_log
+
+let $q=
+SELECT t1.assignment_group
+FROM t1, t3
+WHERE t1.assignment_group = t3.sys_id AND
+ t1.dispatch_group IN
+ (SELECT t2.ugroup
+ FROM t2, t3 t3_i
+ WHERE t2.ugroup = t3_i.sys_id AND
+ t3_i.type LIKE '59e22fb137032000158bbfc8bcbe5d52' AND
+ t2.user = '86826bf03710200044e0bfc8bcbe5d79');
+
+set optimizer_switch='materialization=off';
+eval explain $q;
+eval $q;
+
+set optimizer_switch='materialization=on';
+eval explain $q;
+eval $q;
+
+DROP TABLE t1,t2,t3;
+set optimizer_switch=@save_optimizer_switch;
+
--echo # End of 5.5 tests
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
index f4dc6a5d449..4a3c19b49ab 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/t/union.test
@@ -1370,3 +1370,18 @@ order by d;
drop table t1;
--echo End of 5.0 tests
+
+#
+# Bug #24595639: INCORRECT BEHAVIOR IN QUERY WITH UNION AND GROUP BY
+#
+create table t1 (a int, b int);
+insert into t1 values (1,1),(2,2),(3,3);
+create table t2 (c varchar(30), d varchar(30));
+insert into t1 values ('1','1'),('2','2'),('4','4');
+create table t3 (e int, f int);
+insert into t3 values (1,1),(2,2),(31,31),(32,32);
+select e,f, (e , f) in (select e,b from t1 union select c,d from t2) as sub from t3;
+select avg(f), (e , f) in (select e,b from t1 union select c,d from t2) as sub from t3 group by sub;
+drop table t1,t2,t3;
+
+--echo End of 5.5 tests
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index aece2000cd4..659327eebb1 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -5565,6 +5565,22 @@ select *
drop view v1;
drop table t1,t2,t3;
+--echo #
+--echo # MDEV-11240: Server crashes in check_view_single_update or
+--echo # Assertion `derived->table' failed in mysql_derived_merge_for_insert
+--echo #
+
+CREATE TABLE t3 (a INT);
+CREATE ALGORITHM = MERGE VIEW v1 AS SELECT t2.a FROM t3 AS t1, t3 AS t2;
+CREATE ALGORITHM = MERGE VIEW v2 AS SELECT * FROM v1;
+PREPARE stmt FROM 'REPLACE INTO v2 SELECT a FROM t3';
+--error ER_VIEW_NO_INSERT_FIELD_LIST
+EXECUTE stmt;
+--error ER_VIEW_NO_INSERT_FIELD_LIST
+EXECUTE stmt;
+drop view v1,v2;
+drop table t3;
+
--echo # -----------------------------------------------------------------
--echo # -- End of 5.5 tests.
--echo # -----------------------------------------------------------------
diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c
index 99a9035c0c2..9131a2549e0 100644
--- a/mysys/my_fopen.c
+++ b/mysys/my_fopen.c
@@ -143,7 +143,7 @@ static int no_close(void *cookie __attribute__((unused)))
/*
A hack around a race condition in the implementation of freopen.
- The race condition steams from the fact that the current fd of
+ The race condition stems from the fact that the current fd of
the stream is closed before its number is used to duplicate the
new file descriptor. This defeats the desired atomicity of the
close and duplicate of dup2().
diff --git a/mysys/my_rdtsc.c b/mysys/my_rdtsc.c
index 028c7f810d4..ad11e8c6a6c 100644
--- a/mysys/my_rdtsc.c
+++ b/mysys/my_rdtsc.c
@@ -129,6 +129,31 @@ ulonglong my_timer_cycles_il_x86_64();
clock_gettime(CLOCK_SGI_CYCLE) for Irix platforms,
or on read_real_time for aix platforms. There is
nothing for Alpha platforms, they would be tricky.
+
+ On the platforms that do not have a CYCLE timer,
+ "wait" events are initialized to use NANOSECOND instead of CYCLE
+ during performance_schema initialization (at the server startup).
+
+ Linux performance monitor (see "man perf_event_open") can
+ provide cycle counter on the platforms that do not have
+ other kinds of cycle counters. But we don't use it so far.
+
+ ARM notes
+ ---------
+ During tests on ARMv7 Debian, perf_even_open() based cycle counter provided
+ too low frequency with too high overhead:
+ MariaDB [performance_schema]> SELECT * FROM performance_timers;
+ +-------------+-----------------+------------------+----------------+
+ | TIMER_NAME | TIMER_FREQUENCY | TIMER_RESOLUTION | TIMER_OVERHEAD |
+ +-------------+-----------------+------------------+----------------+
+ | CYCLE | 689368159 | 1 | 970 |
+ | NANOSECOND | 1000000000 | 1 | 308 |
+ | MICROSECOND | 1000000 | 1 | 417 |
+ | MILLISECOND | 1000 | 1000 | 407 |
+ | TICK | 127 | 1 | 612 |
+ +-------------+-----------------+------------------+----------------+
+ Therefore, it was decided not to use perf_even_open() on ARM
+ (i.e. go without CYCLE and have "wait" events use NANOSECOND by default).
*/
ulonglong my_timer_cycles(void)
diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c
index ed35fff41e9..12959f1f24a 100644
--- a/mysys/my_symlink.c
+++ b/mysys/my_symlink.c
@@ -197,7 +197,7 @@ int my_realpath(char *to, const char *filename, myf MyFlags)
const char *my_open_parent_dir_nosymlinks(const char *pathname, int *pdfd)
{
- char buf[PATH_MAX+1];
+ char buf[FN_REFLEN + 1];
char *s= buf, *e= buf+1, *end= strnmov(buf, pathname, sizeof(buf));
int fd, dfd= -1;
diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h
index 661c4c184f1..1004bf8889f 100644
--- a/mysys/mysys_priv.h
+++ b/mysys/mysys_priv.h
@@ -107,12 +107,21 @@ const char *my_open_parent_dir_nosymlinks(const char *pathname, int *pdfd);
res= AT; \
if (dfd >= 0) close(dfd); \
return res;
-#elif defined(HAVE_REALPATH)
+#elif defined(HAVE_REALPATH) && defined(PATH_MAX)
#define NOSYMLINK_FUNCTION_BODY(AT,NOAT) \
char buf[PATH_MAX+1]; \
if (realpath(pathname, buf) == NULL) return -1; \
if (strcmp(pathname, buf)) { errno= ENOTDIR; return -1; } \
return NOAT;
+#elif defined(HAVE_REALPATH)
+#define NOSYMLINK_FUNCTION_BODY(AT,NOAT) \
+ char *buf= realpath(pathname, NULL); \
+ int res; \
+ if (buf == NULL) return -1; \
+ if (strcmp(pathname, buf)) { errno= ENOTDIR; res= -1; } \
+ else res= NOAT; \
+ free(buf); \
+ return res;
#else
#define NOSYMLINK_FUNCTION_BODY(AT,NOAT) \
return NOAT;
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c
index 402520990b6..ae715c04621 100644
--- a/mysys/stacktrace.c
+++ b/mysys/stacktrace.c
@@ -744,7 +744,7 @@ void my_safe_print_str(const char *val, int len)
size_t my_write_stderr(const void *buf, size_t count)
{
- return (size_t) write(STDERR_FILENO, buf, count);
+ return (size_t) write(fileno(stderr), buf, count);
}
diff --git a/plugin/semisync/semisync_master.cc b/plugin/semisync/semisync_master.cc
index 3c22bcb94f2..16e6b091ca8 100644
--- a/plugin/semisync/semisync_master.cc
+++ b/plugin/semisync/semisync_master.cc
@@ -552,7 +552,7 @@ int ReplSemiSyncMaster::reportReplyBinlog(uint32 server_id,
if (need_copy_send_pos)
{
- strcpy(reply_file_name_, log_file_name);
+ strmake_buf(reply_file_name_, log_file_name);
reply_file_pos_ = log_file_pos;
reply_file_name_inited_ = true;
@@ -659,7 +659,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
if (cmp <= 0)
{
/* This thd has a lower position, let's update the minimum info. */
- strcpy(wait_file_name_, trx_wait_binlog_name);
+ strmake_buf(wait_file_name_, trx_wait_binlog_name);
wait_file_pos_ = trx_wait_binlog_pos;
rpl_semi_sync_master_wait_pos_backtraverse++;
@@ -670,7 +670,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
}
else
{
- strcpy(wait_file_name_, trx_wait_binlog_name);
+ strmake_buf(wait_file_name_, trx_wait_binlog_name);
wait_file_pos_ = trx_wait_binlog_pos;
wait_file_name_inited_ = true;
diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
index da4f0d9b3bb..0fa74c93d2d 100644
--- a/scripts/CMakeLists.txt
+++ b/scripts/CMakeLists.txt
@@ -1,4 +1,5 @@
-# Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2017, Oracle and/or its affiliates.
+# Copyright (c) 2011, 2017, MariaDB Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -95,6 +96,13 @@ IF(CMAKE_GENERATOR MATCHES "Makefiles")
ENDFOREACH()
ENDIF()
+
+IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+ SET (PERL_PATH "/usr/local/bin/perl")
+ELSE()
+ SET (PERL_PATH "/usr/bin/perl")
+ENDIF()
+
IF(UNIX)
# FIND_PROC and CHECK_PID are used by mysqld_safe
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
@@ -407,4 +415,3 @@ IF(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_FLAGS MATCHES "-static")
COMPONENT Development)
ENDIF()
ENDIF()
-
diff --git a/scripts/dheadgen.pl b/scripts/dheadgen.pl
index c42bd49b32e..69ece2e7c81 100755..100644
--- a/scripts/dheadgen.pl
+++ b/scripts/dheadgen.pl
@@ -1,10 +1,4 @@
-#!/usr/bin/perl -w
-
-#
-# Copyright (c) 2008, 2009 Sun Microsystems, Inc.
-# Use is subject to license terms.
-#
-
+# Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
diff --git a/scripts/mysql_config.pl.in b/scripts/mysql_config.pl.in
index d7b36ec9b09..f2c27bc0b84 100644
--- a/scripts/mysql_config.pl.in
+++ b/scripts/mysql_config.pl.in
@@ -1,7 +1,7 @@
-#!/usr/bin/perl
+#!@PERL_PATH@
# -*- cperl -*-
#
-# Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/scripts/mysql_convert_table_format.sh b/scripts/mysql_convert_table_format.sh
index 5f3e093d2b9..5042a742d55 100644
--- a/scripts/mysql_convert_table_format.sh
+++ b/scripts/mysql_convert_table_format.sh
@@ -1,6 +1,5 @@
-#!/usr/bin/perl
-# Copyright (c) 2000-2002, 2006, 2007 MySQL AB, 2009 Sun Microsystems, Inc.
-# Use is subject to license terms.
+#!@PERL_PATH@
+# Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/scripts/mysql_find_rows.sh b/scripts/mysql_find_rows.sh
index 48c4915ae00..20c3e2c3106 100644
--- a/scripts/mysql_find_rows.sh
+++ b/scripts/mysql_find_rows.sh
@@ -1,6 +1,5 @@
-#!/usr/bin/perl
-# Copyright (c) 2000, 2004, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
-# Use is subject to license terms.
+#!@PERL_PATH@
+# Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/scripts/mysql_fix_extensions.sh b/scripts/mysql_fix_extensions.sh
index 2a50bfe22bb..7aa07209d4d 100644
--- a/scripts/mysql_fix_extensions.sh
+++ b/scripts/mysql_fix_extensions.sh
@@ -1,7 +1,6 @@
-#!/usr/bin/perl
+#!@PERL_PATH@
-# Copyright (c) 2001 MySQL AB, 2009 Sun Microsystems, Inc.
-# Use is subject to license terms.
+# Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
diff --git a/scripts/mysql_install_db.pl.in b/scripts/mysql_install_db.pl.in
index dcb7d7736e0..c6714f66bff 100644
--- a/scripts/mysql_install_db.pl.in
+++ b/scripts/mysql_install_db.pl.in
@@ -1,7 +1,7 @@
-#!/usr/bin/perl
+#!@PERL_PATH@
# -*- cperl -*-
#
-# Copyright (c) 2007, 2013, Oracle and/or its affiliates.
+# Copyright (c) 2007, 2017, Oracle and/or its affiliates.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/scripts/mysql_secure_installation.pl.in b/scripts/mysql_secure_installation.pl.in
index 32331c3d601..01d34c4af4d 100644
--- a/scripts/mysql_secure_installation.pl.in
+++ b/scripts/mysql_secure_installation.pl.in
@@ -1,7 +1,7 @@
-#!/usr/bin/perl
+#!@PERL_PATH@
# -*- cperl -*-
#
-# Copyright (c) 2007, 2012, Oracle and/or its affiliates.
+# Copyright (c) 2007, 2017, Oracle and/or its affiliates.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -388,6 +388,3 @@ Thanks for using MySQL!
HERE
-
-
-
diff --git a/scripts/mysql_setpermission.sh b/scripts/mysql_setpermission.sh
index 48f0b09b566..4416551eadd 100644
--- a/scripts/mysql_setpermission.sh
+++ b/scripts/mysql_setpermission.sh
@@ -1,8 +1,7 @@
-#!/usr/bin/perl
+#!@PERL_PATH@
## Emacs, this is -*- perl -*- mode? :-)
-# Copyright (c) 2000, 2007 MySQL AB, 2009 Sun Microsystems, Inc.
-# Use is subject to license terms.
+# Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
diff --git a/scripts/mysql_zap.sh b/scripts/mysql_zap.sh
index a9c3e7a7f5a..725a4e247a4 100644
--- a/scripts/mysql_zap.sh
+++ b/scripts/mysql_zap.sh
@@ -1,6 +1,5 @@
-#!/usr/bin/perl
-# Copyright (c) 2000-2002, 2004, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
-# Use is subject to license terms.
+#!@PERL_PATH@
+# Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/scripts/mysqlaccess.sh b/scripts/mysqlaccess.sh
index 1d01c84735a..431c70812cb 100644
--- a/scripts/mysqlaccess.sh
+++ b/scripts/mysqlaccess.sh
@@ -1,6 +1,6 @@
-#!/usr/bin/perl
+#!@PERL_PATH@
-# Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
@@ -477,15 +477,22 @@ MySQLaccess::Report::Print_Header();
# *****************************
# Read configuration-file
MySQLaccess::Debug::Print(1, "Reading configuration file...");
- if (-f "./$script_conf") {
- require "./$script_conf";
- }
- elsif (-f "@sysconfdir@/$script_conf") {
+ if (-f "@sysconfdir@/$script_conf") {
+ print "Configuration file '$script_conf' is found in '@sysconfdir@/'\n";
require "@sysconfdir@/$script_conf";
}
elsif (-f "/etc/$script_conf") {
+ print "Configuration file '$script_conf' is found in '/etc/'\n";
require "/etc/$script_conf";
}
+ elsif (-f "./$script_conf") {
+ print "\nERROR! Configuration file '$script_conf' is found in the current ";
+ print "directory.\nThe permissible locations for this file are either ";
+ print "@sysconfdir@/ or /etc/\n";
+ print "Please move it to one of these locations and retry.\n\n";
+ exit 0;
+ }
+
# ****************************
# Read in all parameters
diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh
index 66b8c0d8e21..e4a23440be6 100644
--- a/scripts/mysqld_multi.sh
+++ b/scripts/mysqld_multi.sh
@@ -1,23 +1,7 @@
-#!/usr/bin/perl
-# Copyright (c) 2000, 2010, Oracle and/or its affiliates.
-# Copyright (c) 2000-2011 Monty Program Ab, Jani Tolonen
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Library General Public
-# License as published by the Free Software Foundation; version 2
-# of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Library General Public License for more details.
-#
-# You should have received a copy of the GNU Library General Public
-# License along with this library; if not, write to the Free
-# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
-# MA 02110-1301, USA
+#!@PERL_PATH@
-# Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2000, 2017, Oracle and/or its affiliates.
+# Copyright (c) 2010, 2017, MariaDB Corporation
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
diff --git a/scripts/mysqldumpslow.sh b/scripts/mysqldumpslow.sh
index c04ffad7457..a7d064904a5 100644
--- a/scripts/mysqldumpslow.sh
+++ b/scripts/mysqldumpslow.sh
@@ -1,7 +1,6 @@
-#!/usr/bin/perl
+#!@PERL_PATH@
-# Copyright (c) 2000-2002, 2005-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc.
-# Use is subject to license terms.
+# Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh
index b6ff7e1b28d..d6184d9ef10 100644
--- a/scripts/mysqlhotcopy.sh
+++ b/scripts/mysqlhotcopy.sh
@@ -1,6 +1,6 @@
-#!/usr/bin/perl
+#!@PERL_PATH@
-# Copyright (c) 2000, 2010, Oracle and/or its affiliates
+# Copyright (c) 2000, 2017, Oracle and/or its affiliates.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 19e1ce67b84..99e61520ddb 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -640,7 +640,7 @@ int ha_partition::create(const char *name, TABLE *table_arg,
int ha_partition::drop_partitions(const char *path)
{
List_iterator<partition_element> part_it(m_part_info->partitions);
- char part_name_buff[FN_REFLEN];
+ char part_name_buff[FN_REFLEN + 1];
uint num_parts= m_part_info->partitions.elements;
uint num_subparts= m_part_info->num_subparts;
uint i= 0;
@@ -673,9 +673,11 @@ int ha_partition::drop_partitions(const char *path)
{
partition_element *sub_elem= sub_it++;
part= i * num_subparts + j;
- create_subpartition_name(part_name_buff, path,
- part_elem->partition_name,
- sub_elem->partition_name, name_variant);
+ if ((ret_error= create_subpartition_name(part_name_buff,
+ sizeof(part_name_buff), path,
+ part_elem->partition_name,
+ sub_elem->partition_name, name_variant)))
+ error= ret_error;
file= m_file[part];
DBUG_PRINT("info", ("Drop subpartition %s", part_name_buff));
if ((ret_error= file->ha_delete_table(part_name_buff)))
@@ -686,15 +688,19 @@ int ha_partition::drop_partitions(const char *path)
}
else
{
- create_partition_name(part_name_buff, path,
- part_elem->partition_name, name_variant,
- TRUE);
- file= m_file[i];
- DBUG_PRINT("info", ("Drop partition %s", part_name_buff));
- if ((ret_error= file->ha_delete_table(part_name_buff)))
+ if ((ret_error= create_partition_name(part_name_buff,
+ sizeof(part_name_buff), path,
+ part_elem->partition_name, name_variant, TRUE)))
error= ret_error;
- if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
- error= 1;
+ else
+ {
+ file= m_file[i];
+ DBUG_PRINT("info", ("Drop partition %s", part_name_buff));
+ if ((ret_error= file->ha_delete_table(part_name_buff)))
+ error= ret_error;
+ if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
+ error= 1;
+ }
}
if (part_elem->part_state == PART_IS_CHANGED)
part_elem->part_state= PART_NORMAL;
@@ -730,8 +736,8 @@ int ha_partition::rename_partitions(const char *path)
{
List_iterator<partition_element> part_it(m_part_info->partitions);
List_iterator<partition_element> temp_it(m_part_info->temp_partitions);
- char part_name_buff[FN_REFLEN];
- char norm_name_buff[FN_REFLEN];
+ char part_name_buff[FN_REFLEN + 1];
+ char norm_name_buff[FN_REFLEN + 1];
uint num_parts= m_part_info->partitions.elements;
uint part_count= 0;
uint num_subparts= m_part_info->num_subparts;
@@ -773,10 +779,11 @@ int ha_partition::rename_partitions(const char *path)
{
sub_elem= sub_it++;
file= m_reorged_file[part_count++];
- create_subpartition_name(norm_name_buff, path,
- part_elem->partition_name,
- sub_elem->partition_name,
- NORMAL_PART_NAME);
+ if ((ret_error= create_subpartition_name(norm_name_buff,
+ sizeof(norm_name_buff), path,
+ part_elem->partition_name,
+ sub_elem->partition_name, NORMAL_PART_NAME)))
+ error= ret_error;
DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff));
if ((ret_error= file->ha_delete_table(norm_name_buff)))
error= ret_error;
@@ -789,16 +796,20 @@ int ha_partition::rename_partitions(const char *path)
else
{
file= m_reorged_file[part_count++];
- create_partition_name(norm_name_buff, path,
- part_elem->partition_name, NORMAL_PART_NAME,
- TRUE);
- DBUG_PRINT("info", ("Delete partition %s", norm_name_buff));
- if ((ret_error= file->ha_delete_table(norm_name_buff)))
+ if ((ret_error= create_partition_name(norm_name_buff,
+ sizeof(norm_name_buff), path,
+ part_elem->partition_name, NORMAL_PART_NAME, TRUE)))
error= ret_error;
- else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
- error= 1;
else
- part_elem->log_entry= NULL; /* Indicate success */
+ {
+ DBUG_PRINT("info", ("Delete partition %s", norm_name_buff));
+ if ((ret_error= file->ha_delete_table(norm_name_buff)))
+ error= ret_error;
+ else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
+ error= 1;
+ else
+ part_elem->log_entry= NULL; /* Indicate success */
+ }
}
} while (++i < temp_partitions);
(void) sync_ddl_log();
@@ -841,10 +852,11 @@ int ha_partition::rename_partitions(const char *path)
{
sub_elem= sub_it++;
part= i * num_subparts + j;
- create_subpartition_name(norm_name_buff, path,
- part_elem->partition_name,
- sub_elem->partition_name,
- NORMAL_PART_NAME);
+ if ((ret_error= create_subpartition_name(norm_name_buff,
+ sizeof(norm_name_buff), path,
+ part_elem->partition_name,
+ sub_elem->partition_name, NORMAL_PART_NAME)))
+ error= ret_error;
if (part_elem->part_state == PART_IS_CHANGED)
{
file= m_reorged_file[part_count++];
@@ -856,10 +868,11 @@ int ha_partition::rename_partitions(const char *path)
(void) sync_ddl_log();
}
file= m_new_file[part];
- create_subpartition_name(part_name_buff, path,
- part_elem->partition_name,
- sub_elem->partition_name,
- TEMP_PART_NAME);
+ if ((ret_error= create_subpartition_name(part_name_buff,
+ sizeof(part_name_buff), path,
+ part_elem->partition_name,
+ sub_elem->partition_name, TEMP_PART_NAME)))
+ error= ret_error;
DBUG_PRINT("info", ("Rename subpartition from %s to %s",
part_name_buff, norm_name_buff));
if ((ret_error= file->ha_rename_table(part_name_buff,
@@ -873,32 +886,36 @@ int ha_partition::rename_partitions(const char *path)
}
else
{
- create_partition_name(norm_name_buff, path,
- part_elem->partition_name, NORMAL_PART_NAME,
- TRUE);
- if (part_elem->part_state == PART_IS_CHANGED)
+ if ((ret_error= create_partition_name(norm_name_buff,
+ sizeof(norm_name_buff), path,
+ part_elem->partition_name, NORMAL_PART_NAME, TRUE)) ||
+ (ret_error= create_partition_name(part_name_buff,
+ sizeof(part_name_buff), path,
+ part_elem->partition_name, TEMP_PART_NAME, TRUE)))
+ error= ret_error;
+ else
{
- file= m_reorged_file[part_count++];
- DBUG_PRINT("info", ("Delete partition %s", norm_name_buff));
- if ((ret_error= file->ha_delete_table(norm_name_buff)))
+ if (part_elem->part_state == PART_IS_CHANGED)
+ {
+ file= m_reorged_file[part_count++];
+ DBUG_PRINT("info", ("Delete partition %s", norm_name_buff));
+ if ((ret_error= file->ha_delete_table(norm_name_buff)))
+ error= ret_error;
+ else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
+ error= 1;
+ (void) sync_ddl_log();
+ }
+ file= m_new_file[i];
+ DBUG_PRINT("info", ("Rename partition from %s to %s",
+ part_name_buff, norm_name_buff));
+ if ((ret_error= file->ha_rename_table(part_name_buff,
+ norm_name_buff)))
error= ret_error;
else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
error= 1;
- (void) sync_ddl_log();
+ else
+ part_elem->log_entry= NULL;
}
- file= m_new_file[i];
- create_partition_name(part_name_buff, path,
- part_elem->partition_name, TEMP_PART_NAME,
- TRUE);
- DBUG_PRINT("info", ("Rename partition from %s to %s",
- part_name_buff, norm_name_buff));
- if ((ret_error= file->ha_rename_table(part_name_buff,
- norm_name_buff)))
- error= ret_error;
- else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
- error= 1;
- else
- part_elem->log_entry= NULL;
}
}
} while (++i < num_parts);
@@ -1494,7 +1511,7 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
{
List_iterator<partition_element> part_it(m_part_info->partitions);
List_iterator <partition_element> t_it(m_part_info->temp_partitions);
- char part_name_buff[FN_REFLEN];
+ char part_name_buff[FN_REFLEN + 1];
uint num_parts= m_part_info->partitions.elements;
uint num_subparts= m_part_info->num_subparts;
uint i= 0;
@@ -1704,10 +1721,14 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
do
{
partition_element *sub_elem= sub_it++;
- create_subpartition_name(part_name_buff, path,
- part_elem->partition_name,
- sub_elem->partition_name,
- name_variant);
+ if ((error= create_subpartition_name(part_name_buff,
+ sizeof(part_name_buff), path,
+ part_elem->partition_name, sub_elem->partition_name,
+ name_variant)))
+ {
+ cleanup_new_partition(part_count);
+ DBUG_RETURN(error);
+ }
part= i * num_subparts + j;
DBUG_PRINT("info", ("Add subpartition %s", part_name_buff));
if ((error= prepare_new_partition(table, create_info,
@@ -1725,9 +1746,14 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
}
else
{
- create_partition_name(part_name_buff, path,
- part_elem->partition_name, name_variant,
- TRUE);
+ if ((error= create_partition_name(part_name_buff,
+ sizeof(part_name_buff), path, part_elem->partition_name,
+ name_variant, TRUE)))
+ {
+ cleanup_new_partition(part_count);
+ DBUG_RETURN(error);
+ }
+
DBUG_PRINT("info", ("Add partition %s", part_name_buff));
if ((error= prepare_new_partition(table, create_info,
new_file_array[i],
@@ -1986,8 +2012,8 @@ int ha_partition::del_ren_cre_table(const char *from,
{
int save_error= 0;
int error= HA_ERR_INTERNAL_ERROR;
- char from_buff[FN_REFLEN], to_buff[FN_REFLEN], from_lc_buff[FN_REFLEN],
- to_lc_buff[FN_REFLEN], buff[FN_REFLEN];
+ char from_buff[FN_REFLEN + 1], to_buff[FN_REFLEN + 1],
+ from_lc_buff[FN_REFLEN], to_lc_buff[FN_REFLEN], buff[FN_REFLEN];
char *name_buffer_ptr;
const char *from_path;
const char *to_path= NULL;
@@ -2034,13 +2060,15 @@ int ha_partition::del_ren_cre_table(const char *from,
i= 0;
do
{
- create_partition_name(from_buff, from_path, name_buffer_ptr,
- NORMAL_PART_NAME, FALSE);
+ if ((error= create_partition_name(from_buff, sizeof(from_buff), from_path,
+ name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
+ goto rename_error;
if (to != NULL)
{ // Rename branch
- create_partition_name(to_buff, to_path, name_buffer_ptr,
- NORMAL_PART_NAME, FALSE);
+ if ((error= create_partition_name(to_buff, sizeof(to_buff), to_path,
+ name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
+ goto rename_error;
error= (*file)->ha_rename_table(from_buff, to_buff);
if (error)
goto rename_error;
@@ -2087,9 +2115,9 @@ create_error:
name_buffer_ptr= m_name_buffer_ptr;
for (abort_file= file, file= m_file; file < abort_file; file++)
{
- create_partition_name(from_buff, from_path, name_buffer_ptr, NORMAL_PART_NAME,
- FALSE);
- (void) (*file)->ha_delete_table((const char*) from_buff);
+ if (!create_partition_name(from_buff, sizeof(from_buff), from_path,
+ name_buffer_ptr, NORMAL_PART_NAME, FALSE))
+ (void) (*file)->ha_delete_table(from_buff);
name_buffer_ptr= strend(name_buffer_ptr) + 1;
}
DBUG_RETURN(error);
@@ -2098,12 +2126,11 @@ rename_error:
for (abort_file= file, file= m_file; file < abort_file; file++)
{
/* Revert the rename, back from 'to' to the original 'from' */
- create_partition_name(from_buff, from_path, name_buffer_ptr,
- NORMAL_PART_NAME, FALSE);
- create_partition_name(to_buff, to_path, name_buffer_ptr,
- NORMAL_PART_NAME, FALSE);
- /* Ignore error here */
- (void) (*file)->ha_rename_table(to_buff, from_buff);
+ if (!create_partition_name(from_buff, sizeof(from_buff), from_path,
+ name_buffer_ptr, NORMAL_PART_NAME, FALSE) &&
+ !create_partition_name(to_buff, sizeof(to_buff), to_path, name_buffer_ptr,
+ NORMAL_PART_NAME, FALSE))
+ (void) (*file)->ha_rename_table(to_buff, from_buff);
name_buffer_ptr= strend(name_buffer_ptr) + 1;
}
DBUG_RETURN(error);
@@ -2901,7 +2928,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
char *name_buffer_ptr;
int error= HA_ERR_INITIALIZATION;
handler **file;
- char name_buff[FN_REFLEN];
+ char name_buff[FN_REFLEN + 1];
bool is_not_tmp_table= (table_share->tmp_table == NO_TMP_TABLE);
ulonglong check_table_flags;
DBUG_ENTER("ha_partition::open");
@@ -2971,8 +2998,9 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
file= m_is_clone_of->m_file;
for (i= 0; i < m_tot_parts; i++)
{
- create_partition_name(name_buff, name, name_buffer_ptr, NORMAL_PART_NAME,
- FALSE);
+ if ((error= create_partition_name(name_buff, sizeof(name_buff), name,
+ name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
+ goto err_handler;
if (!(m_file[i]= file[i]->clone(name_buff, m_clone_mem_root)))
{
error= HA_ERR_INITIALIZATION;
@@ -2987,8 +3015,9 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
file= m_file;
do
{
- create_partition_name(name_buff, name, name_buffer_ptr, NORMAL_PART_NAME,
- FALSE);
+ if ((error= create_partition_name(name_buff, sizeof(name_buff), name,
+ name_buffer_ptr, NORMAL_PART_NAME, FALSE)))
+ goto err_handler;
table->s->connect_string = m_connect_string[(uint)(file-m_file)];
if ((error= (*file)->ha_open(table, name_buff, mode, test_if_locked)))
goto err_handler;
diff --git a/sql/item.cc b/sql/item.cc
index 1df91dc2534..fdfbba31404 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2016, MariaDB
+ Copyright (c) 2010, 2017, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -817,6 +817,7 @@ Item_ident::Item_ident(Name_resolution_context *context_arg,
cached_table(0), depended_from(0), can_be_depended(TRUE)
{
name = (char*) field_name_arg;
+ name_length= name ? strlen(name) : 0;
}
@@ -829,6 +830,7 @@ Item_ident::Item_ident(TABLE_LIST *view_arg, const char *field_name_arg)
cached_table(NULL), depended_from(NULL), can_be_depended(TRUE)
{
name = (char*) field_name_arg;
+ name_length= name ? strlen(name) : 0;
}
@@ -4622,7 +4624,7 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
int cur_match_degree= 0;
/* SELECT list element with explicit alias */
- if ((*(cur_group->item))->name &&
+ if ((*(cur_group->item))->name && !table_name &&
!(*(cur_group->item))->is_autogenerated_name &&
!my_strcasecmp(system_charset_info,
(*(cur_group->item))->name, field_name))
@@ -5045,6 +5047,12 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ?
(Item_ident*) (*reference) :
0));
+ if (thd->lex->in_sum_func &&
+ thd->lex->in_sum_func->nest_level >= select->nest_level)
+ {
+ set_if_bigger(thd->lex->in_sum_func->max_arg_level,
+ select->nest_level);
+ }
/*
A reference to a view field had been found and we
substituted it instead of this Item (find_field_in_tables
diff --git a/sql/item_func.h b/sql/item_func.h
index d60801745fe..2157c6b6b6d 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1165,7 +1165,11 @@ public:
longlong val_int();
const char *func_name() const { return "coercibility"; }
void fix_length_and_dec() { max_length=10; maybe_null= 0; }
- table_map not_null_tables() const { return 0; }
+ bool eval_not_null_tables(uchar *opt_arg)
+ {
+ not_null_tables_cache= 0;
+ return 0;
+ }
};
class Item_func_locate :public Item_int_func
@@ -1433,7 +1437,11 @@ public:
}
void cleanup();
Item_result result_type () const { return udf.result_type(); }
- table_map not_null_tables() const { return 0; }
+ bool eval_not_null_tables(uchar *opt_arg)
+ {
+ not_null_tables_cache= 0;
+ return 0;
+ }
bool is_expensive() { return 1; }
virtual void print(String *str, enum_query_type query_type);
};
@@ -1889,7 +1897,11 @@ public:
bool is_expensive_processor(uchar *arg) { return TRUE; }
enum Functype functype() const { return FT_FUNC; }
const char *func_name() const { return "match"; }
- table_map not_null_tables() const { return 0; }
+ bool eval_not_null_tables(uchar *opt_arg)
+ {
+ not_null_tables_cache= 0;
+ return 0;
+ }
bool fix_fields(THD *thd, Item **ref);
bool eq(const Item *, bool binary_cmp) const;
/* The following should be safe, even if we compare doubles */
@@ -2091,6 +2103,11 @@ public:
{
return TRUE;
}
+ bool eval_not_null_tables(uchar *opt_arg)
+ {
+ not_null_tables_cache= 0;
+ return 0;
+ }
};
@@ -2138,7 +2155,11 @@ public:
void fix_length_and_dec();
enum Item_result result_type () const { return last_value->result_type(); }
const char *func_name() const { return "last_value"; }
- table_map not_null_tables() const { return 0; }
+ bool eval_not_null_tables(uchar *opt_arg)
+ {
+ not_null_tables_cache= 0;
+ return 0;
+ }
enum_field_types field_type() const { return last_value->field_type(); }
bool const_item() const { return 0; }
void evaluate_sideeffects();
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 78dcfc4215c..ef90dd59be3 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -316,7 +316,8 @@ bool Item_subselect::enumerate_field_refs_processor(uchar *arg)
while ((upper= it++))
{
- if (upper->item->walk(&Item::enumerate_field_refs_processor, FALSE, arg))
+ if (upper->item &&
+ upper->item->walk(&Item::enumerate_field_refs_processor, FALSE, arg))
return TRUE;
}
return FALSE;
@@ -1366,7 +1367,7 @@ Item_in_subselect::Item_in_subselect(Item * left_exp,
Item_exists_subselect(),
left_expr_cache(0), first_execution(TRUE), in_strategy(SUBS_NOT_TRANSFORMED),
optimizer(0), pushed_cond_guards(NULL), emb_on_expr_nest(NULL),
- is_jtbm_merged(FALSE), is_jtbm_const_tab(FALSE),
+ do_not_convert_to_sj(FALSE), is_jtbm_merged(FALSE), is_jtbm_const_tab(FALSE),
is_flattenable_semijoin(FALSE),
is_registered_semijoin(FALSE),
upper_item(0)
@@ -2493,6 +2494,27 @@ bool Item_in_subselect::inject_in_to_exists_cond(JOIN *join_arg)
DBUG_ENTER("Item_in_subselect::inject_in_to_exists_cond");
DBUG_ASSERT(thd == join_arg->thd);
+ if (select_lex->min_max_opt_list.elements)
+ {
+ /*
+ MIN/MAX optimizations have been applied to Item_sum objects
+ of the subquery this subquery predicate in opt_sum_query().
+ Injection of new condition invalidates this optimizations.
+ Thus those optimizations must be rolled back.
+ */
+ List_iterator_fast<Item_sum> it(select_lex->min_max_opt_list);
+ Item_sum *item;
+ while ((item= it++))
+ {
+ item->clear();
+ item->reset_forced_const();
+ }
+ if (where_item)
+ where_item->update_used_tables();
+ if (having_item)
+ having_item->update_used_tables();
+ }
+
if (where_item)
{
List<Item> *and_args= NULL;
@@ -2850,7 +2872,8 @@ bool Item_in_subselect::init_cond_guards()
{
DBUG_ASSERT(thd);
uint cols_num= left_expr->cols();
- if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
+ if (!abort_on_null && !pushed_cond_guards &&
+ (left_expr->maybe_null || cols_num > 1))
{
if (!(pushed_cond_guards= (bool*)thd->alloc(sizeof(bool) * cols_num)))
return TRUE;
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 2f166c83e8f..75822ff8c6b 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -466,6 +466,8 @@ public:
NULL - for all other locations
*/
TABLE_LIST *emb_on_expr_nest;
+ /* May be TRUE only for the candidates to semi-join conversion */
+ bool do_not_convert_to_sj;
/*
Types of left_expr and subquery's select list allow to perform subquery
materialization. Currently, we set this to FALSE when it as well could
@@ -554,9 +556,9 @@ public:
Item_in_subselect()
:Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
abort_on_null(0), in_strategy(SUBS_NOT_TRANSFORMED), optimizer(0),
- pushed_cond_guards(NULL), func(NULL), emb_on_expr_nest(NULL),
- is_jtbm_merged(FALSE), is_jtbm_const_tab(FALSE),
- upper_item(0)
+ pushed_cond_guards(NULL), func(NULL), emb_on_expr_nest(NULL),
+ do_not_convert_to_sj(FALSE), is_jtbm_merged(FALSE),
+ is_jtbm_const_tab(FALSE), upper_item(0)
{}
void cleanup();
subs_type substype() { return IN_SUBS; }
@@ -617,6 +619,8 @@ public:
emb_on_expr_nest= embedding;
}
+ void block_conversion_to_sj () { do_not_convert_to_sj= TRUE; }
+
bool test_strategy(uchar strategy)
{ return test(in_strategy & strategy); }
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 86093f5d4f5..dcc3e494f82 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -454,6 +454,7 @@ public:
used_tables_cache= 0;
forced_const= TRUE;
}
+ void reset_forced_const() { forced_const= FALSE; }
virtual bool const_item() const { return forced_const; }
virtual bool const_during_execution() const { return false; }
virtual void print(String *str, enum_query_type query_type);
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 420fb29f518..0ed1506bbee 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -3041,7 +3041,7 @@ get_date_time_result_type(const char *format, uint length)
const char *val= format;
const char *end= format + length;
- for (; val != end && val != end; val++)
+ for (; val != end; val++)
{
if (*val == '%' && val+1 != end)
{
diff --git a/sql/log.cc b/sql/log.cc
index f8333fbe3cf..d7aebb4ccf7 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -4995,13 +4995,20 @@ int THD::binlog_write_table_map(TABLE *table, bool is_transactional,
IO_CACHE *file=
cache_mngr->get_binlog_cache_log(use_trans_cache(this, is_transactional));
+ binlog_cache_data *cache_data=
+ cache_mngr->get_binlog_cache_data(use_trans_cache(this, is_transactional));
+
if (with_annotate && *with_annotate)
{
Annotate_rows_log_event anno(current_thd, is_transactional, false);
/* Annotate event should be written not more than once */
*with_annotate= 0;
if ((error= anno.write(file)))
+ {
+ if (my_errno == EFBIG)
+ cache_data->set_incident();
DBUG_RETURN(error);
+ }
}
if ((error= the_event.write(file)))
DBUG_RETURN(error);
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index a280fcf4cf4..ea66bb53394 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2012, 2016, MariaDB
+ Copyright (c) 2012, 2017, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 5137d8a0986..af1abb2001e 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -678,6 +678,7 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
!((join->select_options | // 10
select_lex->outer_select()->join->select_options) // 10
& SELECT_STRAIGHT_JOIN)) // 10
+
{
DBUG_PRINT("info", ("Subquery is semi-join conversion candidate"));
@@ -1000,6 +1001,25 @@ bool check_for_outer_joins(List<TABLE_LIST> *join_list)
}
+void find_and_block_conversion_to_sj(Item *to_find,
+ List_iterator_fast<Item_in_subselect> &li)
+{
+ if (to_find->type() != Item::SUBSELECT_ITEM ||
+ ((Item_subselect *) to_find)->substype() != Item_subselect::IN_SUBS)
+ return;
+ Item_in_subselect *in_subq;
+ li.rewind();
+ while ((in_subq= li++))
+ {
+ if (in_subq == to_find)
+ {
+ in_subq->block_conversion_to_sj();
+ return;
+ }
+ }
+}
+
+
/*
Convert semi-join subquery predicates into semi-join join nests
@@ -1052,7 +1072,6 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
Query_arena *arena, backup;
Item_in_subselect *in_subq;
THD *thd= join->thd;
- List_iterator<TABLE_LIST> ti(join->select_lex->leaf_tables);
DBUG_ENTER("convert_join_subqueries_to_semijoins");
if (join->select_lex->sj_subselects.is_empty())
@@ -1070,6 +1089,89 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
subq_sel->update_used_tables();
}
+ /*
+ Check all candidates to semi-join conversion that occur
+ in ON expressions of outer join. Set the flag blocking
+ this conversion for them.
+ */
+ TABLE_LIST *tbl;
+ List_iterator<TABLE_LIST> ti(join->select_lex->leaf_tables);
+ while ((tbl= ti++))
+ {
+ TABLE_LIST *embedded;
+ TABLE_LIST *embedding= tbl;
+ do
+ {
+ embedded= embedding;
+ bool block_conversion_to_sj= false;
+ if (embedded->on_expr)
+ {
+ /*
+ Conversion of an IN subquery predicate into semi-join
+ is blocked now if the predicate occurs:
+ - in the ON expression of an outer join
+ - in the ON expression of an inner join embedded directly
+ or indirectly in the inner nest of an outer join
+ */
+ for (TABLE_LIST *tl= embedded; tl; tl= tl->embedding)
+ {
+ if (tl->outer_join)
+ {
+ block_conversion_to_sj= true;
+ break;
+ }
+ }
+ }
+ if (block_conversion_to_sj)
+ {
+ Item *cond= embedded->on_expr;
+ if (!cond)
+ ;
+ else if (cond->type() != Item::COND_ITEM)
+ find_and_block_conversion_to_sj(cond, li);
+ else if (((Item_cond*) cond)->functype() ==
+ Item_func::COND_AND_FUNC)
+ {
+ Item *item;
+ List_iterator<Item> it(*(((Item_cond*) cond)->argument_list()));
+ while ((item= it++))
+ {
+ find_and_block_conversion_to_sj(item, li);
+ }
+ }
+ }
+ embedding= embedded->embedding;
+ }
+ while (embedding &&
+ embedding->nested_join->join_list.head() == embedded);
+ }
+
+ /*
+ Block conversion to semi-joins for those candidates that
+ are encountered in the WHERE condition of the multi-table view
+ with CHECK OPTION if this view is used in UPDATE/DELETE.
+ (This limitation can be, probably, easily lifted.)
+ */
+ li.rewind();
+ while ((in_subq= li++))
+ {
+ if (in_subq->emb_on_expr_nest != NO_JOIN_NEST &&
+ in_subq->emb_on_expr_nest->effective_with_check)
+ {
+ in_subq->block_conversion_to_sj();
+ }
+ }
+
+ if (join->select_options & SELECT_STRAIGHT_JOIN)
+ {
+ /* Block conversion to semijoins for all candidates */
+ li.rewind();
+ while ((in_subq= li++))
+ {
+ in_subq->block_conversion_to_sj();
+ }
+ }
+
li.rewind();
/* First, convert child join's subqueries. We proceed bottom-up here */
while ((in_subq= li++))
@@ -1088,8 +1190,10 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
if (convert_join_subqueries_to_semijoins(child_join))
DBUG_RETURN(TRUE);
+
+
in_subq->sj_convert_priority=
- test(in_subq->emb_on_expr_nest != NO_JOIN_NEST) * MAX_TABLES * 2 +
+ test(in_subq->do_not_convert_to_sj) * MAX_TABLES * 2 +
in_subq->is_correlated * MAX_TABLES + child_join->outer_tables;
}
@@ -1122,7 +1226,7 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
bool remove_item= TRUE;
/* Stop processing if we've reached a subquery that's attached to the ON clause */
- if (in_subq->emb_on_expr_nest != NO_JOIN_NEST)
+ if (in_subq->do_not_convert_to_sj)
break;
if (in_subq->is_flattenable_semijoin)
@@ -3325,6 +3429,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
table_map remaining_tables= 0;
table_map handled_tabs= 0;
join->sjm_lookup_tables= 0;
+ join->sjm_scan_tables= 0;
for (tablenr= table_count - 1 ; tablenr != join->const_tables - 1; tablenr--)
{
POSITION *pos= join->best_positions + tablenr;
@@ -3383,6 +3488,9 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
for (i= tablenr; i != (first + sjm->tables - 1); i--)
rem_tables |= join->best_positions[i].table->table->map;
+ for (i= first; i < first+ sjm->tables; i++)
+ join->sjm_scan_tables |= join->best_positions[i].table->table->map;
+
POSITION dummy;
join->cur_sj_inner_tables= 0;
for (i= first + sjm->tables; i <= tablenr; i++)
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index aa8b17a2c85..1a8c6be5f41 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -253,6 +253,8 @@ int opt_sum_query(THD *thd,
int error= 0;
DBUG_ENTER("opt_sum_query");
+ thd->lex->current_select->min_max_opt_list.empty();
+
if (conds)
where_tables= conds->used_tables();
@@ -444,7 +446,14 @@ int opt_sum_query(THD *thd,
item_sum->aggregator_clear();
}
else
+ {
item_sum->reset_and_add();
+ /*
+ Save a reference to the item for possible rollback
+ of the min/max optimizations for this select
+ */
+ thd->lex->current_select->min_max_opt_list.push_back(item_sum);
+ }
item_sum->make_const();
recalc_const_item= 1;
break;
diff --git a/sql/records.cc b/sql/records.cc
index aca950d7435..59ea50bd061 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -1,5 +1,6 @@
/*
Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2017, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/rpl_handler.cc b/sql/rpl_handler.cc
index 5b75d6c30ea..ca3b57edce3 100644
--- a/sql/rpl_handler.cc
+++ b/sql/rpl_handler.cc
@@ -260,7 +260,7 @@ int Binlog_storage_delegate::after_flush(THD *thd,
thd->semisync_info= log_info;
}
- strcpy(log_info->log_file, log_file+dirname_length(log_file));
+ strmake_buf(log_info->log_file, log_file+dirname_length(log_file));
log_info->log_pos = log_pos;
FOREACH_OBSERVER(ret, after_flush, false,
diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc
index 3c5a99121fa..adaa7cf864f 100644
--- a/sql/rpl_mi.cc
+++ b/sql/rpl_mi.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2006, 2012, Oracle and/or its affiliates.
- Copyright (c) 2010, 2011, Monty Program Ab
+/* Copyright (c) 2006, 2017, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2017, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -401,7 +401,7 @@ file '%s')", fname);
mi->connect_retry= (uint) connect_retry;
mi->ssl= (my_bool) ssl;
mi->ssl_verify_server_cert= ssl_verify_server_cert;
- mi->heartbeat_period= master_heartbeat_period;
+ mi->heartbeat_period= min(SLAVE_MAX_HEARTBEAT_PERIOD, master_heartbeat_period);
}
DBUG_PRINT("master_info",("log_file_name: %s position: %ld",
mi->master_log_name,
@@ -518,8 +518,8 @@ int flush_master_info(Master_info* mi,
contents of file). But because of number of lines in the first line
of file we don't care about this garbage.
*/
- char heartbeat_buf[sizeof(mi->heartbeat_period) * 4]; // buffer to suffice always
- sprintf(heartbeat_buf, "%.3f", mi->heartbeat_period);
+ char heartbeat_buf[FLOATING_POINT_BUFFER];
+ my_fcvt(mi->heartbeat_period, 3, heartbeat_buf, NULL);
my_b_seek(file, 0L);
my_b_printf(file,
"%u\n%s\n%s\n%s\n%s\n%s\n%d\n%d\n%d\n%s\n%s\n%s\n%s\n%s\n%d\n%s\n%s\n%s\n",
@@ -548,7 +548,6 @@ void end_master_info(Master_info* mi)
if (!mi->inited)
DBUG_VOID_RETURN;
- end_relay_log_info(&mi->rli);
if (mi->fd >= 0)
{
end_io_cache(&mi->file);
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 5007b8e1237..c0c541eee93 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2006, 2013, Oracle and/or its affiliates.
- Copyright (c) 2011, 2013, Monty Program Ab
+/* Copyright (c) 2006, 2017, Oracle and/or its affiliates.
+ Copyright (c) 2011, 2017, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -42,7 +42,8 @@ Relay_log_info::Relay_log_info(bool is_slave_recovery)
no_storage(FALSE), replicate_same_server_id(::replicate_same_server_id),
info_fd(-1), cur_log_fd(-1), relay_log(&sync_relaylog_period),
sync_counter(0), is_relay_log_recovery(is_slave_recovery),
- save_temporary_tables(0), cur_log_old_open_count(0), group_relay_log_pos(0),
+ save_temporary_tables(0), cur_log_old_open_count(0),
+ error_on_rli_init_info(false), group_relay_log_pos(0),
event_relay_log_pos(0),
#if HAVE_valgrind
is_fake(FALSE),
@@ -112,7 +113,7 @@ int init_relay_log_info(Relay_log_info* rli,
const char* info_fname)
{
char fname[FN_REFLEN+128];
- int info_fd;
+ int info_fd= -1;
const char* msg = 0;
int error = 0;
DBUG_ENTER("init_relay_log_info");
@@ -122,6 +123,8 @@ int init_relay_log_info(Relay_log_info* rli,
DBUG_RETURN(0);
fn_format(fname, info_fname, mysql_data_home, "", 4+32);
mysql_mutex_lock(&rli->data_lock);
+ if (rli->error_on_rli_init_info)
+ goto err;
info_fd = rli->info_fd;
rli->cur_log_fd = -1;
rli->slave_skip_counter=0;
@@ -358,11 +361,14 @@ Failed to open the existing relay log info file '%s' (errno %d)",
goto err;
}
rli->inited= 1;
+ rli->error_on_rli_init_info= false;
mysql_mutex_unlock(&rli->data_lock);
DBUG_RETURN(error);
err:
- sql_print_error("%s", msg);
+ rli->error_on_rli_init_info= true;
+ if (msg)
+ sql_print_error("%s", msg);
end_io_cache(&rli->info_file);
if (info_fd >= 0)
mysql_file_close(info_fd, MYF(0));
@@ -947,6 +953,8 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset,
const char** errmsg)
{
int error=0;
+ const char *ln;
+ char name_buf[FN_REFLEN];
DBUG_ENTER("purge_relay_logs");
/*
@@ -973,12 +981,34 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset,
if (!rli->inited)
{
DBUG_PRINT("info", ("rli->inited == 0"));
- DBUG_RETURN(0);
- }
-
- DBUG_ASSERT(rli->slave_running == 0);
- DBUG_ASSERT(rli->mi->slave_running == 0);
+ if (rli->error_on_rli_init_info)
+ {
+ ln= rli->relay_log.generate_name(opt_relay_logname, "-relay-bin",
+ 1, name_buf);
+ if (rli->relay_log.open_index_file(opt_relaylog_index_name, ln, TRUE))
+ {
+ sql_print_error("Unable to purge relay log files. Failed to open relay "
+ "log index file:%s.", rli->relay_log.get_index_fname());
+ DBUG_RETURN(1);
+ }
+ if (rli->relay_log.open(ln, LOG_BIN, 0, SEQ_READ_APPEND, 0,
+ (max_relay_log_size ? max_relay_log_size :
+ max_binlog_size), 1, TRUE))
+ {
+ sql_print_error("Unable to purge relay log files. Failed to open relay "
+ "log file:%s.", rli->relay_log.get_log_fname());
+ DBUG_RETURN(1);
+ }
+ }
+ else
+ DBUG_RETURN(0);
+ }
+ else
+ {
+ DBUG_ASSERT(rli->slave_running == 0);
+ DBUG_ASSERT(rli->mi->slave_running == 0);
+ }
rli->slave_skip_counter=0;
mysql_mutex_lock(&rli->data_lock);
@@ -1016,6 +1046,8 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset,
rli->group_relay_log_pos,
0 /* do not need data lock */, errmsg, 0);
+ if (!rli->inited && rli->error_on_rli_init_info)
+ rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
err:
#ifndef DBUG_OFF
char buf[22];
diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h
index 5f15d2f1fd8..75cb9b7a645 100644
--- a/sql/rpl_rli.h
+++ b/sql/rpl_rli.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2005, 2012, Oracle and/or its affiliates.
+/* Copyright (c) 2005, 2017, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2017, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -154,7 +155,14 @@ public:
a different log under our feet
*/
uint32 cur_log_old_open_count;
-
+
+ /*
+ If on init_info() call error_on_rli_init_info is true that means
+ that previous call to init_info() terminated with an error, RESET
+ SLAVE must be executed and the problem fixed manually.
+ */
+ bool error_on_rli_init_info;
+
/*
Let's call a group (of events) :
- a transaction
diff --git a/sql/slave.cc b/sql/slave.cc
index f472825b0a9..f043ea3c477 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2009, 2016, MariaDB
+/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2017, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -883,6 +883,7 @@ void close_active_mi()
if (active_mi)
{
end_master_info(active_mi);
+ end_relay_log_info(&active_mi->rli);
delete active_mi;
active_mi= 0;
}
@@ -4607,6 +4608,7 @@ void end_relay_log_info(Relay_log_info* rli)
{
DBUG_ENTER("end_relay_log_info");
+ rli->error_on_rli_init_info= false;
if (!rli->inited)
DBUG_VOID_RETURN;
if (rli->info_fd >= 0)
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 1d0b86ad2f5..43d7ffd94d6 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1455,6 +1455,8 @@ void THD::init(void)
server_status= SERVER_STATUS_AUTOCOMMIT;
if (variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
+ if (variables.sql_mode & MODE_ANSI_QUOTES)
+ server_status|= SERVER_STATUS_ANSI_QUOTES;
transaction.all.modified_non_trans_table=
transaction.stmt.modified_non_trans_table= FALSE;
@@ -3922,7 +3924,7 @@ void Security_context::destroy()
if (external_user)
{
my_free(external_user);
- user= NULL;
+ external_user= NULL;
}
my_free(ip);
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 20fca2de8cf..493f0eccc8c 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -525,7 +525,9 @@ bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived)
derived->schema_table= derived->merge_underlying_list->schema_table;
derived->merged_for_insert= TRUE;
}
- }
+ }
+ else
+ derived->table= derived->merge_underlying_list->table;
DBUG_RETURN(FALSE);
}
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 80ca358fd32..446a4449e2f 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1886,6 +1886,7 @@ void st_select_lex::init_query()
leaf_tables_prep.empty();
leaf_tables.empty();
item_list.empty();
+ min_max_opt_list.empty();
join= 0;
having= prep_having= where= prep_where= 0;
olap= UNSPECIFIED_OLAP_TYPE;
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index b13befd8dbe..d283085886e 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -766,6 +766,11 @@ public:
*/
List<Item_func_match> *ftfunc_list;
List<Item_func_match> ftfunc_list_alloc;
+ /*
+ The list of items to which MIN/MAX optimizations of opt_sum_query()
+ have been applied. Used to rollback those optimizations if it's needed.
+ */
+ List<Item_sum> min_max_opt_list;
JOIN *join; /* after JOIN::prepare it is pointer to corresponding JOIN */
List<TABLE_LIST> top_join_list; /* join list of the top level */
List<TABLE_LIST> *join_list; /* list for the currently parsed join */
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index dcbd9f180d1..23865ab8983 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2016, MariaDB
+ Copyright (c) 2010, 2017, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 28963e65218..745ea171030 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -951,20 +951,16 @@ static my_bool deny_updates_if_read_only_option(THD *thd,
if (lex->sql_command == SQLCOM_UPDATE_MULTI)
DBUG_RETURN(FALSE);
- const my_bool create_temp_tables=
- (lex->sql_command == SQLCOM_CREATE_TABLE) &&
- (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
-
- const my_bool drop_temp_tables=
- (lex->sql_command == SQLCOM_DROP_TABLE) &&
- lex->drop_temporary;
-
- const my_bool update_real_tables=
- some_non_temp_table_to_be_updated(thd, all_tables) &&
- !(create_temp_tables || drop_temp_tables);
-
+ /*
+ a table-to-be-created is not in the temp table list yet,
+ so CREATE TABLE needs a special treatment
+ */
+ const bool update_real_tables=
+ lex->sql_command == SQLCOM_CREATE_TABLE
+ ? !(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)
+ : some_non_temp_table_to_be_updated(thd, all_tables);
- const my_bool create_or_drop_databases=
+ const bool create_or_drop_databases=
(lex->sql_command == SQLCOM_CREATE_DB) ||
(lex->sql_command == SQLCOM_DROP_DB);
@@ -1456,9 +1452,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
kill_zombie_dump_threads(slave_server_id);
thd->server_id = slave_server_id;
- general_log_print(thd, command, "Log: '%s' Pos: %ld", packet+10,
- (long) pos);
- mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags);
+ const char *name= packet + 10;
+ size_t nlen= strlen(name);
+
+ general_log_print(thd, command, "Log: '%s' Pos: %lu", name, pos);
+ if (nlen < FN_REFLEN)
+ mysql_binlog_send(thd, thd->strmake(name, nlen), (my_off_t)pos, flags);
unregister_slave(thd,1,1);
/* fake COM_QUIT -- if we get here, the thread needs to terminate */
error = TRUE;
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index b0fb38bf748..0d9f6e6a1f5 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -1913,6 +1913,22 @@ static int add_subpartition_by(File fptr)
return err + add_partition_by(fptr);
}
+static int add_name_string(File fptr, const char *name)
+{
+ int err;
+ String name_string("", 0, system_charset_info);
+ THD *thd= current_thd;
+ ulonglong save_sql_mode= thd->variables.sql_mode;
+ thd->variables.sql_mode&= ~MODE_ANSI_QUOTES;
+ ulonglong save_options= thd->variables.option_bits;
+ thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE;
+ append_identifier(thd, &name_string, name, strlen(name));
+ thd->variables.sql_mode= save_sql_mode;
+ thd->variables.option_bits= save_options;
+ err= add_string_object(fptr, &name_string);
+ return err;
+}
+
static int add_part_field_list(File fptr, List<char> field_list)
{
uint i, num_fields;
@@ -1924,15 +1940,7 @@ static int add_part_field_list(File fptr, List<char> field_list)
err+= add_begin_parenthesis(fptr);
while (i < num_fields)
{
- const char *field_str= part_it++;
- String field_string("", 0, system_charset_info);
- THD *thd= current_thd;
- ulonglong save_options= thd->variables.option_bits;
- thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE;
- append_identifier(thd, &field_string, field_str,
- strlen(field_str));
- thd->variables.option_bits= save_options;
- err+= add_string_object(fptr, &field_string);
+ err+= add_name_string(fptr, part_it++);
if (i != (num_fields-1))
err+= add_comma(fptr);
i++;
@@ -1941,20 +1949,6 @@ static int add_part_field_list(File fptr, List<char> field_list)
return err;
}
-static int add_name_string(File fptr, const char *name)
-{
- int err;
- String name_string("", 0, system_charset_info);
- THD *thd= current_thd;
- ulonglong save_options= thd->variables.option_bits;
- thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE;
- append_identifier(thd, &name_string, name,
- strlen(name));
- thd->variables.option_bits= save_options;
- err= add_string_object(fptr, &name_string);
- return err;
-}
-
static int add_int(File fptr, longlong number)
{
char buff[32];
@@ -5888,8 +5882,8 @@ static bool write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
DDL_LOG_ENTRY ddl_log_entry;
partition_info *part_info= lpt->part_info;
DDL_LOG_MEMORY_ENTRY *log_entry;
- char tmp_path[FN_REFLEN];
- char normal_path[FN_REFLEN];
+ char tmp_path[FN_REFLEN + 1];
+ char normal_path[FN_REFLEN + 1];
List_iterator<partition_element> part_it(part_info->partitions);
uint temp_partitions= part_info->temp_partitions.elements;
uint num_elements= part_info->partitions.elements;
@@ -5913,14 +5907,15 @@ static bool write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
ddl_log_entry.next_entry= *next_entry;
ddl_log_entry.handler_name=
ha_resolve_storage_engine_name(sub_elem->engine_type);
- create_subpartition_name(tmp_path, path,
- part_elem->partition_name,
- sub_elem->partition_name,
- TEMP_PART_NAME);
- create_subpartition_name(normal_path, path,
- part_elem->partition_name,
- sub_elem->partition_name,
- NORMAL_PART_NAME);
+ if (create_subpartition_name(tmp_path, sizeof(tmp_path), path,
+ part_elem->partition_name,
+ sub_elem->partition_name,
+ TEMP_PART_NAME) ||
+ create_subpartition_name(normal_path, sizeof(normal_path), path,
+ part_elem->partition_name,
+ sub_elem->partition_name,
+ NORMAL_PART_NAME))
+ DBUG_RETURN(TRUE);
ddl_log_entry.name= normal_path;
ddl_log_entry.from_name= tmp_path;
if (part_elem->part_state == PART_IS_CHANGED)
@@ -5941,12 +5936,13 @@ static bool write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
ddl_log_entry.next_entry= *next_entry;
ddl_log_entry.handler_name=
ha_resolve_storage_engine_name(part_elem->engine_type);
- create_partition_name(tmp_path, path,
- part_elem->partition_name,
- TEMP_PART_NAME, TRUE);
- create_partition_name(normal_path, path,
- part_elem->partition_name,
- NORMAL_PART_NAME, TRUE);
+ if (create_partition_name(tmp_path, sizeof(tmp_path), path,
+ part_elem->partition_name, TEMP_PART_NAME,
+ TRUE) ||
+ create_partition_name(normal_path, sizeof(normal_path), path,
+ part_elem->partition_name, NORMAL_PART_NAME,
+ TRUE))
+ DBUG_RETURN(TRUE);
ddl_log_entry.name= normal_path;
ddl_log_entry.from_name= tmp_path;
if (part_elem->part_state == PART_IS_CHANGED)
@@ -5985,7 +5981,7 @@ static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
DDL_LOG_ENTRY ddl_log_entry;
partition_info *part_info= lpt->part_info;
DDL_LOG_MEMORY_ENTRY *log_entry;
- char tmp_path[FN_LEN];
+ char tmp_path[FN_REFLEN + 1];
List_iterator<partition_element> part_it(part_info->partitions);
List_iterator<partition_element> temp_it(part_info->temp_partitions);
uint num_temp_partitions= part_info->temp_partitions.elements;
@@ -6024,10 +6020,10 @@ static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
ddl_log_entry.next_entry= *next_entry;
ddl_log_entry.handler_name=
ha_resolve_storage_engine_name(sub_elem->engine_type);
- create_subpartition_name(tmp_path, path,
- part_elem->partition_name,
- sub_elem->partition_name,
- name_variant);
+ if (create_subpartition_name(tmp_path, sizeof(tmp_path), path,
+ part_elem->partition_name,
+ sub_elem->partition_name, name_variant))
+ DBUG_RETURN(TRUE);
ddl_log_entry.name= tmp_path;
if (write_ddl_log_entry(&ddl_log_entry, &log_entry))
{
@@ -6043,9 +6039,10 @@ static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
ddl_log_entry.next_entry= *next_entry;
ddl_log_entry.handler_name=
ha_resolve_storage_engine_name(part_elem->engine_type);
- create_partition_name(tmp_path, path,
- part_elem->partition_name,
- name_variant, TRUE);
+ if (create_partition_name(tmp_path, sizeof(tmp_path), path,
+ part_elem->partition_name, name_variant,
+ TRUE))
+ DBUG_RETURN(TRUE);
ddl_log_entry.name= tmp_path;
if (write_ddl_log_entry(&ddl_log_entry, &log_entry))
{
@@ -8123,31 +8120,41 @@ static uint32 get_next_subpartition_via_walking(PARTITION_ITERATOR *part_iter)
}
+/* used in error messages below */
+static const char *longest_str(const char *s1, const char *s2,
+ const char *s3=0)
+{
+ if (strlen(s2) > strlen(s1)) s1= s2;
+ if (s3 && strlen(s3) > strlen(s1)) s1= s3;
+ return s1;
+}
+
/*
Create partition names
SYNOPSIS
create_partition_name()
- out:out Created partition name string
+ out:out The buffer for the created partition name string
+ must be *at least* of FN_REFLEN+1 bytes
in1 First part
in2 Second part
name_variant Normal, temporary or renamed partition name
RETURN VALUE
- NONE
+ 0 if ok, error if name too long
DESCRIPTION
This method is used to calculate the partition name, service routine to
the del_ren_cre_table method.
*/
-void create_partition_name(char *out, const char *in1,
- const char *in2, uint name_variant,
- bool translate)
+int create_partition_name(char *out, size_t outlen, const char *in1,
+ const char *in2, uint name_variant, bool translate)
{
char transl_part_name[FN_REFLEN];
- const char *transl_part;
+ const char *transl_part, *end;
+ DBUG_ASSERT(outlen >= FN_REFLEN + 1); // consistency! same limit everywhere
if (translate)
{
@@ -8157,11 +8164,17 @@ void create_partition_name(char *out, const char *in1,
else
transl_part= in2;
if (name_variant == NORMAL_PART_NAME)
- strxmov(out, in1, "#P#", transl_part, NullS);
+ end= strxnmov(out, outlen-1, in1, "#P#", transl_part, NullS);
else if (name_variant == TEMP_PART_NAME)
- strxmov(out, in1, "#P#", transl_part, "#TMP#", NullS);
+ end= strxnmov(out, outlen-1, in1, "#P#", transl_part, "#TMP#", NullS);
else if (name_variant == RENAMED_PART_NAME)
- strxmov(out, in1, "#P#", transl_part, "#REN#", NullS);
+ end= strxnmov(out, outlen-1, in1, "#P#", transl_part, "#REN#", NullS);
+ if (end - out == static_cast<ptrdiff_t>(outlen-1))
+ {
+ my_error(ER_PATH_LENGTH, MYF(0), longest_str(in1, transl_part));
+ return HA_WRONG_CREATE_OPTION;
+ }
+ return 0;
}
@@ -8170,37 +8183,46 @@ void create_partition_name(char *out, const char *in1,
SYNOPSIS
create_subpartition_name()
- out:out Created partition name string
+ out:out The buffer for the created partition name string
+ must be *at least* of FN_REFLEN+1 bytes
in1 First part
in2 Second part
in3 Third part
name_variant Normal, temporary or renamed partition name
RETURN VALUE
- NONE
+ 0 if ok, error if name too long
DESCRIPTION
This method is used to calculate the subpartition name, service routine to
the del_ren_cre_table method.
*/
-void create_subpartition_name(char *out, const char *in1,
- const char *in2, const char *in3,
- uint name_variant)
+int create_subpartition_name(char *out, size_t outlen,
+ const char *in1, const char *in2,
+ const char *in3, uint name_variant)
{
- char transl_part_name[FN_REFLEN], transl_subpart_name[FN_REFLEN];
+ char transl_part_name[FN_REFLEN], transl_subpart_name[FN_REFLEN], *end;
+ DBUG_ASSERT(outlen >= FN_REFLEN + 1); // consistency! same limit everywhere
tablename_to_filename(in2, transl_part_name, FN_REFLEN);
tablename_to_filename(in3, transl_subpart_name, FN_REFLEN);
if (name_variant == NORMAL_PART_NAME)
- strxmov(out, in1, "#P#", transl_part_name,
- "#SP#", transl_subpart_name, NullS);
+ end= strxnmov(out, outlen-1, in1, "#P#", transl_part_name,
+ "#SP#", transl_subpart_name, NullS);
else if (name_variant == TEMP_PART_NAME)
- strxmov(out, in1, "#P#", transl_part_name,
- "#SP#", transl_subpart_name, "#TMP#", NullS);
+ end= strxnmov(out, outlen-1, in1, "#P#", transl_part_name,
+ "#SP#", transl_subpart_name, "#TMP#", NullS);
else if (name_variant == RENAMED_PART_NAME)
- strxmov(out, in1, "#P#", transl_part_name,
- "#SP#", transl_subpart_name, "#REN#", NullS);
+ end= strxnmov(out, outlen-1, in1, "#P#", transl_part_name,
+ "#SP#", transl_subpart_name, "#REN#", NullS);
+ if (end - out == static_cast<ptrdiff_t>(outlen-1))
+ {
+ my_error(ER_PATH_LENGTH, MYF(0),
+ longest_str(in1, transl_part_name, transl_subpart_name));
+ return HA_WRONG_CREATE_OPTION;
+ }
+ return 0;
}
uint get_partition_field_store_length(Field *field)
diff --git a/sql/sql_partition.h b/sql/sql_partition.h
index 951d58a655b..838006203c0 100644
--- a/sql/sql_partition.h
+++ b/sql/sql_partition.h
@@ -274,12 +274,12 @@ bool partition_key_modified(TABLE *table, const MY_BITMAP *fields);
#define partition_key_modified(X,Y) 0
#endif
-void create_partition_name(char *out, const char *in1,
- const char *in2, uint name_variant,
- bool translate);
-void create_subpartition_name(char *out, const char *in1,
- const char *in2, const char *in3,
- uint name_variant);
+int __attribute__((warn_unused_result))
+ create_partition_name(char *out, size_t outlen, const char *in1, const char
+ *in2, uint name_variant, bool translate);
+int __attribute__((warn_unused_result))
+ create_subpartition_name(char *out, size_t outlen, const char *in1, const
+ char *in2, const char *in3, uint name_variant);
void set_field_ptr(Field **ptr, const uchar *new_buf, const uchar *old_buf);
void set_key_field_ptr(KEY *key_info, const uchar *new_buf,
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 97bbc5a83d6..f527fcce34c 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -316,6 +316,12 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref plugin);
static void intern_plugin_unlock(LEX *lex, plugin_ref plugin);
static void reap_plugins(void);
+bool plugin_is_forced(struct st_plugin_int *p)
+{
+ return p->load_option == PLUGIN_FORCE ||
+ p->load_option == PLUGIN_FORCE_PLUS_PERMANENT;
+}
+
static void report_error(int where_to, uint error, ...)
{
va_list args;
@@ -1353,7 +1359,7 @@ static int plugin_initialize(MEM_ROOT *tmp_root, struct st_plugin_int *plugin,
if (options_only || state == PLUGIN_IS_DISABLED)
{
- ret= 0;
+ ret= !options_only && plugin_is_forced(plugin);
goto err;
}
@@ -1657,8 +1663,7 @@ int plugin_init(int *argc, char **argv, int flags)
while ((plugin_ptr= *(--reap)))
{
mysql_mutex_unlock(&LOCK_plugin);
- if (plugin_ptr->load_option == PLUGIN_FORCE ||
- plugin_ptr->load_option == PLUGIN_FORCE_PLUS_PERMANENT)
+ if (plugin_is_forced(plugin_ptr))
reaped_mandatory_plugin= TRUE;
plugin_deinitialize(plugin_ptr, true);
mysql_mutex_lock(&LOCK_plugin);
@@ -3511,8 +3516,7 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
plugin_dash.length + 1);
strxmov(plugin_name_with_prefix_ptr, plugin_dash.str, plugin_name_ptr, NullS);
- if (tmp->load_option != PLUGIN_FORCE &&
- tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT)
+ if (!plugin_is_forced(tmp))
{
/* support --skip-plugin-foo syntax */
options[0].name= plugin_name_ptr;
@@ -3829,8 +3833,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
We adjust the default value to account for the hardcoded exceptions
we have set for the federated and ndbcluster storage engines.
*/
- if (tmp->load_option != PLUGIN_FORCE &&
- tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT)
+ if (!plugin_is_forced(tmp))
opts[0].def_value= opts[1].def_value= plugin_load_option;
error= handle_options(argc, &argv, opts, NULL);
@@ -3846,8 +3849,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
Set plugin loading policy from option value. First element in the option
list is always the <plugin name> option value.
*/
- if (tmp->load_option != PLUGIN_FORCE &&
- tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT)
+ if (!plugin_is_forced(tmp))
plugin_load_option= (enum_plugin_load_option) *(ulong*) opts[0].value;
}
diff --git a/sql/sql_priv.h b/sql/sql_priv.h
index 749ee245aa7..b5589cb4b22 100644
--- a/sql/sql_priv.h
+++ b/sql/sql_priv.h
@@ -121,7 +121,7 @@
#define OPTION_AUTOCOMMIT (1ULL << 8) // THD, user
#define OPTION_BIG_SELECTS (1ULL << 9) // THD, user
#define OPTION_LOG_OFF (1ULL << 10) // THD, user
-#define OPTION_QUOTE_SHOW_CREATE (1ULL << 11) // THD, user, unused
+#define OPTION_QUOTE_SHOW_CREATE (1ULL << 11) // THD, user
#define TMP_TABLE_ALL_COLUMNS (1ULL << 12) // SELECT, intern
#define OPTION_WARNINGS (1ULL << 13) // THD, user
#define OPTION_AUTO_IS_NULL (1ULL << 14) // THD, user, binlog
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index dca29ec3273..3bfc417f2f6 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2008, 2014, SkySQL Ab.
+/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
+ Copyright (c) 2008, 2017, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1494,6 +1494,7 @@ int reset_slave(THD *thd, Master_info* mi)
// close master_info_file, relay_log_info_file, set mi->inited=rli->inited=0
end_master_info(mi);
+ end_relay_log_info(&mi->rli);
// and delete these two files
fn_format(fname, master_info_file, mysql_data_home, "", 4+32);
if (mysql_file_stat(key_file_master_info, fname, &stat_area, MYF(0)) &&
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index c5f2a83fc01..720c0a22681 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1195,6 +1195,7 @@ JOIN::optimize()
DBUG_PRINT("info",("Select tables optimized away"));
zero_result_cause= "Select tables optimized away";
tables_list= 0; // All tables resolved
+ select_lex->min_max_opt_list.empty();
const_tables= top_join_tab_count= table_count;
/*
Extract all table-independent conditions and replace the WHERE
@@ -2758,8 +2759,11 @@ JOIN::exec()
if (sort_table_cond)
{
if (!curr_table->select)
+ {
if (!(curr_table->select= new SQL_SELECT))
DBUG_VOID_RETURN;
+ curr_table->select->head= curr_table->table;
+ }
if (!curr_table->select->cond)
curr_table->select->cond= sort_table_cond;
else
@@ -2845,7 +2849,7 @@ JOIN::exec()
curr_join->select_limit,
(select_options & OPTION_FOUND_ROWS ?
HA_POS_ERROR : unit->select_limit_cnt),
- curr_join->group_list ? TRUE : FALSE))
+ curr_join->group_list ? FALSE : TRUE))
DBUG_VOID_RETURN;
sortorder= curr_join->sortorder;
if (curr_join->const_tables != curr_join->table_count &&
@@ -7361,6 +7365,63 @@ bool JOIN_TAB::hash_join_is_possible()
}
+/**
+ @brief
+ Check whether a KEYUSE can be really used for access this join table
+
+ @param join Join structure with the best join order
+ for which the check is performed
+ @param keyuse Evaluated KEYUSE structure
+
+ @details
+ This function is supposed to be used after the best execution plan have been
+ already chosen and the JOIN_TAB array for the best join order been already set.
+ For a given KEYUSE to access this JOIN_TAB in the best execution plan the
+ function checks whether it really can be used. The function first performs
+ the check with access_from_tables_is_allowed(). If it succeeds it checks
+ whether the keyuse->val does not use some fields of a materialized semijoin
+ nest that cannot be used to build keys to access outer tables.
+ Such KEYUSEs exists for the query like this:
+ select * from ot
+ where ot.c in (select it1.c from it1, it2 where it1.c=f(it2.c))
+ Here we have two KEYUSEs to access table ot: with val=it1.c and val=f(it2.c).
+ However if the subquery was materialized the second KEYUSE cannot be employed
+ to access ot.
+
+ @retval true the given keyuse can be used for ref access of this JOIN_TAB
+ @retval false otherwise
+*/
+
+bool JOIN_TAB::keyuse_is_valid_for_access_in_chosen_plan(JOIN *join,
+ KEYUSE *keyuse)
+{
+ if (!access_from_tables_is_allowed(keyuse->used_tables,
+ join->sjm_lookup_tables))
+ return false;
+ if (join->sjm_scan_tables & table->map)
+ return true;
+ table_map keyuse_sjm_scan_tables= keyuse->used_tables &
+ join->sjm_scan_tables;
+ if (!keyuse_sjm_scan_tables)
+ return true;
+ uint sjm_tab_nr= 0;
+ while (!(keyuse_sjm_scan_tables & table_map(1) << sjm_tab_nr))
+ sjm_tab_nr++;
+ JOIN_TAB *sjm_tab= join->map2table[sjm_tab_nr];
+ TABLE_LIST *emb_sj_nest= sjm_tab->emb_sj_nest;
+ if (!(emb_sj_nest->sj_mat_info && emb_sj_nest->sj_mat_info->is_used &&
+ emb_sj_nest->sj_mat_info->is_sj_scan))
+ return true;
+ st_select_lex *sjm_sel= emb_sj_nest->sj_subq_pred->unit->first_select();
+ for (uint i= 0; i < sjm_sel->item_list.elements; i++)
+ {
+ if (sjm_sel->ref_pointer_array[i] == keyuse->val)
+ return true;
+ }
+ return false;
+}
+
+
static uint
cache_record_length(JOIN *join,uint idx)
{
@@ -7844,12 +7905,14 @@ get_best_combination(JOIN *join)
{
if (j->bush_children)
j= j->bush_children->start;
-
+
used_tables|= j->table->map;
- if ((keyuse= join->best_positions[tablenr].key) &&
- create_ref_for_key(join, j, keyuse, TRUE, used_tables))
- DBUG_RETURN(TRUE); // Something went wrong
-
+ if (j->type != JT_CONST && j->type != JT_SYSTEM)
+ {
+ if ((keyuse= join->best_positions[tablenr].key) &&
+ create_ref_for_key(join, j, keyuse, TRUE, used_tables))
+ DBUG_RETURN(TRUE); // Something went wrong
+ }
if (j->last_leaf_in_bush)
j= j->bush_root_tab;
}
@@ -7902,6 +7965,7 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
do
{
if (!(~used_tables & keyuse->used_tables) &&
+ join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse) &&
are_tables_local(join_tab, keyuse->used_tables))
{
if (first_keyuse)
@@ -7916,6 +7980,8 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
{
if (curr->keypart == keyuse->keypart &&
!(~used_tables & curr->used_tables) &&
+ join_tab->keyuse_is_valid_for_access_in_chosen_plan(join,
+ keyuse) &&
are_tables_local(join_tab, curr->used_tables))
break;
}
@@ -7949,6 +8015,7 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
do
{
if (!(~used_tables & keyuse->used_tables) &&
+ join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse) &&
are_tables_local(join_tab, keyuse->used_tables))
{
bool add_key_part= TRUE;
@@ -7958,7 +8025,9 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
{
if (curr->keypart == keyuse->keypart &&
!(~used_tables & curr->used_tables) &&
- are_tables_local(join_tab, curr->used_tables))
+ join_tab->keyuse_is_valid_for_access_in_chosen_plan(join,
+ curr) &&
+ are_tables_local(join_tab, curr->used_tables))
{
keyuse->keypart= NO_KEYPART;
add_key_part= FALSE;
@@ -8060,8 +8129,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
do
{
if (!(~used_tables & keyuse->used_tables) &&
- j->access_from_tables_is_allowed(keyuse->used_tables,
- join->sjm_lookup_tables))
+ j->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse))
{
if (are_tables_local(j, keyuse->val->used_tables()))
{
@@ -8130,8 +8198,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
for (i=0 ; i < keyparts ; keyuse++,i++)
{
while (((~used_tables) & keyuse->used_tables) ||
- !j->access_from_tables_is_allowed(keyuse->used_tables,
- join->sjm_lookup_tables) ||
+ !j->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse) ||
keyuse->keypart == NO_KEYPART ||
(keyuse->keypart !=
(is_hash_join_key_no(key) ?
@@ -8759,12 +8826,20 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
/*
Step #2: Extract WHERE/ON parts
*/
+ uint i;
+ for (i= join->top_join_tab_count - 1; i >= join->const_tables; i--)
+ {
+ if (!join->join_tab[i].bush_children)
+ break;
+ }
+ uint last_top_base_tab_idx= i;
+
table_map save_used_tables= 0;
used_tables=((select->const_tables=join->const_table_map) |
OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
JOIN_TAB *tab;
table_map current_map;
- uint i= join->const_tables;
+ i= join->const_tables;
for (tab= first_depth_first_tab(join); tab;
tab= next_depth_first_tab(join, tab), i++)
{
@@ -8802,7 +8877,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
Following force including random expression in last table condition.
It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
*/
- if (tab == join->join_tab + join->top_join_tab_count - 1)
+ if (tab == join->join_tab + last_top_base_tab_idx)
current_map|= RAND_TABLE_BIT;
used_tables|=current_map;
@@ -8841,10 +8916,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
save_used_tables= 0;
}
else
- {
- tmp= make_cond_for_table(thd, cond, used_tables, current_map, i,
+ {
+ tmp= make_cond_for_table(thd, cond, used_tables, current_map, i,
FALSE, FALSE);
- }
+ }
/* Add conditions added by add_not_null_conds(). */
if (tab->select_cond)
add_cond_and_fix(thd, &tmp, tab->select_cond);
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 0623672840e..1bc1e4c2b7a 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -540,6 +540,8 @@ typedef struct st_join_table {
!(used_sjm_lookup_tables & ~emb_sj_nest->sj_inner_tables));
}
+ bool keyuse_is_valid_for_access_in_chosen_plan(JOIN *join, KEYUSE *keyuse);
+
} JOIN_TAB;
@@ -1003,6 +1005,11 @@ public:
to materialize and access by lookups
*/
table_map sjm_lookup_tables;
+ /**
+ Bitmap of semijoin tables that the chosen plan decided
+ to materialize to scan the results of materialization
+ */
+ table_map sjm_scan_tables;
/*
Constant tables for which we have found a row (as opposed to those for
which we didn't).
@@ -1331,6 +1338,7 @@ public:
pre_sort_join_tab= NULL;
emb_sjm_nest= NULL;
sjm_lookup_tables= 0;
+ sjm_scan_tables= 0;
/*
The following is needed because JOIN::cleanup(true) may be called for
joins for which JOIN::optimize was aborted with an error before a proper
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 95ce1c9b940..2d816e0309d 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
- Copyright (c) 2010, 2014, SkySQL Ab.
+/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
+ Copyright (c) 2010, 2017, Corporation
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -362,6 +362,19 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
Item *item_tmp;
while ((item_tmp= it++))
{
+ /*
+ If the outer query has a GROUP BY clause, an outer reference to this
+ query block may have been wrapped in a Item_outer_ref, which has not
+ been fixed yet. An Item_type_holder must be created based on a fixed
+ Item, so use the inner Item instead.
+ */
+ DBUG_ASSERT(item_tmp->fixed ||
+ (item_tmp->type() == Item::REF_ITEM &&
+ ((Item_ref *)(item_tmp))->ref_type() ==
+ Item_ref::OUTER_REF));
+ if (!item_tmp->fixed)
+ item_tmp= item_tmp->real_item();
+
/* Error's in 'new' will be detected after loop */
types.push_back(new Item_type_holder(thd_arg, item_tmp));
}
@@ -1070,4 +1083,3 @@ void st_select_lex_unit::set_unique_exclude()
}
}
}
-
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 581a5f18746..a0475c136ae 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -2194,6 +2194,10 @@ static bool fix_sql_mode(sys_var *self, THD *thd, enum_var_type type)
thd->server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
else
thd->server_status&= ~SERVER_STATUS_NO_BACKSLASH_ESCAPES;
+ if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
+ thd->server_status|= SERVER_STATUS_ANSI_QUOTES;
+ else
+ thd->server_status&= ~SERVER_STATUS_ANSI_QUOTES;
}
return false;
}
diff --git a/sql/threadpool_unix.cc b/sql/threadpool_unix.cc
index 6075c758e40..0ffe08a8051 100644
--- a/sql/threadpool_unix.cc
+++ b/sql/threadpool_unix.cc
@@ -979,24 +979,26 @@ static void thread_group_close(thread_group_t *thread_group)
if (pipe(thread_group->shutdown_pipe))
{
- DBUG_VOID_RETURN;
+ goto end;
}
/* Wake listener */
if (io_poll_associate_fd(thread_group->pollfd,
thread_group->shutdown_pipe[0], NULL))
{
- DBUG_VOID_RETURN;
+ goto end;
+ }
+ {
+ char c= 0;
+ if (write(thread_group->shutdown_pipe[1], &c, 1) < 0)
+ goto end;
}
- char c= 0;
- if (write(thread_group->shutdown_pipe[1], &c, 1) < 0)
- DBUG_VOID_RETURN;
-
/* Wake all workers. */
while(wake_thread(thread_group) == 0)
{
}
+end:
mysql_mutex_unlock(&thread_group->mutex);
DBUG_VOID_RETURN;
diff --git a/sql/uniques.cc b/sql/uniques.cc
index fe3e329cda6..8b7da7e6e52 100644
--- a/sql/uniques.cc
+++ b/sql/uniques.cc
@@ -461,7 +461,7 @@ C_MODE_END
<> 0 error
*/
-static bool merge_walk(uchar *merge_buffer, ulong merge_buffer_size,
+static bool merge_walk(uchar *merge_buffer, size_t merge_buffer_size,
uint key_length, BUFFPEK *begin, BUFFPEK *end,
tree_walk_action walk_action, void *walk_action_arg,
qsort_cmp2 compare, void *compare_arg,
@@ -470,7 +470,7 @@ static bool merge_walk(uchar *merge_buffer, ulong merge_buffer_size,
BUFFPEK_COMPARE_CONTEXT compare_context = { compare, compare_arg };
QUEUE queue;
if (end <= begin ||
- merge_buffer_size < (ulong) (key_length * (end - begin + 1)) ||
+ merge_buffer_size < (size_t) (key_length * (end - begin + 1)) ||
init_queue(&queue, (uint) (end - begin), offsetof(BUFFPEK, key), 0,
buffpek_compare, &compare_context, 0, 0))
return 1;
@@ -607,15 +607,19 @@ bool Unique::walk(TABLE *table, tree_walk_action action, void *walk_action_arg)
return 1;
if (flush_io_cache(&file) || reinit_io_cache(&file, READ_CACHE, 0L, 0, 0))
return 1;
- size_t buff_sz= (max_in_memory_size / full_size + 1) * full_size;
+ /*
+ merge_buffer must fit at least MERGEBUFF2 keys, because
+ merge_index() can merge that many BUFFPEKs at once.
+ */
+ size_t buff_sz= max(MERGEBUFF2, max_in_memory_size/full_size+1) * full_size;
if (!(merge_buffer = (uchar *)my_malloc(buff_sz, MYF(MY_WME))))
return 1;
if (buff_sz < (ulong) (full_size * (file_ptrs.elements + 1)))
- res= merge(table, merge_buffer, buff_sz >= full_size * MERGEBUFF2) ;
+ res= merge(table, merge_buffer, true) ;
if (!res)
{
- res= merge_walk(merge_buffer, (ulong) max_in_memory_size, full_size,
+ res= merge_walk(merge_buffer, buff_sz, full_size,
(BUFFPEK *) file_ptrs.buffer,
(BUFFPEK *) file_ptrs.buffer + file_ptrs.elements,
action, walk_action_arg,
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index 872373bbeb6..d39d1187ce6 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -1640,7 +1640,6 @@ int ha_archive::info(uint flag)
stats.update_time= (ulong) file_stat.st_mtime;
if (flag & HA_STATUS_CONST)
{
- stats.max_data_file_length= share->rows_recorded * stats.mean_rec_length;
stats.max_data_file_length= MAX_FILE_SIZE;
stats.create_time= (ulong) file_stat.st_ctime;
}
diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
index a5e1c045b7b..80a15ffe0d5 100644
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
@@ -2560,14 +2560,8 @@ wait_until_unfixed:
}
}
buf_pool_mutex_exit(buf_pool);
- fprintf(stderr,
- "innodb_change_buffering_debug evict %u %u\n",
- (unsigned) space, (unsigned) offset);
return(NULL);
} else if (buf_flush_page_try(buf_pool, block)) {
- fprintf(stderr,
- "innodb_change_buffering_debug flush %u %u\n",
- (unsigned) space, (unsigned) offset);
guess = block;
goto loop;
}
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index fb35edc3be3..198df72a1d6 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -4250,6 +4250,8 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
}
*/
DBUG_PRINT("info", ("is quick repair: %d", (int) rep_quick));
+ if (!rep_quick)
+ my_b_clear(&new_data_cache);
/* Initialize pthread structures before goto err. */
mysql_mutex_init(key_SORT_INFO_mutex, &sort_info.mutex, MY_MUTEX_INIT_FAST);
@@ -4608,7 +4610,7 @@ err:
already or they were not yet started (if the error happend before
creating the threads).
*/
- if (!rep_quick)
+ if (!rep_quick && my_b_inited(&new_data_cache))
end_io_cache(&new_data_cache);
if (!got_error)
{
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index bf2205f5a4c..e2e52546fc9 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -1269,6 +1269,7 @@ static my_bool translog_set_lsn_for_files(uint32 from_file, uint32 to_file,
mysql_file_close(fd, MYF(MY_WME))))
{
translog_stop_writing();
+ mysql_mutex_unlock(&log_descriptor.file_header_lock);
DBUG_RETURN(1);
}
}
@@ -2291,10 +2292,11 @@ static void translog_set_only_in_buffers(TRANSLOG_ADDRESS in_buffers)
if (cmp_translog_addr(in_buffers, log_descriptor.in_buffers_only) > 0)
{
if (translog_status != TRANSLOG_OK)
- DBUG_VOID_RETURN;
+ goto end;
log_descriptor.in_buffers_only= in_buffers;
DBUG_PRINT("info", ("set new in_buffers_only"));
}
+end:
mysql_mutex_unlock(&log_descriptor.sent_to_disk_lock);
DBUG_VOID_RETURN;
}
@@ -7814,8 +7816,24 @@ void translog_flush_buffers(TRANSLOG_ADDRESS *lsn,
translog_force_current_buffer_to_finish();
translog_buffer_unlock(buffer);
}
- else if (log_descriptor.bc.buffer->prev_last_lsn != LSN_IMPOSSIBLE)
+ else
{
+ if (log_descriptor.bc.buffer->last_lsn == LSN_IMPOSSIBLE)
+ {
+ /*
+ In this case both last_lsn & prev_last_lsn are LSN_IMPOSSIBLE
+ otherwise it will go in the first IF because LSN_IMPOSSIBLE less
+ then any real LSN and cmp_translog_addr(*lsn,
+ log_descriptor.bc.buffer->prev_last_lsn) will be TRUE
+ */
+ DBUG_ASSERT(log_descriptor.bc.buffer->prev_last_lsn ==
+ LSN_IMPOSSIBLE);
+ DBUG_PRINT("info", ("There is no LSNs yet generated => do nothing"));
+ translog_unlock();
+ DBUG_VOID_RETURN;
+ }
+
+ DBUG_ASSERT(log_descriptor.bc.buffer->prev_last_lsn != LSN_IMPOSSIBLE);
/* fix lsn if it was horizon */
*lsn= log_descriptor.bc.buffer->prev_last_lsn;
DBUG_PRINT("info", ("LSN to flush fixed to prev last lsn: (%lu,0x%lx)",
@@ -7824,13 +7842,6 @@ void translog_flush_buffers(TRANSLOG_ADDRESS *lsn,
TRANSLOG_BUFFERS_NO);
translog_unlock();
}
- else if (log_descriptor.bc.buffer->last_lsn == LSN_IMPOSSIBLE)
- {
- DBUG_PRINT("info", ("There is no LSNs yet generated => do nothing"));
- translog_unlock();
- DBUG_VOID_RETURN;
- }
-
/* flush buffers */
*sent_to_disk= translog_get_sent_to_disk();
if (cmp_translog_addr(*lsn, *sent_to_disk) > 0)
diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c
index 1a791d43034..bb9f5a03ad7 100644
--- a/storage/maria/ma_pagecache.c
+++ b/storage/maria/ma_pagecache.c
@@ -3474,6 +3474,7 @@ restart:
lock_to_read[lock].unlock_lock,
unlock_pin, FALSE))
{
+ pagecache_pthread_mutex_unlock(&pagecache->cache_lock);
DBUG_ASSERT(0);
return (uchar*) 0;
}
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index 5e42ebc8d5d..b2e8705b15e 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -887,9 +887,7 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
if (create_database_if_not_exists(name))
goto end;
fn_format(filename, name, "", MARIA_NAME_IEXT,
- (MY_UNPACK_FILENAME |
- (flags & HA_DONT_TOUCH_DATA) ? MY_RETURN_REAL_PATH : 0) |
- MY_APPEND_EXT);
+ MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH | MY_APPEND_EXT);
linkname_ptr= NULL;
create_flag= MY_DELETE_OLD;
tprint(tracef, "Table '%s' creating as '%s'\n", name, filename);
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index df97d6035d8..23e54966e2d 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -2676,6 +2676,8 @@ int mi_repair_parallel(HA_CHECK *param, register MI_INFO *info,
*/
DBUG_PRINT("info", ("is quick repair: %d", rep_quick));
bzero((char*)&sort_info,sizeof(sort_info));
+ if (!rep_quick)
+ my_b_clear(&new_data_cache);
/* Initialize pthread structures before goto err. */
mysql_mutex_init(mi_key_mutex_MI_SORT_INFO_mutex,
&sort_info.mutex, MY_MUTEX_INIT_FAST);
@@ -3050,7 +3052,7 @@ err:
already or they were not yet started (if the error happend before
creating the threads).
*/
- if (!rep_quick)
+ if (!rep_quick && my_b_inited(&new_data_cache))
(void) end_io_cache(&new_data_cache);
if (!got_error)
{
diff --git a/storage/myisam/mysql-test/storage_engine/parts/disabled.def b/storage/myisam/mysql-test/storage_engine/parts/disabled.def
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/parts/disabled.def
diff --git a/storage/xtradb/btr/btr0btr.c b/storage/xtradb/btr/btr0btr.c
index fb670df2329..76c2d9cd8ae 100644
--- a/storage/xtradb/btr/btr0btr.c
+++ b/storage/xtradb/btr/btr0btr.c
@@ -2958,7 +2958,7 @@ Removes a page from the level list of pages.
/*************************************************************//**
Removes a page from the level list of pages. */
-static __attribute__((nonnull))
+static
void
btr_level_list_remove_func(
/*=======================*/
diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c
index 5f6ae046dbf..73cfc62d960 100644
--- a/storage/xtradb/buf/buf0buf.c
+++ b/storage/xtradb/buf/buf0buf.c
@@ -2852,9 +2852,6 @@ wait_until_unfixed:
}
}
//buf_pool_mutex_exit(buf_pool);
- fprintf(stderr,
- "innodb_change_buffering_debug evict %u %u\n",
- (unsigned) space, (unsigned) offset);
return(NULL);
} else if (UNIV_UNLIKELY(buf_block_get_state(block)
@@ -2875,9 +2872,6 @@ wait_until_unfixed:
ut_ad(!mutex_own(&buf_pool->LRU_list_mutex));
if (buf_flush_page_try(buf_pool, block)) {
- fprintf(stderr,
- "innodb_change_buffering_debug flush %u %u\n",
- (unsigned) space, (unsigned) offset);
guess = block;
goto loop;
}
diff --git a/storage/xtradb/dict/dict0crea.c b/storage/xtradb/dict/dict0crea.c
index 1529c22bbb9..e9484a04176 100644
--- a/storage/xtradb/dict/dict0crea.c
+++ b/storage/xtradb/dict/dict0crea.c
@@ -115,8 +115,8 @@ dict_create_sys_tables_tuple(
if (table->flags & (~DICT_TF_COMPACT & ~(~0U << DICT_TF_BITS))) {
ut_a(table->flags & DICT_TF_COMPACT);
ut_a(dict_table_get_format(table) >= DICT_TF_FORMAT_ZIP);
- ut_a(((ulonglong) table->flags & DICT_TF_ZSSIZE_MASK)
- <= (ulonglong) (DICT_TF_ZSSIZE_MAX << DICT_TF_ZSSIZE_SHIFT));
+ ut_a((table->flags & DICT_TF_ZSSIZE_MASK)
+ <= (DICT_TF_ZSSIZE_MAX << DICT_TF_ZSSIZE_SHIFT));
ut_a(!(table->flags & (~0U << DICT_TF2_BITS)));
mach_write_to_4(ptr, table->flags & ~(~0U << DICT_TF_BITS));
} else {
diff --git a/storage/xtradb/fsp/fsp0fsp.c b/storage/xtradb/fsp/fsp0fsp.c
index 4477b34f7b4..433fcdc8ffe 100644
--- a/storage/xtradb/fsp/fsp0fsp.c
+++ b/storage/xtradb/fsp/fsp0fsp.c
@@ -249,8 +249,7 @@ fsp_fill_free_list(
then we do not allocate more extents */
ulint space, /*!< in: space */
fsp_header_t* header, /*!< in/out: space header */
- mtr_t* mtr) /*!< in/out: mini-transaction */
- __attribute__((nonnull));
+ mtr_t* mtr); /*!< in/out: mini-transaction */
/**********************************************************************//**
Allocates a single free page from a segment. This function implements
the intelligent allocation strategy which tries to minimize file space
@@ -279,7 +278,7 @@ fseg_alloc_free_page_low(
in which the page should be initialized.
If init_mtr!=mtr, but the page is already
latched in mtr, do not initialize the page. */
- __attribute__((warn_unused_result, nonnull));
+ __attribute__((warn_unused_result));
#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
@@ -1568,7 +1567,7 @@ Allocates a single free page from a space. The page is marked as used.
@retval block, rw_lock_x_lock_count(&block->lock) == 1 if allocation succeeded
(init_mtr == mtr, or the page was not previously freed in mtr)
@retval block (not allocated or initialized) otherwise */
-static __attribute__((nonnull, warn_unused_result))
+static __attribute__((warn_unused_result))
buf_block_t*
fsp_alloc_free_page(
/*================*/
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index c868fbbedea..9f05a8a751c 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -7423,29 +7423,7 @@ i_s_innodb_changed_pages_fill(
while(log_online_bitmap_iterator_next(&i) &&
(!srv_max_changed_pages ||
- output_rows_num < srv_max_changed_pages) &&
- /*
- There is no need to compare both start LSN and end LSN fields
- with maximum value. It's enough to compare only start LSN.
- Example:
-
- max_lsn = 100
- \\\\\\\\\\\\\\\\\\\\\\\\\|\\\\\\\\ - Query 1
- I------I I-------I I-------------I I----I
- ////////////////// | - Query 2
- 1 2 3 4
-
- Query 1:
- SELECT * FROM INNODB_CHANGED_PAGES WHERE start_lsn < 100
- will select 1,2,3 bitmaps
- Query 2:
- SELECT * FROM INNODB_CHANGED_PAGES WHERE end_lsn < 100
- will select 1,2 bitmaps
-
- The condition start_lsn <= 100 will be false after reading
- 1,2,3 bitmaps which suits for both cases.
- */
- LOG_BITMAP_ITERATOR_START_LSN(i) <= max_lsn)
+ output_rows_num < srv_max_changed_pages))
{
if (!LOG_BITMAP_ITERATOR_PAGE_CHANGED(i))
continue;
diff --git a/storage/xtradb/include/btr0cur.h b/storage/xtradb/include/btr0cur.h
index 25f987cb8e1..97dd0ba4618 100644
--- a/storage/xtradb/include/btr0cur.h
+++ b/storage/xtradb/include/btr0cur.h
@@ -261,7 +261,7 @@ btr_cur_update_alloc_zip(
FALSE=update-in-place */
mtr_t* mtr, /*!< in: mini-transaction */
trx_t* trx) /*!< in: NULL or transaction */
- __attribute__((nonnull (1, 2, 3, 6), warn_unused_result));
+ __attribute__((warn_unused_result));
/*************************************************************//**
Updates a record when the update causes no size changes in its fields.
@return DB_SUCCESS or error number */
@@ -345,8 +345,7 @@ btr_cur_del_mark_set_clust_rec(
const ulint* offsets,/*!< in: rec_get_offsets(rec) */
ibool val, /*!< in: value to set */
que_thr_t* thr, /*!< in: query thread */
- mtr_t* mtr) /*!< in: mtr */
- __attribute__((nonnull));
+ mtr_t* mtr); /*!< in: mtr */
/***********************************************************//**
Sets a secondary index record delete mark to TRUE or FALSE.
@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
@@ -499,8 +498,7 @@ btr_cur_disown_inherited_fields(
dict_index_t* index, /*!< in: index of the page */
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
const upd_t* update, /*!< in: update vector */
- mtr_t* mtr) /*!< in/out: mini-transaction */
- __attribute__((nonnull(2,3,4,5,6)));
+ mtr_t* mtr); /*!< in/out: mini-transaction */
/** Operation code for btr_store_big_rec_extern_fields(). */
enum blob_op {
@@ -545,7 +543,7 @@ btr_store_big_rec_extern_fields(
mtr_t* btr_mtr, /*!< in: mtr containing the
latches to the clustered index */
enum blob_op op) /*! in: operation code */
- __attribute__((nonnull, warn_unused_result));
+ __attribute__((warn_unused_result));
/*******************************************************************//**
Frees the space in an externally stored field to the file space
@@ -621,8 +619,7 @@ btr_push_update_extern_fields(
/*==========================*/
dtuple_t* tuple, /*!< in/out: data tuple */
const upd_t* update, /*!< in: update vector */
- mem_heap_t* heap) /*!< in: memory heap */
- __attribute__((nonnull));
+ mem_heap_t* heap); /*!< in: memory heap */
/***********************************************************//**
Sets a secondary index record's delete mark to the given value. This
function is only used by the insert buffer merge mechanism. */
diff --git a/storage/xtradb/include/btr0sea.h b/storage/xtradb/include/btr0sea.h
index 39c0a66fb9a..bdffe402277 100644
--- a/storage/xtradb/include/btr0sea.h
+++ b/storage/xtradb/include/btr0sea.h
@@ -205,14 +205,14 @@ hash_table_t*
btr_search_get_hash_table(
/*======================*/
const dict_index_t* index) /*!< in: index */
- __attribute__((nonnull,pure,warn_unused_result));
+ __attribute__((warn_unused_result));
UNIV_INLINE
rw_lock_t*
btr_search_get_latch(
/*=================*/
const dict_index_t* index) /*!< in: index */
- __attribute__((nonnull,pure,warn_unused_result));
+ __attribute__((warn_unused_result));
/*********************************************************************//**
Returns the AHI partition number corresponding to a given index ID. */
@@ -229,8 +229,7 @@ UNIV_INLINE
void
btr_search_index_init(
/*===============*/
- dict_index_t* index) /*!< in: index */
- __attribute__((nonnull));
+ dict_index_t* index); /*!< in: index */
UNIV_INLINE
void
diff --git a/storage/xtradb/include/buf0buddy.ic b/storage/xtradb/include/buf0buddy.ic
index d7053881caa..2b5e62e97b2 100644
--- a/storage/xtradb/include/buf0buddy.ic
+++ b/storage/xtradb/include/buf0buddy.ic
@@ -51,7 +51,7 @@ buf_buddy_alloc_low(
buf_pool->mutex was temporarily
released */
ibool have_page_hash_mutex)
- __attribute__((malloc, nonnull));
+ __attribute__((malloc));
/**********************************************************************//**
Deallocate a block. */
diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h
index 23692c92c09..d584062a81f 100644
--- a/storage/xtradb/include/buf0buf.h
+++ b/storage/xtradb/include/buf0buf.h
@@ -274,8 +274,7 @@ buf_relocate(
buf_page_t* bpage, /*!< in/out: control block being relocated;
buf_page_get_state(bpage) must be
BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_ZIP_PAGE */
- buf_page_t* dpage) /*!< in/out: destination control block */
- __attribute__((nonnull));
+ buf_page_t* dpage); /*!< in/out: destination control block */
/*********************************************************************//**
Gets the current size of buffer buf_pool in bytes.
@return size in bytes */
diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h
index 3d05f40eb08..d8c8e39b1bf 100644
--- a/storage/xtradb/include/dict0dict.h
+++ b/storage/xtradb/include/dict0dict.h
@@ -605,7 +605,7 @@ ulint
dict_index_is_clust(
/*================*/
const dict_index_t* index) /*!< in: index */
- __attribute__((nonnull, pure, warn_unused_result));
+ __attribute__((warn_unused_result));
/********************************************************************//**
Check whether the index is unique.
@return nonzero for unique index, zero for other indexes */
@@ -614,7 +614,7 @@ ulint
dict_index_is_unique(
/*=================*/
const dict_index_t* index) /*!< in: index */
- __attribute__((nonnull, pure, warn_unused_result));
+ __attribute__((warn_unused_result));
/********************************************************************//**
Check whether the index is the insert buffer tree.
@return nonzero for insert buffer, zero for other indexes */
@@ -623,7 +623,7 @@ ulint
dict_index_is_ibuf(
/*===============*/
const dict_index_t* index) /*!< in: index */
- __attribute__((nonnull, pure, warn_unused_result));
+ __attribute__((warn_unused_result));
/********************************************************************//**
Check whether the index is a secondary index or the insert buffer tree.
@return nonzero for insert buffer, zero for other indexes */
@@ -632,7 +632,7 @@ ulint
dict_index_is_sec_or_ibuf(
/*======================*/
const dict_index_t* index) /*!< in: index */
- __attribute__((nonnull, pure, warn_unused_result));
+ __attribute__((warn_unused_result));
/********************************************************************//**
Gets the number of user-defined columns in a table in the dictionary
@@ -643,7 +643,7 @@ ulint
dict_table_get_n_user_cols(
/*=======================*/
const dict_table_t* table) /*!< in: table */
- __attribute__((nonnull, pure, warn_unused_result));
+ __attribute__((warn_unused_result));
/********************************************************************//**
Gets the number of system columns in a table in the dictionary cache.
@return number of system (e.g., ROW_ID) columns of a table */
@@ -662,7 +662,7 @@ ulint
dict_table_get_n_cols(
/*==================*/
const dict_table_t* table) /*!< in: table */
- __attribute__((nonnull, pure, warn_unused_result));
+ __attribute__((warn_unused_result));
#ifdef UNIV_DEBUG
/********************************************************************//**
Gets the nth column of a table.
@@ -1321,7 +1321,7 @@ ulint
dict_index_is_corrupted(
/*====================*/
const dict_index_t* index) /*!< in: index */
- __attribute__((nonnull, pure, warn_unused_result));
+ __attribute__((warn_unused_result));
#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
@@ -1332,7 +1332,7 @@ void
dict_set_corrupted(
/*===============*/
dict_index_t* index) /*!< in/out: index */
- UNIV_COLD __attribute__((nonnull));
+ UNIV_COLD;
/**********************************************************************//**
Flags an index corrupted in the data dictionary cache only. This
diff --git a/storage/xtradb/include/dyn0dyn.h b/storage/xtradb/include/dyn0dyn.h
index 62ed862e82c..e3517108a29 100644
--- a/storage/xtradb/include/dyn0dyn.h
+++ b/storage/xtradb/include/dyn0dyn.h
@@ -47,9 +47,8 @@ UNIV_INLINE
dyn_array_t*
dyn_array_create(
/*=============*/
- dyn_array_t* arr) /*!< in/out memory buffer of
+ dyn_array_t* arr); /*!< in/out memory buffer of
size sizeof(dyn_array_t) */
- __attribute__((nonnull));
/************************************************************//**
Frees a dynamic array. */
UNIV_INLINE
@@ -70,7 +69,7 @@ dyn_array_open(
dyn_array_t* arr, /*!< in: dynamic array */
ulint size) /*!< in: size in bytes of the buffer; MUST be
smaller than DYN_ARRAY_DATA_SIZE! */
- __attribute__((nonnull, warn_unused_result));
+ __attribute__((warn_unused_result));
/*********************************************************************//**
Closes the buffer returned by dyn_array_open. */
UNIV_INLINE
@@ -78,8 +77,7 @@ void
dyn_array_close(
/*============*/
dyn_array_t* arr, /*!< in: dynamic array */
- const byte* ptr) /*!< in: end of used space */
- __attribute__((nonnull));
+ const byte* ptr); /*!< in: end of used space */
/*********************************************************************//**
Makes room on top of a dyn array and returns a pointer to
the added element. The caller must copy the element to
@@ -91,7 +89,7 @@ dyn_array_push(
/*===========*/
dyn_array_t* arr, /*!< in/out: dynamic array */
ulint size) /*!< in: size in bytes of the element */
- __attribute__((nonnull, warn_unused_result));
+ __attribute__((warn_unused_result));
/************************************************************//**
Returns pointer to an element in dyn array.
@return pointer to element */
@@ -102,7 +100,7 @@ dyn_array_get_element(
const dyn_array_t* arr, /*!< in: dyn array */
ulint pos) /*!< in: position of element
in bytes from array start */
- __attribute__((nonnull, warn_unused_result));
+ __attribute__((warn_unused_result));
/************************************************************//**
Returns the size of stored data in a dyn array.
@return data size in bytes */
@@ -111,7 +109,7 @@ ulint
dyn_array_get_data_size(
/*====================*/
const dyn_array_t* arr) /*!< in: dyn array */
- __attribute__((nonnull, warn_unused_result, pure));
+ __attribute__((warn_unused_result));
/************************************************************//**
Gets the first block in a dyn array.
@param arr dyn array
@@ -145,7 +143,7 @@ ulint
dyn_block_get_used(
/*===============*/
const dyn_block_t* block) /*!< in: dyn array block */
- __attribute__((nonnull, warn_unused_result, pure));
+ __attribute__((warn_unused_result));
/********************************************************************//**
Gets pointer to the start of data in a dyn array block.
@return pointer to data */
@@ -154,7 +152,7 @@ byte*
dyn_block_get_data(
/*===============*/
const dyn_block_t* block) /*!< in: dyn array block */
- __attribute__((nonnull, warn_unused_result, pure));
+ __attribute__((warn_unused_result));
/********************************************************//**
Pushes n bytes to a dyn array. */
UNIV_INLINE
diff --git a/storage/xtradb/include/dyn0dyn.ic b/storage/xtradb/include/dyn0dyn.ic
index 2565a249271..137ad2b88c7 100644
--- a/storage/xtradb/include/dyn0dyn.ic
+++ b/storage/xtradb/include/dyn0dyn.ic
@@ -36,7 +36,7 @@ dyn_block_t*
dyn_array_add_block(
/*================*/
dyn_array_t* arr) /*!< in/out: dyn array */
- __attribute__((nonnull, warn_unused_result));
+ __attribute__((warn_unused_result));
/********************************************************************//**
Gets the number of used bytes in a dyn array block.
diff --git a/storage/xtradb/include/log0online.h b/storage/xtradb/include/log0online.h
index 02d75001505..2462263dec2 100644
--- a/storage/xtradb/include/log0online.h
+++ b/storage/xtradb/include/log0online.h
@@ -37,19 +37,25 @@ log_online_bitmap_file_range_t;
/** An iterator over changed page info */
typedef struct log_bitmap_iterator_struct log_bitmap_iterator_t;
-/*********************************************************************//**
-Initializes the online log following subsytem. */
+/** Initialize the constant part of the log tracking subsystem */
+UNIV_INTERN
+void
+log_online_init(void);
+
+/** Initialize the dynamic part of the log tracking subsystem */
UNIV_INTERN
void
log_online_read_init(void);
-/*=======================*/
-/*********************************************************************//**
-Shuts down the online log following subsystem. */
+/** Shut down the dynamic part of the log tracking subsystem */
UNIV_INTERN
void
log_online_read_shutdown(void);
-/*===========================*/
+
+/** Shut down the constant part of the log tracking subsystem */
+UNIV_INTERN
+void
+log_online_shutdown(void);
/*********************************************************************//**
Reads and parses the redo log up to last checkpoint LSN to build the changed
@@ -159,6 +165,8 @@ struct log_online_bitmap_file_range_struct {
/** Struct for an iterator through all bits of changed pages bitmap blocks */
struct log_bitmap_iterator_struct
{
+ ib_uint64_t max_lsn; /*!< End LSN of the
+ range */
ibool failed; /*!< Has the iteration
stopped prematurely */
log_online_bitmap_file_range_t in_files; /*!< The bitmap files
diff --git a/storage/xtradb/include/mach0data.h b/storage/xtradb/include/mach0data.h
index 81c0866f367..d9a4a9170c7 100644
--- a/storage/xtradb/include/mach0data.h
+++ b/storage/xtradb/include/mach0data.h
@@ -51,7 +51,7 @@ ulint
mach_read_from_1(
/*=============*/
const byte* b) /*!< in: pointer to byte */
- __attribute__((nonnull, pure));
+ __attribute__((warn_unused_result));
/*******************************************************//**
The following function is used to store data in two consecutive
bytes. We store the most significant byte to the lower address. */
@@ -112,7 +112,7 @@ ulint
mach_read_from_3(
/*=============*/
const byte* b) /*!< in: pointer to 3 bytes */
- __attribute__((nonnull, pure));
+ __attribute__((warn_unused_result));
/*******************************************************//**
The following function is used to store data in four consecutive
bytes. We store the most significant byte to the lowest address. */
@@ -131,7 +131,7 @@ ulint
mach_read_from_4(
/*=============*/
const byte* b) /*!< in: pointer to four bytes */
- __attribute__((nonnull, pure));
+ __attribute__((warn_unused_result));
/*********************************************************//**
Writes a ulint in a compressed form (1..5 bytes).
@return stored size in bytes */
@@ -158,7 +158,7 @@ ulint
mach_read_compressed(
/*=================*/
const byte* b) /*!< in: pointer to memory from where to read */
- __attribute__((nonnull, pure));
+ __attribute__((warn_unused_result));
/*******************************************************//**
The following function is used to store data in 6 consecutive
bytes. We store the most significant byte to the lowest address. */
@@ -177,7 +177,7 @@ ib_uint64_t
mach_read_from_6(
/*=============*/
const byte* b) /*!< in: pointer to 6 bytes */
- __attribute__((nonnull, pure));
+ __attribute__((warn_unused_result));
/*******************************************************//**
The following function is used to store data in 7 consecutive
bytes. We store the most significant byte to the lowest address. */
@@ -196,7 +196,7 @@ ib_uint64_t
mach_read_from_7(
/*=============*/
const byte* b) /*!< in: pointer to 7 bytes */
- __attribute__((nonnull, pure));
+ __attribute__((warn_unused_result));
/*******************************************************//**
The following function is used to store data in 8 consecutive
bytes. We store the most significant byte to the lowest address. */
@@ -241,7 +241,7 @@ ib_uint64_t
mach_ull_read_compressed(
/*=====================*/
const byte* b) /*!< in: pointer to memory from where to read */
- __attribute__((nonnull, pure));
+ __attribute__((warn_unused_result));
/*********************************************************//**
Writes a 64-bit integer in a compressed form (1..11 bytes).
@return size in bytes */
@@ -268,7 +268,7 @@ ib_uint64_t
mach_ull_read_much_compressed(
/*==========================*/
const byte* b) /*!< in: pointer to memory from where to read */
- __attribute__((nonnull, pure));
+ __attribute__((warn_unused_result));
/*********************************************************//**
Reads a ulint in a compressed form if the log record fully contains it.
@return pointer to end of the stored field, NULL if not complete */
diff --git a/storage/xtradb/include/mtr0mtr.h b/storage/xtradb/include/mtr0mtr.h
index 031fccd300c..bb60ffbd9bb 100644
--- a/storage/xtradb/include/mtr0mtr.h
+++ b/storage/xtradb/include/mtr0mtr.h
@@ -205,8 +205,7 @@ UNIV_INTERN
void
mtr_commit(
/*=======*/
- mtr_t* mtr) /*!< in/out: mini-transaction */
- __attribute__((nonnull));
+ mtr_t* mtr); /*!< in/out: mini-transaction */
/**********************************************************//**
Sets and returns a savepoint in mtr.
@return savepoint */
@@ -311,7 +310,7 @@ mtr_memo_contains(
mtr_t* mtr, /*!< in: mtr */
const void* object, /*!< in: object to search */
ulint type) /*!< in: type of object */
- __attribute__((warn_unused_result, nonnull));
+ __attribute__((warn_unused_result));
/**********************************************************//**
Checks if memo contains the given page.
diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h
index 71da5ea6125..618d6f540ae 100644
--- a/storage/xtradb/include/os0file.h
+++ b/storage/xtradb/include/os0file.h
@@ -515,9 +515,10 @@ os_file_create_simple_no_error_handling_func(
it would be enabled otherwise). */
ibool* success);/*!< out: TRUE if succeed, FALSE if error */
/****************************************************************//**
-Tries to disable OS caching on an opened file descriptor. */
+Tries to disable OS caching on an opened file descriptor.
+@return TRUE if operation is success and FALSE otherwise */
UNIV_INTERN
-void
+ibool
os_file_set_nocache(
/*================*/
int fd, /*!< in: file descriptor to alter */
diff --git a/storage/xtradb/include/page0page.h b/storage/xtradb/include/page0page.h
index ba1ee7a7d11..f7b9f9f06c8 100644
--- a/storage/xtradb/include/page0page.h
+++ b/storage/xtradb/include/page0page.h
@@ -231,8 +231,7 @@ ulint
page_header_get_offs(
/*=================*/
const page_t* page, /*!< in: page */
- ulint field) /*!< in: PAGE_FREE, ... */
- __attribute__((nonnull, pure));
+ ulint field); /*!< in: PAGE_FREE, ... */
/*************************************************************//**
Returns the pointer stored in the given header field, or NULL. */
@@ -792,8 +791,7 @@ page_copy_rec_list_end(
buf_block_t* block, /*!< in: index page containing rec */
rec_t* rec, /*!< in: record on page */
dict_index_t* index, /*!< in: record descriptor */
- mtr_t* mtr) /*!< in: mtr */
- __attribute__((nonnull));
+ mtr_t* mtr); /*!< in: mtr */
/*************************************************************//**
Copies records from page to new_page, up to the given record, NOT
including that record. Infimum and supremum records are not copied.
@@ -808,8 +806,7 @@ page_copy_rec_list_start(
buf_block_t* block, /*!< in: index page containing rec */
rec_t* rec, /*!< in: record on page */
dict_index_t* index, /*!< in: record descriptor */
- mtr_t* mtr) /*!< in: mtr */
- __attribute__((nonnull));
+ mtr_t* mtr); /*!< in: mtr */
/*************************************************************//**
Deletes records from a page from a given record onward, including that record.
The infimum and supremum records are not deleted. */
@@ -852,8 +849,7 @@ page_move_rec_list_end(
buf_block_t* block, /*!< in: index page from where to move */
rec_t* split_rec, /*!< in: first record to move */
dict_index_t* index, /*!< in: record descriptor */
- mtr_t* mtr) /*!< in: mtr */
- __attribute__((nonnull(1, 2, 4, 5)));
+ mtr_t* mtr); /*!< in: mtr */
/*************************************************************//**
Moves record list start to another page. Moved records do not include
split_rec.
@@ -877,8 +873,7 @@ page_dir_split_slot(
page_t* page, /*!< in: index page */
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
uncompressed part will be written, or NULL */
- ulint slot_no)/*!< in: the directory slot */
- __attribute__((nonnull(1)));
+ ulint slot_no);/*!< in: the directory slot */
/*************************************************************//**
Tries to balance the given directory slot with too few records
with the upper neighbor, so that there are at least the minimum number
@@ -890,8 +885,7 @@ page_dir_balance_slot(
/*==================*/
page_t* page, /*!< in/out: index page */
page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
- ulint slot_no)/*!< in: the directory slot */
- __attribute__((nonnull(1)));
+ ulint slot_no);/*!< in: the directory slot */
/**********************************************************//**
Parses a log record of a record list end or start deletion.
@return end of log record or NULL */
diff --git a/storage/xtradb/include/page0zip.h b/storage/xtradb/include/page0zip.h
index a33407e78bc..abd62ab99a5 100644
--- a/storage/xtradb/include/page0zip.h
+++ b/storage/xtradb/include/page0zip.h
@@ -402,8 +402,7 @@ page_zip_reorganize(
out: data, n_blobs,
m_start, m_end, m_nonempty */
dict_index_t* index, /*!< in: index of the B-tree node */
- mtr_t* mtr) /*!< in: mini-transaction */
- __attribute__((nonnull));
+ mtr_t* mtr); /*!< in: mini-transaction */
#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Copy the records of a page byte for byte. Do not copy the page header
@@ -436,7 +435,7 @@ page_zip_parse_compress(
byte* end_ptr,/*!< in: buffer end */
page_t* page, /*!< out: uncompressed page */
page_zip_des_t* page_zip)/*!< out: compressed page */
- __attribute__((nonnull(1,2)));
+ __attribute__((warn_unused_result));
/**********************************************************************//**
Calculate the compressed page checksum.
diff --git a/storage/xtradb/include/rem0rec.h b/storage/xtradb/include/rem0rec.h
index 7e76b4f40cb..239a02a83f8 100644
--- a/storage/xtradb/include/rem0rec.h
+++ b/storage/xtradb/include/rem0rec.h
@@ -626,8 +626,7 @@ rec_copy(
/*=====*/
void* buf, /*!< in: buffer */
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
- __attribute__((nonnull));
+ const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
#ifndef UNIV_HOTBACKUP
/**********************************************************//**
Determines the size of a data tuple prefix in a temporary file.
diff --git a/storage/xtradb/include/row0upd.h b/storage/xtradb/include/row0upd.h
index 16c069d5ae8..e23a71374c2 100644
--- a/storage/xtradb/include/row0upd.h
+++ b/storage/xtradb/include/row0upd.h
@@ -232,9 +232,8 @@ row_upd_index_replace_new_col_vals_index_pos(
/*!< in: if TRUE, limit the replacement to
ordering fields of index; note that this
does not work for non-clustered indexes. */
- mem_heap_t* heap) /*!< in: memory heap for allocating and
+ mem_heap_t* heap); /*!< in: memory heap for allocating and
copying the new values */
- __attribute__((nonnull));
/***********************************************************//**
Replaces the new column values stored in the update vector to the index entry
given. */
@@ -295,7 +294,7 @@ row_upd_changes_ord_field_binary_func(
compile time */
const row_ext_t*ext) /*!< NULL, or prefixes of the externally
stored columns in the old row */
- __attribute__((nonnull(1,2), warn_unused_result));
+ __attribute__((warn_unused_result));
#ifdef UNIV_DEBUG
# define row_upd_changes_ord_field_binary(index,update,thr,row,ext) \
row_upd_changes_ord_field_binary_func(index,update,thr,row,ext)
diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h
index 7be135f9778..5d0f85f1c18 100644
--- a/storage/xtradb/include/trx0trx.h
+++ b/storage/xtradb/include/trx0trx.h
@@ -90,7 +90,7 @@ trx_t*
trx_create(
/*=======*/
sess_t* sess) /*!< in: session */
- __attribute__((nonnull));
+ __attribute__((warn_unused_result));
/********************************************************************//**
Creates a transaction object for MySQL.
@return own: transaction object */
@@ -119,7 +119,7 @@ void
trx_free_prepared(
/*==============*/
trx_t* trx) /*!< in, own: trx object */
- UNIV_COLD __attribute__((nonnull));
+ UNIV_COLD;
/********************************************************************//**
Frees a transaction object for MySQL. */
UNIV_INTERN
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index 7c5fdff1533..3ecfe8d26e1 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -64,10 +64,10 @@ component, i.e. we show M.N.P as M.N */
(INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR)
#ifndef PERCONA_INNODB_VERSION
-#define PERCONA_INNODB_VERSION 38.3
+#define PERCONA_INNODB_VERSION 38.8
#endif
-#define INNODB_VERSION_STR "5.5.52-MariaDB-" IB_TO_STR(PERCONA_INNODB_VERSION)
+#define INNODB_VERSION_STR "5.5.55-MariaDB-" IB_TO_STR(PERCONA_INNODB_VERSION)
#define REFMAN "http://dev.mysql.com/doc/refman/" \
IB_TO_STR(MYSQL_MAJOR_VERSION) "." \
diff --git a/storage/xtradb/log/log0online.c b/storage/xtradb/log/log0online.c
index fa2c8b882bf..45739dffa5d 100644
--- a/storage/xtradb/log/log0online.c
+++ b/storage/xtradb/log/log0online.c
@@ -84,12 +84,14 @@ struct log_bitmap_struct {
both the correct type and the tree does
not mind its overwrite during
rbt_next() tree traversal. */
- mutex_t mutex; /*!< mutex protecting all the fields.*/
};
/* The log parsing and bitmap output struct instance */
static struct log_bitmap_struct* log_bmp_sys;
+/* Mutex protecting log_bmp_sys */
+static mutex_t log_bmp_sys_mutex;
+
/** File name stem for bitmap files. */
static const char* bmp_file_name_stem = "ib_modified_log_";
@@ -188,7 +190,7 @@ log_online_set_page_bit(
byte search_page[MODIFIED_PAGE_BLOCK_SIZE];
byte *page_ptr;
- ut_ad(mutex_own(&log_bmp_sys->mutex));
+ ut_ad(mutex_own(&log_bmp_sys_mutex));
ut_a(space != ULINT_UNDEFINED);
ut_a(page_no != ULINT_UNDEFINED);
@@ -339,7 +341,7 @@ log_online_read_last_tracked_lsn(void)
ib_uint64_t result;
ib_uint64_t read_offset = log_bmp_sys->out.offset;
- while (!checksum_ok && read_offset > 0 && !is_last_page)
+ while ((!checksum_ok || !is_last_page) && read_offset > 0)
{
read_offset -= MODIFIED_PAGE_BLOCK_SIZE;
log_bmp_sys->out.offset = read_offset;
@@ -609,12 +611,19 @@ log_online_is_bitmap_file(
&& (!strcmp(stem, bmp_file_name_stem)));
}
-/*********************************************************************//**
-Initialize the online log following subsytem. */
+/** Initialize the constant part of the log tracking subsystem */
+UNIV_INTERN
+void
+log_online_init(void)
+{
+ mutex_create(log_bmp_sys_mutex_key, &log_bmp_sys_mutex,
+ SYNC_LOG_ONLINE);
+}
+
+/** Initialize the dynamic part of the log tracking subsystem */
UNIV_INTERN
void
log_online_read_init(void)
-/*======================*/
{
ibool success;
ib_uint64_t tracking_start_lsn
@@ -635,9 +644,6 @@ log_online_read_init(void)
log_bmp_sys->read_buf = ut_align(log_bmp_sys->read_buf_ptr,
OS_FILE_LOG_BLOCK_SIZE);
- mutex_create(log_bmp_sys_mutex_key, &log_bmp_sys->mutex,
- SYNC_LOG_ONLINE);
-
/* Initialize bitmap file directory from srv_data_home and add a path
separator if needed. */
srv_data_home_len = strlen(srv_data_home);
@@ -720,6 +726,7 @@ log_online_read_init(void)
ulint size_high;
ib_uint64_t last_tracked_lsn;
ib_uint64_t file_start_lsn;
+ ibool need_rotate;
success = os_file_get_size(log_bmp_sys->out.file, &size_low,
&size_high);
@@ -742,7 +749,11 @@ log_online_read_init(void)
}
last_tracked_lsn = log_online_read_last_tracked_lsn();
+ /* Do not rotate if we truncated the file to zero length - we
+ can just start writing there */
+ need_rotate = (last_tracked_lsn != 0);
if (!last_tracked_lsn) {
+
last_tracked_lsn = last_file_start_lsn;
}
@@ -754,7 +765,10 @@ log_online_read_init(void)
} else {
file_start_lsn = tracking_start_lsn;
}
- if (!log_online_rotate_bitmap_file(file_start_lsn)) {
+
+ if (need_rotate
+ && !log_online_rotate_bitmap_file(file_start_lsn)) {
+
exit(1);
}
@@ -782,14 +796,18 @@ log_online_read_init(void)
log_set_tracked_lsn(tracking_start_lsn);
}
-/*********************************************************************//**
-Shut down the online log following subsystem. */
+/** Shut down the dynamic part of the log tracking subsystem */
UNIV_INTERN
void
log_online_read_shutdown(void)
-/*==========================*/
{
- ib_rbt_node_t *free_list_node = log_bmp_sys->page_free_list;
+ ib_rbt_node_t *free_list_node;
+
+ mutex_enter(&log_bmp_sys_mutex);
+
+ srv_track_changed_pages = FALSE;
+
+ free_list_node = log_bmp_sys->page_free_list;
if (log_bmp_sys->out.file != os_file_invalid) {
os_file_close(log_bmp_sys->out.file);
@@ -804,10 +822,21 @@ log_online_read_shutdown(void)
free_list_node = next;
}
- mutex_free(&log_bmp_sys->mutex);
-
ut_free(log_bmp_sys->read_buf_ptr);
ut_free(log_bmp_sys);
+ log_bmp_sys = NULL;
+
+ srv_redo_log_thread_started = FALSE;
+
+ mutex_exit(&log_bmp_sys_mutex);
+}
+
+/** Shut down the constant part of the log tracking subsystem */
+UNIV_INTERN
+void
+log_online_shutdown(void)
+{
+ mutex_free(&log_bmp_sys_mutex);
}
/*********************************************************************//**
@@ -858,7 +887,7 @@ log_online_parse_redo_log(void)
ulint len = 0;
- ut_ad(mutex_own(&log_bmp_sys->mutex));
+ ut_ad(mutex_own(&log_bmp_sys_mutex));
while (ptr != end
&& log_bmp_sys->next_parse_lsn < log_bmp_sys->end_lsn) {
@@ -950,7 +979,7 @@ log_online_add_to_parse_buf(
ulint actual_data_len = (end_offset >= start_offset)
? end_offset - start_offset : 0;
- ut_ad(mutex_own(&log_bmp_sys->mutex));
+ ut_ad(mutex_own(&log_bmp_sys_mutex));
ut_memcpy(log_bmp_sys->parse_buf_end, log_block + start_offset,
actual_data_len);
@@ -976,7 +1005,7 @@ log_online_parse_redo_log_block(
{
ulint block_data_len;
- ut_ad(mutex_own(&log_bmp_sys->mutex));
+ ut_ad(mutex_own(&log_bmp_sys_mutex));
block_data_len = log_block_get_data_len(log_block);
@@ -1004,7 +1033,7 @@ log_online_follow_log_seg(
byte* log_block_end = log_bmp_sys->read_buf
+ (block_end_lsn - block_start_lsn);
- ut_ad(mutex_own(&log_bmp_sys->mutex));
+ ut_ad(mutex_own(&log_bmp_sys_mutex));
mutex_enter(&log_sys->mutex);
log_group_read_log_seg(LOG_RECOVER, log_bmp_sys->read_buf,
@@ -1068,7 +1097,7 @@ log_online_follow_log_group(
ib_uint64_t block_start_lsn = contiguous_lsn;
ib_uint64_t block_end_lsn;
- ut_ad(mutex_own(&log_bmp_sys->mutex));
+ ut_ad(mutex_own(&log_bmp_sys_mutex));
log_bmp_sys->next_parse_lsn = log_bmp_sys->start_lsn;
log_bmp_sys->parse_buf_end = log_bmp_sys->parse_buf;
@@ -1108,10 +1137,35 @@ log_online_write_bitmap_page(
{
ibool success;
- ut_ad(mutex_own(&log_bmp_sys->mutex));
+ ut_ad(mutex_own(&log_bmp_sys_mutex));
/* Simulate a write error */
- DBUG_EXECUTE_IF("bitmap_page_write_error", return FALSE;);
+ DBUG_EXECUTE_IF("bitmap_page_write_error",
+ {
+ ulint space_id
+ = mach_read_from_4(block
+ + MODIFIED_PAGE_SPACE_ID);
+ if (space_id > 0) {
+ fprintf(stderr, "InnoDB: Error: "
+ "simulating bitmap write "
+ "error in "
+ "log_online_write_bitmap_page "
+ "for space ID %lu\n",
+ space_id);
+ return FALSE;
+ }
+ });
+
+ /* A crash injection site that ensures last checkpoint LSN > last
+ tracked LSN, so that LSN tracking for this interval is tested. */
+ DBUG_EXECUTE_IF("crash_before_bitmap_write",
+ {
+ ulint space_id
+ = mach_read_from_4(block
+ + MODIFIED_PAGE_SPACE_ID);
+ if (space_id > 0)
+ DBUG_SUICIDE();
+ });
success = os_file_write(log_bmp_sys->out.name, log_bmp_sys->out.file,
block,
@@ -1161,7 +1215,7 @@ log_online_write_bitmap(void)
const ib_rbt_node_t *last_bmp_tree_node;
ibool success = TRUE;
- ut_ad(mutex_own(&log_bmp_sys->mutex));
+ ut_ad(mutex_own(&log_bmp_sys_mutex));
if (log_bmp_sys->out.offset >= srv_max_bitmap_file_size) {
if (!log_online_rotate_bitmap_file(log_bmp_sys->start_lsn)) {
@@ -1204,7 +1258,11 @@ log_online_write_bitmap(void)
rbt_next(log_bmp_sys->modified_pages, bmp_tree_node);
DBUG_EXECUTE_IF("bitmap_page_2_write_error",
- DBUG_SET("+d,bitmap_page_write_error"););
+ if (bmp_tree_node)
+ {
+ DBUG_SET("+d,bitmap_page_write_error");
+ DBUG_SET("-d,bitmap_page_2_write_error");
+ });
}
rbt_reset(log_bmp_sys->modified_pages);
@@ -1225,11 +1283,16 @@ log_online_follow_redo_log(void)
log_group_t* group;
ibool result;
- mutex_enter(&log_bmp_sys->mutex);
+ if (!srv_track_changed_pages)
+ return TRUE;
+
+ DEBUG_SYNC_C("log_online_follow_redo_log");
+
+ mutex_enter(&log_bmp_sys_mutex);
if (!srv_track_changed_pages) {
- mutex_exit(&log_bmp_sys->mutex);
- return FALSE;
+ mutex_exit(&log_bmp_sys_mutex);
+ return TRUE;
}
/* Grab the LSN of the last checkpoint, we will parse up to it */
@@ -1238,7 +1301,7 @@ log_online_follow_redo_log(void)
mutex_exit(&(log_sys->mutex));
if (log_bmp_sys->end_lsn == log_bmp_sys->start_lsn) {
- mutex_exit(&log_bmp_sys->mutex);
+ mutex_exit(&log_bmp_sys_mutex);
return TRUE;
}
@@ -1253,15 +1316,11 @@ log_online_follow_redo_log(void)
group = UT_LIST_GET_NEXT(log_groups, group);
}
- /* A crash injection site that ensures last checkpoint LSN > last
- tracked LSN, so that LSN tracking for this interval is tested. */
- DBUG_EXECUTE_IF("crash_before_bitmap_write", DBUG_SUICIDE(););
-
result = log_online_write_bitmap();
log_bmp_sys->start_lsn = log_bmp_sys->end_lsn;
log_set_tracked_lsn(log_bmp_sys->start_lsn);
- mutex_exit(&log_bmp_sys->mutex);
+ mutex_exit(&log_bmp_sys_mutex);
return result;
}
@@ -1608,6 +1667,8 @@ log_online_bitmap_iterator_init(
{
ut_a(i);
+ i->max_lsn = max_lsn;
+
if (UNIV_UNLIKELY(min_lsn > max_lsn)) {
/* Empty range */
@@ -1716,6 +1777,9 @@ log_online_bitmap_iterator_next(
return TRUE;
}
+ if (i->end_lsn >= i->max_lsn && i->last_page_in_run)
+ return FALSE;
+
while (!checksum_ok)
{
while (i->in.size < MODIFIED_PAGE_BLOCK_SIZE
@@ -1808,6 +1872,7 @@ log_online_purge_changed_page_bitmaps(
log_online_bitmap_file_range_t bitmap_files;
size_t i;
ibool result = FALSE;
+ ibool log_bmp_sys_inited = FALSE;
if (lsn == 0) {
lsn = IB_ULONGLONG_MAX;
@@ -1816,13 +1881,18 @@ log_online_purge_changed_page_bitmaps(
if (srv_redo_log_thread_started) {
/* User requests might happen with both enabled and disabled
tracking */
- mutex_enter(&log_bmp_sys->mutex);
+ log_bmp_sys_inited = TRUE;
+ mutex_enter(&log_bmp_sys_mutex);
+ if (!srv_redo_log_thread_started) {
+ log_bmp_sys_inited = FALSE;
+ mutex_exit(&log_bmp_sys_mutex);
+ }
}
if (!log_online_setup_bitmap_file_range(&bitmap_files, 0,
IB_ULONGLONG_MAX)) {
- if (srv_redo_log_thread_started) {
- mutex_exit(&log_bmp_sys->mutex);
+ if (log_bmp_sys_inited) {
+ mutex_exit(&log_bmp_sys_mutex);
}
return TRUE;
}
@@ -1858,7 +1928,7 @@ log_online_purge_changed_page_bitmaps(
}
}
- if (srv_redo_log_thread_started) {
+ if (log_bmp_sys_inited) {
if (lsn > log_bmp_sys->end_lsn) {
ib_uint64_t new_file_lsn;
if (lsn == IB_ULONGLONG_MAX) {
@@ -1874,7 +1944,7 @@ log_online_purge_changed_page_bitmaps(
}
}
- mutex_exit(&log_bmp_sys->mutex);
+ mutex_exit(&log_bmp_sys_mutex);
}
free(bitmap_files.files);
diff --git a/storage/xtradb/mach/mach0data.c b/storage/xtradb/mach/mach0data.c
index 00378f036c9..9669516244d 100644
--- a/storage/xtradb/mach/mach0data.c
+++ b/storage/xtradb/mach/mach0data.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -55,7 +55,6 @@ mach_parse_compressed(
if (flag < 0x80UL) {
*val = flag;
return(ptr + 1);
-
}
/* Workaround GCC bug
@@ -64,7 +63,11 @@ mach_parse_compressed(
function, causing and out-of-bounds read if we are reading a short
integer close to the end of buffer. */
#if defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__clang__)
- asm volatile("": : :"memory");
+#define DEPLOY_FENCE
+#endif
+
+#ifdef DEPLOY_FENCE
+ __atomic_thread_fence(__ATOMIC_ACQUIRE);
#endif
if (flag < 0xC0UL) {
@@ -75,8 +78,13 @@ mach_parse_compressed(
*val = mach_read_from_2(ptr) & 0x7FFFUL;
return(ptr + 2);
+ }
- } else if (flag < 0xE0UL) {
+#ifdef DEPLOY_FENCE
+ __atomic_thread_fence(__ATOMIC_ACQUIRE);
+#endif
+
+ if (flag < 0xE0UL) {
if (end_ptr < ptr + 3) {
return(NULL);
}
@@ -84,7 +92,13 @@ mach_parse_compressed(
*val = mach_read_from_3(ptr) & 0x3FFFFFUL;
return(ptr + 3);
- } else if (flag < 0xF0UL) {
+ }
+
+#ifdef DEPLOY_FENCE
+ __atomic_thread_fence(__ATOMIC_ACQUIRE);
+#endif
+
+ if (flag < 0xF0UL) {
if (end_ptr < ptr + 4) {
return(NULL);
}
@@ -92,14 +106,20 @@ mach_parse_compressed(
*val = mach_read_from_4(ptr) & 0x1FFFFFFFUL;
return(ptr + 4);
- } else {
- ut_ad(flag == 0xF0UL);
+ }
- if (end_ptr < ptr + 5) {
- return(NULL);
- }
+#ifdef DEPLOY_FENCE
+ __atomic_thread_fence(__ATOMIC_ACQUIRE);
+#endif
- *val = mach_read_from_4(ptr + 1);
- return(ptr + 5);
+#undef DEPLOY_FENCE
+
+ ut_ad(flag == 0xF0UL);
+
+ if (end_ptr < ptr + 5) {
+ return(NULL);
}
+
+ *val = mach_read_from_4(ptr + 1);
+ return(ptr + 5);
}
diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c
index 396a0b43094..8e5cc9a6ba6 100644
--- a/storage/xtradb/os/os0file.c
+++ b/storage/xtradb/os/os0file.c
@@ -1058,50 +1058,15 @@ next_file:
char* full_path;
int ret;
struct stat statinfo;
-#ifdef HAVE_READDIR_R
- char dirent_buf[sizeof(struct dirent)
- + _POSIX_PATH_MAX + 100];
- /* In /mysys/my_lib.c, _POSIX_PATH_MAX + 1 is used as
- the max file name len; but in most standards, the
- length is NAME_MAX; we add 100 to be even safer */
-#endif
next_file:
-#ifdef HAVE_READDIR_R
- ret = readdir_r(dir, (struct dirent*)dirent_buf, &ent);
-
- if (ret != 0
-#ifdef UNIV_AIX
- /* On AIX, only if we got non-NULL 'ent' (result) value and
- a non-zero 'ret' (return) value, it indicates a failed
- readdir_r() call. An NULL 'ent' with an non-zero 'ret'
- would indicate the "end of the directory" is reached. */
- && ent != NULL
-#endif
- ) {
- fprintf(stderr,
- "InnoDB: cannot read directory %s, error %lu\n",
- dirname, (ulong)ret);
-
- return(-1);
- }
-
- if (ent == NULL) {
- /* End of directory */
-
- return(1);
- }
-
- ut_a(strlen(ent->d_name) < _POSIX_PATH_MAX + 100 - 1);
-#else
ent = readdir(dir);
if (ent == NULL) {
return(1);
}
-#endif
ut_a(strlen(ent->d_name) < OS_FILE_MAX_PATH);
if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
@@ -1484,9 +1449,10 @@ os_file_create_simple_no_error_handling_func(
}
/****************************************************************//**
-Tries to disable OS caching on an opened file descriptor. */
+Tries to disable OS caching on an opened file descriptor.
+@return TRUE if operation is success and FALSE otherwise */
UNIV_INTERN
-void
+ibool
os_file_set_nocache(
/*================*/
int fd /*!< in: file descriptor to alter */
@@ -1507,6 +1473,7 @@ os_file_set_nocache(
" InnoDB: Failed to set DIRECTIO_ON "
"on file %s: %s: %s, continuing anyway\n",
file_name, operation_name, strerror(errno_save));
+ return FALSE;
}
#elif defined(O_DIRECT)
if (fcntl(fd, F_SETFL, O_DIRECT) == -1) {
@@ -1524,8 +1491,10 @@ os_file_set_nocache(
"'Invalid argument' on Linux on tmpfs, "
"see MySQL Bug#26662\n");
}
+ return FALSE;
}
#endif
+ return TRUE;
}
@@ -1824,7 +1793,11 @@ try_again:
/* ALL_O_DIRECT: O_DIRECT also for transaction log file */
if (srv_unix_file_flush_method == SRV_UNIX_ALL_O_DIRECT) {
- os_file_set_nocache(file, name, mode_str);
+ /* Do fsync() on log files when setting O_DIRECT fails.
+ See log_io_complete() */
+ if (!os_file_set_nocache(file, name, mode_str)) {
+ srv_unix_file_flush_method = SRV_UNIX_O_DIRECT;
+ }
}
#ifdef USE_FILE_LOCK
diff --git a/storage/xtradb/rem/rem0rec.c b/storage/xtradb/rem/rem0rec.c
index cc181c7d333..232033a3f23 100644
--- a/storage/xtradb/rem/rem0rec.c
+++ b/storage/xtradb/rem/rem0rec.c
@@ -777,7 +777,7 @@ rec_get_nth_field_offs_old(
/**********************************************************//**
Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
@return total size */
-UNIV_INLINE __attribute__((warn_unused_result, nonnull(1,2)))
+UNIV_INLINE __attribute__((warn_unused_result))
ulint
rec_get_converted_size_comp_prefix_low(
/*===================================*/
diff --git a/storage/xtradb/row/row0merge.c b/storage/xtradb/row/row0merge.c
index 7409d5a5e1a..00a7decdce6 100644
--- a/storage/xtradb/row/row0merge.c
+++ b/storage/xtradb/row/row0merge.c
@@ -802,7 +802,7 @@ row_merge_write(
/********************************************************************//**
Read a merge record.
@return pointer to next record, or NULL on I/O error or end of list */
-static __attribute__((nonnull))
+static __attribute__((warn_unused_result))
const byte*
row_merge_read_rec(
/*===============*/
@@ -1162,7 +1162,7 @@ row_merge_cmp(
Reads clustered index of the table and create temporary files
containing the index entries for the indexes to be built.
@return DB_SUCCESS or error */
-static __attribute__((nonnull))
+static __attribute__((warn_unused_result))
ulint
row_merge_read_clustered_index(
/*===========================*/
diff --git a/storage/xtradb/row/row0purge.c b/storage/xtradb/row/row0purge.c
index 8ada79a2bbc..4186da884b6 100644
--- a/storage/xtradb/row/row0purge.c
+++ b/storage/xtradb/row/row0purge.c
@@ -742,7 +742,7 @@ err_exit:
Fetches an undo log record and does the purge for the recorded operation.
If none left, or the current purge completed, returns the control to the
parent node, which is always a query thread node. */
-static __attribute__((nonnull))
+static
void
row_purge(
/*======*/
diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c
index 65bea0d0a6e..9e863765dc0 100644
--- a/storage/xtradb/srv/srv0srv.c
+++ b/storage/xtradb/srv/srv0srv.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2013, 2014, SkySQL Ab. All Rights Reserved.
@@ -3373,10 +3373,8 @@ srv_redo_log_follow_thread(
} while (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE);
- srv_track_changed_pages = FALSE;
log_online_read_shutdown();
os_event_set(srv_redo_log_thread_finished_event);
- srv_redo_log_thread_started = FALSE; /* Defensive, not required */
my_thread_end();
os_thread_exit(NULL);
@@ -3555,6 +3553,7 @@ srv_master_thread(
ib_uint64_t oldest_lsn;
ib_time_t last_print_time;
+ my_thread_init();
#ifdef UNIV_DEBUG_THREAD_CREATION
fprintf(stderr, "Master thread starts, id %lu\n",
os_thread_pf(os_thread_get_curr_id()));
@@ -4263,6 +4262,7 @@ suspend_thread:
os_event_wait(slot->event);
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
+ my_thread_end();
os_thread_exit(NULL);
}
@@ -4288,6 +4288,7 @@ srv_purge_thread(
ulint next_itr_time;
ib_int64_t sig_count;
+ my_thread_init();
ut_a(srv_n_purge_threads == 1);
#ifdef UNIV_PFS_THREAD
@@ -4396,6 +4397,8 @@ srv_purge_thread(
os_thread_pf(os_thread_get_curr_id()));
#endif /* UNIV_DEBUG_THREAD_CREATION */
+ my_thread_end();
+
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
os_thread_exit(NULL);
diff --git a/storage/xtradb/srv/srv0start.c b/storage/xtradb/srv/srv0start.c
index e946472e6ee..d8710eab82c 100644
--- a/storage/xtradb/srv/srv0start.c
+++ b/storage/xtradb/srv/srv0start.c
@@ -1657,6 +1657,7 @@ innobase_start_or_create_for_mysql(void)
fsp_init();
log_init();
+ log_online_init();
lock_sys_create(srv_lock_table_size);
@@ -2510,6 +2511,7 @@ innobase_shutdown_for_mysql(void)
btr_search_disable();
ibuf_close();
+ log_online_shutdown();
log_shutdown();
trx_sys_file_format_close();
trx_sys_close();
diff --git a/storage/xtradb/trx/trx0roll.c b/storage/xtradb/trx/trx0roll.c
index 2eeed9378cc..f2a3a2cc4c7 100644
--- a/storage/xtradb/trx/trx0roll.c
+++ b/storage/xtradb/trx/trx0roll.c
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 2017, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -625,12 +626,15 @@ trx_rollback_or_clean_all_recovered(
/*!< in: a dummy parameter required by
os_thread_create */
{
+ my_thread_init();
+
#ifdef UNIV_PFS_THREAD
pfs_register_thread(trx_rollback_clean_thread_key);
#endif /* UNIV_PFS_THREAD */
trx_rollback_or_clean_recovered(TRUE);
+ my_thread_end();
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */