summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2017-06-15 15:27:11 +0400
committerAlexander Barkov <bar@mariadb.org>2017-06-15 15:27:11 +0400
commit765347384af7fd3393ad37567a612d93ed8b3d92 (patch)
treea2c0a08596142312ec38f33e4e02f353a2730fe1 /sql
parent3b1921c714fcb4415cea9058408fb5a626e93b62 (diff)
parente813fe862226554cfe31754b3dfeafbb2b9a7159 (diff)
downloadmariadb-git-765347384af7fd3393ad37567a612d93ed8b3d92.tar.gz
Merge remote-tracking branch 'origin/10.2' into bb-10.2-ext
Diffstat (limited to 'sql')
-rw-r--r--sql/CMakeLists.txt15
-rw-r--r--sql/discover.cc3
-rw-r--r--sql/events.cc2
-rw-r--r--sql/filesort.cc1
-rw-r--r--sql/handler.cc16
-rw-r--r--sql/item.cc5
-rw-r--r--sql/item_cmpfunc.cc83
-rw-r--r--sql/item_cmpfunc.h14
-rw-r--r--sql/item_func.cc5
-rw-r--r--sql/item_func.h31
-rw-r--r--sql/item_strfunc.cc12
-rw-r--r--sql/item_subselect.cc29
-rw-r--r--sql/item_subselect.h8
-rw-r--r--sql/item_sum.h1
-rw-r--r--sql/lock.cc3
-rw-r--r--sql/log.cc9
-rw-r--r--sql/log_event.cc1
-rw-r--r--sql/log_event_old.cc2
-rw-r--r--sql/mysqld.cc9
-rw-r--r--sql/mysqld.h4
-rw-r--r--sql/opt_range.cc7
-rw-r--r--sql/opt_subselect.cc109
-rw-r--r--sql/opt_sum.cc12
-rw-r--r--sql/rpl_gtid.cc2
-rw-r--r--sql/rpl_mi.cc57
-rw-r--r--sql/rpl_mi.h2
-rw-r--r--sql/slave.cc5
-rw-r--r--sql/sp_head.cc2
-rw-r--r--sql/sql_acl.cc6
-rw-r--r--sql/sql_audit.cc9
-rw-r--r--sql/sql_class.cc1
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_digest.cc4
-rw-r--r--sql/sql_lex.cc6
-rw-r--r--sql/sql_lex.h5
-rw-r--r--sql/sql_parse.cc16
-rw-r--r--sql/sql_plugin.cc5
-rw-r--r--sql/sql_prepare.cc6
-rw-r--r--sql/sql_reload.cc8
-rw-r--r--sql/sql_repl.cc6
-rw-r--r--sql/sql_select.cc27
-rw-r--r--sql/sql_show.cc3
-rw-r--r--sql/sql_table.cc11
-rw-r--r--sql/sql_yacc.yy2
-rw-r--r--sql/sys_vars.cc3
-rw-r--r--sql/table.cc39
-rw-r--r--sql/wsrep_thd.cc3
47 files changed, 506 insertions, 105 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 87e41817857..88a4e40e373 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -62,15 +62,22 @@ SET_SOURCE_FILES_PROPERTIES(${GEN_SOURCES}
# Gen_lex_token
# Make sure sql_yacc.h is generated before compiling gen_lex_token
+
+IF(NOT CMAKE_GENERATOR MATCHES "Visual Studio")
+ SET(DEPENDS_gen_lex_token DEPENDS gen_lex_token)
+ SET(DEPENDS_gen_lex_hash DEPENDS gen_lex_hash)
+ENDIF()
+
+
IF(NOT CMAKE_CROSSCOMPILING)
- ADD_EXECUTABLE(gen_lex_token gen_lex_token.cc)
- ADD_DEPENDENCIES(gen_lex_token GenServerSource)
+ ADD_EXECUTABLE(gen_lex_token gen_lex_token.cc
+ ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.h)
ENDIF()
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lex_token.h
COMMAND gen_lex_token > lex_token.h
- DEPENDS gen_lex_token
+ ${DEPENDS_gen_lex_token}
)
ADD_DEFINITIONS(-DMYSQL_SERVER -DHAVE_EVENT_SCHEDULER)
@@ -341,7 +348,7 @@ ENDIF()
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h
COMMAND gen_lex_hash > lex_hash.h
- DEPENDS gen_lex_hash
+ ${DEPENDS_gen_lex_hash}
)
MYSQL_ADD_EXECUTABLE(mysql_tzinfo_to_sql tztime.cc COMPONENT Server)
diff --git a/sql/discover.cc b/sql/discover.cc
index d8ed718fc58..d8bf6ca79c5 100644
--- a/sql/discover.cc
+++ b/sql/discover.cc
@@ -89,8 +89,7 @@ int readfrm(const char *name, const uchar **frmdata, size_t *len)
error= 0;
err:
- if (file > 0)
- (void) mysql_file_close(file, MYF(MY_WME));
+ (void) mysql_file_close(file, MYF(MY_WME));
err_end: /* Here when no file */
DBUG_RETURN (error);
diff --git a/sql/events.cc b/sql/events.cc
index 978a1ebc710..86e85d7f757 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -1,5 +1,6 @@
/*
Copyright (c) 2005, 2013, Oracle and/or its affiliates.
+ Copyright (c) 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
@@ -243,6 +244,7 @@ common_1_lev_code:
break;
case INTERVAL_WEEK:
expr/= 7;
+ /* fall through */
default:
close_quote= FALSE;
break;
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 007216b392f..21b45e78c6e 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -953,6 +953,7 @@ write_keys(Sort_param *param, SORT_INFO *fs_info, uint count,
/* check we won't have more buffpeks than we can possibly keep in memory */
if (my_b_tell(buffpek_pointers) + sizeof(BUFFPEK) > (ulonglong)UINT_MAX)
goto err;
+ bzero(&buffpek, sizeof(buffpek));
buffpek.file_pos= my_b_tell(tempfile);
if ((ha_rows) count > param->max_rows)
count=(uint) param->max_rows; /* purecov: inspected */
diff --git a/sql/handler.cc b/sql/handler.cc
index 9b66801b109..66f0bb19482 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -5685,6 +5685,20 @@ bool handler::check_table_binlog_row_based_internal(bool binlog_row)
table->file->partition_ht()->db_type != DB_TYPE_INNODB) ||
(thd->wsrep_ignore_table == true)))
return 0;
+
+ /* enforce wsrep_max_ws_rows */
+ if (WSREP(thd) && table->s->tmp_table == NO_TMP_TABLE)
+ {
+ thd->wsrep_affected_rows++;
+ if (wsrep_max_ws_rows &&
+ thd->wsrep_exec_mode != REPL_RECV &&
+ thd->wsrep_affected_rows > wsrep_max_ws_rows)
+ {
+ trans_rollback_stmt(thd) || trans_rollback(thd);
+ my_message(ER_ERROR_DURING_COMMIT, "wsrep_max_ws_rows exceeded", MYF(0));
+ return ER_ERROR_DURING_COMMIT;
+ }
+ }
#endif
return (table->s->cached_row_logging_check &&
@@ -5893,7 +5907,7 @@ int handler::ha_external_lock(THD *thd, int lock_type)
DBUG_EXECUTE_IF("external_lock_failure", error= HA_ERR_GENERIC;);
- if (error == 0)
+ if (error == 0 || lock_type == F_UNLCK)
{
m_lock_type= lock_type;
cached_table_flags= table_flags();
diff --git a/sql/item.cc b/sql/item.cc
index f4236eee013..c295c83e1e4 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
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
@@ -561,7 +561,8 @@ Item::Item(THD *thd):
command => we should check thd->lex->current_select on zero (thd->lex
can be uninitialised)
*/
- if (thd->lex->current_select)
+ if (thd->lex->current_select &&
+ thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
{
enum_parsing_place place=
thd->lex->current_select->parsing_place;
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 07b5f90bf69..49135e846cd 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -5264,6 +5264,15 @@ int Regexp_processor_pcre::default_regex_flags()
return default_regex_flags_pcre(current_thd);
}
+void Regexp_processor_pcre::set_recursion_limit(THD *thd)
+{
+ long stack_used;
+ DBUG_ASSERT(thd == current_thd);
+ stack_used= available_stack_size(thd->thread_stack, &stack_used);
+ m_pcre_extra.match_limit_recursion=
+ (my_thread_stack_size - stack_used)/my_pcre_frame_size;
+}
+
/**
Convert string to lib_charset, if needed.
@@ -5355,15 +5364,77 @@ void Regexp_processor_pcre::pcre_exec_warn(int rc) const
*/
switch (rc)
{
+ case PCRE_ERROR_NULL:
+ errmsg= "pcre_exec: null arguement passed";
+ break;
+ case PCRE_ERROR_BADOPTION:
+ errmsg= "pcre_exec: bad option";
+ break;
+ case PCRE_ERROR_BADMAGIC:
+ errmsg= "pcre_exec: bad magic - not a compiled regex";
+ break;
+ case PCRE_ERROR_UNKNOWN_OPCODE:
+ errmsg= "pcre_exec: error in compiled regex";
+ break;
case PCRE_ERROR_NOMEMORY:
errmsg= "pcre_exec: Out of memory";
break;
+ case PCRE_ERROR_NOSUBSTRING:
+ errmsg= "pcre_exec: no substring";
+ break;
+ case PCRE_ERROR_MATCHLIMIT:
+ errmsg= "pcre_exec: match limit exceeded";
+ break;
+ case PCRE_ERROR_CALLOUT:
+ errmsg= "pcre_exec: callout error";
+ break;
case PCRE_ERROR_BADUTF8:
errmsg= "pcre_exec: Invalid utf8 byte sequence in the subject string";
break;
+ case PCRE_ERROR_BADUTF8_OFFSET:
+ errmsg= "pcre_exec: Started at invalid location within utf8 byte sequence";
+ break;
+ case PCRE_ERROR_PARTIAL:
+ errmsg= "pcre_exec: partial match";
+ break;
+ case PCRE_ERROR_INTERNAL:
+ errmsg= "pcre_exec: internal error";
+ break;
+ case PCRE_ERROR_BADCOUNT:
+ errmsg= "pcre_exec: ovesize is negative";
+ break;
+ case PCRE_ERROR_RECURSIONLIMIT:
+ my_snprintf(buf, sizeof(buf), "pcre_exec: recursion limit of %ld exceeded",
+ m_pcre_extra.match_limit_recursion);
+ errmsg= buf;
+ break;
+ case PCRE_ERROR_BADNEWLINE:
+ errmsg= "pcre_exec: bad newline options";
+ break;
+ case PCRE_ERROR_BADOFFSET:
+ errmsg= "pcre_exec: start offset negative or greater than string length";
+ break;
+ case PCRE_ERROR_SHORTUTF8:
+ errmsg= "pcre_exec: ended in middle of utf8 sequence";
+ break;
+ case PCRE_ERROR_JIT_STACKLIMIT:
+ errmsg= "pcre_exec: insufficient stack memory for JIT compile";
+ break;
case PCRE_ERROR_RECURSELOOP:
errmsg= "pcre_exec: Recursion loop detected";
break;
+ case PCRE_ERROR_BADMODE:
+ errmsg= "pcre_exec: compiled pattern passed to wrong bit library function";
+ break;
+ case PCRE_ERROR_BADENDIANNESS:
+ errmsg= "pcre_exec: compiled pattern passed to wrong endianness processor";
+ break;
+ case PCRE_ERROR_JIT_BADOPTION:
+ errmsg= "pcre_exec: bad jit option";
+ break;
+ case PCRE_ERROR_BADLENGTH:
+ errmsg= "pcre_exec: negative length";
+ break;
default:
/*
As other error codes should normally not happen,
@@ -5399,8 +5470,8 @@ int Regexp_processor_pcre::pcre_exec_with_warn(const pcre *code,
bool Regexp_processor_pcre::exec(const char *str, int length, int offset)
{
- m_pcre_exec_rc= pcre_exec_with_warn(m_pcre, NULL, str, length, offset, 0,
- m_SubStrVec, m_subpatterns_needed * 3);
+ m_pcre_exec_rc= pcre_exec_with_warn(m_pcre, &m_pcre_extra, str, length, offset, 0,
+ m_SubStrVec, array_elements(m_SubStrVec));
return false;
}
@@ -5410,10 +5481,10 @@ bool Regexp_processor_pcre::exec(String *str, int offset,
{
if (!(str= convert_if_needed(str, &subject_converter)))
return true;
- m_pcre_exec_rc= pcre_exec_with_warn(m_pcre, NULL,
+ m_pcre_exec_rc= pcre_exec_with_warn(m_pcre, &m_pcre_extra,
str->c_ptr_safe(), str->length(),
offset, 0,
- m_SubStrVec, m_subpatterns_needed * 3);
+ m_SubStrVec, array_elements(m_SubStrVec));
if (m_pcre_exec_rc > 0)
{
uint i;
@@ -5471,7 +5542,7 @@ Item_func_regex::fix_length_and_dec()
if (agg_arg_charsets_for_comparison(cmp_collation, args, 2))
return;
- re.init(cmp_collation.collation, 0, 0);
+ re.init(cmp_collation.collation, 0);
re.fix_owner(this, args[0], args[1]);
}
@@ -5495,7 +5566,7 @@ Item_func_regexp_instr::fix_length_and_dec()
if (agg_arg_charsets_for_comparison(cmp_collation, args, 2))
return;
- re.init(cmp_collation.collation, 0, 1);
+ re.init(cmp_collation.collation, 0);
re.fix_owner(this, args[0], args[1]);
max_length= MY_INT32_NUM_DECIMAL_DIGITS; // See also Item_func_locate
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index e21e074a7a3..f19cae72cb5 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -2554,6 +2554,7 @@ public:
class Regexp_processor_pcre
{
pcre *m_pcre;
+ pcre_extra m_pcre_extra;
bool m_conversion_is_needed;
bool m_is_const;
int m_library_flags;
@@ -2562,7 +2563,6 @@ class Regexp_processor_pcre
String m_prev_pattern;
int m_pcre_exec_rc;
int m_SubStrVec[30];
- uint m_subpatterns_needed;
void pcre_exec_warn(int rc) const;
int pcre_exec_with_warn(const pcre *code, const pcre_extra *extra,
const char *subject, int length, int startoffset,
@@ -2576,11 +2576,14 @@ public:
m_pcre(NULL), m_conversion_is_needed(true), m_is_const(0),
m_library_flags(0),
m_data_charset(&my_charset_utf8_general_ci),
- m_library_charset(&my_charset_utf8_general_ci),
- m_subpatterns_needed(0)
- {}
+ m_library_charset(&my_charset_utf8_general_ci)
+ {
+ m_pcre_extra.flags= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
+ m_pcre_extra.match_limit_recursion= 100L;
+ }
int default_regex_flags();
- void init(CHARSET_INFO *data_charset, int extra_flags, uint nsubpatterns_arg)
+ void set_recursion_limit(THD *);
+ void init(CHARSET_INFO *data_charset, int extra_flags)
{
m_library_flags= default_regex_flags() | extra_flags |
(data_charset != &my_charset_bin ?
@@ -2594,7 +2597,6 @@ public:
m_conversion_is_needed= (data_charset != &my_charset_bin) &&
!my_charset_same(data_charset, m_library_charset);
- m_subpatterns_needed= nsubpatterns_arg;
}
void fix_owner(Item_func *owner, Item *subject_arg, Item *pattern_arg);
bool compile(String *pattern, bool send_error);
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 74427da4cf2..c36f177223b 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2009, 2015, MariaDB
+ Copyright (c) 2009, 2017, MariaDB
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
@@ -1729,6 +1729,7 @@ my_decimal *Item_func_mod::decimal_op(my_decimal *decimal_value)
return decimal_value;
case E_DEC_DIV_ZERO:
signal_divide_by_null();
+ /* fall through */
default:
null_value= 1;
return 0;
@@ -3648,6 +3649,7 @@ longlong Item_master_gtid_wait::val_int()
{
DBUG_ASSERT(fixed == 1);
longlong result= 0;
+ String *gtid_pos = args[0]->val_str(&value);
if (args[0]->null_value)
{
@@ -3659,7 +3661,6 @@ longlong Item_master_gtid_wait::val_int()
#ifdef HAVE_REPLICATION
THD* thd= current_thd;
longlong timeout_us;
- String *gtid_pos = args[0]->val_str(&value);
if (arg_count==2 && !args[1]->null_value)
timeout_us= (longlong)(1e6*args[1]->val_real());
diff --git a/sql/item_func.h b/sql/item_func.h
index 077f69fe0f5..03eb01bbcc9 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1622,7 +1622,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(void *)
+ {
+ not_null_tables_cache= 0;
+ return false;
+ }
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
{ return this; }
bool const_item() const { return true; }
@@ -1953,7 +1957,11 @@ public:
}
}
void cleanup();
- table_map not_null_tables() const { return 0; }
+ bool eval_not_null_tables(void *opt_arg)
+ {
+ not_null_tables_cache= 0;
+ return 0;
+ }
bool is_expensive() { return 1; }
virtual void print(String *str, enum_query_type query_type);
bool check_vcol_func_processor(void *arg)
@@ -2201,7 +2209,7 @@ public:
:Item_long_func(thd, a, b) {}
longlong val_int();
const char *func_name() const { return "master_gtid_wait"; }
- void fix_length_and_dec() { max_length= 2; maybe_null=0;}
+ void fix_length_and_dec() { max_length=2; }
bool check_vcol_func_processor(void *arg)
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
@@ -2482,7 +2490,11 @@ public:
bool is_expensive_processor(void *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(void *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 */
@@ -2769,6 +2781,11 @@ public:
clone->sp_result_field= NULL;
return clone;
}
+ bool eval_not_null_tables(void *opt_arg)
+ {
+ not_null_tables_cache= 0;
+ return 0;
+ }
};
@@ -2863,8 +2880,12 @@ public:
my_decimal *val_decimal(my_decimal *);
void fix_length_and_dec();
const char *func_name() const { return "last_value"; }
- table_map not_null_tables() const { return 0; }
const Type_handler *type_handler() const { return last_value->type_handler(); }
+ bool eval_not_null_tables(void *)
+ {
+ not_null_tables_cache= 0;
+ return 0;
+ }
bool const_item() const { return 0; }
void evaluate_sideeffects();
void update_used_tables()
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 4fcff4c0d2e..fb7a60f356e 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -225,7 +225,7 @@ String *Item_func_sha2::val_str_ascii(String *str)
break;
case 0: // SHA-256 is the default
digest_length= 256;
- /* fall trough */
+ /* fall through */
case 256:
my_sha256(digest_buf, input_ptr, input_len);
break;
@@ -271,7 +271,7 @@ void Item_func_sha2::fix_length_and_dec()
switch (sha_variant) {
case 0: // SHA-256 is the default
sha_variant= 256;
- /* fall trough */
+ /* fall through */
case 512:
case 384:
case 256:
@@ -1349,7 +1349,7 @@ void Item_func_regexp_replace::fix_length_and_dec()
if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 3))
return;
max_length= MAX_BLOB_WIDTH;
- re.init(collation.collation, 0, 10);
+ re.init(collation.collation, 0);
re.fix_owner(this, args[0], args[1]);
}
@@ -1484,7 +1484,7 @@ void Item_func_regexp_substr::fix_length_and_dec()
if (agg_arg_charsets_for_string_result_with_comparison(collation, args, 2))
return;
fix_char_length(args[0]->max_char_length());
- re.init(collation.collation, 0, 10);
+ re.init(collation.collation, 0);
re.fix_owner(this, args[0], args[1]);
}
@@ -5163,7 +5163,7 @@ bool Item_dyncol_get::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
goto null;
case DYN_COL_INT:
signed_value= 1; // For error message
- /* fall_trough */
+ /* fall through */
case DYN_COL_UINT:
if (signed_value || val.x.ulong_value <= LONGLONG_MAX)
{
@@ -5177,7 +5177,7 @@ bool Item_dyncol_get::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
}
/* let double_to_datetime_with_warn() issue the warning message */
val.x.double_value= static_cast<double>(ULONGLONG_MAX);
- /* fall_trough */
+ /* fall through */
case DYN_COL_DOUBLE:
if (double_to_datetime_with_warn(val.x.double_value, ltime, fuzzy_date,
0 /* TODO */))
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 09fbf3e239c..dd362cbc15e 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1425,8 +1425,9 @@ Item_in_subselect::Item_in_subselect(THD *thd, Item * left_exp,
st_select_lex *select_lex):
Item_exists_subselect(thd), left_expr_cache(0), first_execution(TRUE),
in_strategy(SUBS_NOT_TRANSFORMED),
- pushed_cond_guards(NULL), is_jtbm_merged(FALSE), is_jtbm_const_tab(FALSE),
- is_flattenable_semijoin(FALSE), is_registered_semijoin(FALSE),
+ pushed_cond_guards(NULL), 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)
{
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
@@ -2587,6 +2588,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;
@@ -3761,7 +3783,10 @@ int subselect_single_select_engine::exec()
}
}
if (item->engine_changed(this))
+ {
+ thd->lex->current_select= save_select;
DBUG_RETURN(1);
+ }
}
if (select_lex->uncacheable &&
select_lex->uncacheable != UNCACHEABLE_EXPLAIN
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index cb60b646979..6112c1c22f4 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -505,6 +505,8 @@ public:
Item *left_expr_orig;
/* Priority of this predicate in the convert-to-semi-join-nest process. */
int sj_convert_priority;
+ /* 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
@@ -595,8 +597,8 @@ public:
Item_in_subselect(THD *thd_arg):
Item_exists_subselect(thd_arg), left_expr_cache(0), first_execution(TRUE),
in_strategy(SUBS_NOT_TRANSFORMED),
- pushed_cond_guards(NULL), func(NULL), is_jtbm_merged(FALSE),
- is_jtbm_const_tab(FALSE), upper_item(0) {}
+ pushed_cond_guards(NULL), func(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; }
void reset()
@@ -651,6 +653,8 @@ public:
*/
int get_identifier();
+ void block_conversion_to_sj () { do_not_convert_to_sj= TRUE; }
+
bool test_strategy(uchar strategy)
{ return MY_TEST(in_strategy & strategy); }
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 65306ab6f48..a160d0ee522 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -485,6 +485,7 @@ public:
used_tables_cache= 0;
const_item_cache= true;
}
+ void reset_forced_const() { const_item_cache= false; }
virtual bool const_during_execution() const { return false; }
virtual void print(String *str, enum_query_type query_type);
void fix_num_length_and_dec();
diff --git a/sql/lock.cc b/sql/lock.cc
index 12de6ae0616..a34613fb7fe 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -422,6 +422,7 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock)
{
DBUG_ENTER("mysql_unlock_tables");
+ bool errors= thd->is_error();
THD_STAGE_INFO(thd, stage_unlocking_tables);
if (sql_lock->table_count)
@@ -430,6 +431,8 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock)
thr_multi_unlock(sql_lock->locks, sql_lock->lock_count, 0);
if (free_lock)
my_free(sql_lock);
+ if (!errors)
+ thd->clear_error();
DBUG_VOID_RETURN;
}
diff --git a/sql/log.cc b/sql/log.cc
index 0ffa4a5a82d..166180e08a4 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -5681,7 +5681,11 @@ int THD::binlog_write_table_map(TABLE *table, bool is_transactional,
/* Annotate event should be written not more than once */
*with_annotate= 0;
if ((error= writer.write(&anno)))
+ {
+ if (my_errno == EFBIG)
+ cache_data->set_incident();
DBUG_RETURN(error);
+ }
}
if ((error= writer.write(&the_event)))
DBUG_RETURN(error);
@@ -9220,8 +9224,10 @@ void TC_LOG_MMAP::close()
mysql_cond_destroy(&COND_pool);
mysql_cond_destroy(&COND_active);
mysql_cond_destroy(&COND_queue_busy);
+ /* fall through */
case 5:
data[0]='A'; // garble the first (signature) byte, in case mysql_file_delete fails
+ /* fall through */
case 4:
for (i=0; i < npages; i++)
{
@@ -9230,10 +9236,13 @@ void TC_LOG_MMAP::close()
mysql_mutex_destroy(&pages[i].lock);
mysql_cond_destroy(&pages[i].cond);
}
+ /* fall through */
case 3:
my_free(pages);
+ /* fall through */
case 2:
my_munmap((char*)data, (size_t)file_length);
+ /* fall through */
case 1:
mysql_file_close(fd, MYF(0));
}
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 3c062975041..24bcaf8a60b 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -8404,7 +8404,6 @@ int Xid_log_event::do_apply_event(rpl_group_info *rgi)
consistent.
*/
#ifdef WITH_WSREP
- /*Set wsrep_affected_rows = 0 */
thd->wsrep_affected_rows= 0;
#endif
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index 9ba29ddb0f6..8f1cfe17656 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -1587,7 +1587,7 @@ int Old_rows_log_event::do_apply_event(rpl_group_info *rgi)
rli->report(ERROR_LEVEL, thd->net.last_errno, NULL,
"Error in %s event: row application failed. %s",
get_type_str(), thd->net.last_error);
- thd->is_slave_error = 1;
+ thd->is_slave_error= 1;
break;
}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 74efb91cbd1..6da1bd75531 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -105,6 +105,7 @@
#include "sp_rcontext.h"
#include "sp_cache.h"
#include "sql_reload.h" // reload_acl_and_cache
+#include "pcre.h"
#ifdef HAVE_POLL_H
#include <poll.h>
@@ -3721,6 +3722,7 @@ static void init_libstrings()
#endif
}
+ulonglong my_pcre_frame_size;
static void init_pcre()
{
@@ -3728,6 +3730,8 @@ static void init_pcre()
pcre_free= pcre_stack_free= my_str_free_mysqld;
#ifndef EMBEDDED_LIBRARY
pcre_stack_guard= check_enough_stack_size_slow;
+ /* See http://pcre.org/original/doc/html/pcrestack.html */
+ my_pcre_frame_size= -pcre_exec(NULL, NULL, NULL, -999, -999, 0, NULL, 0) + 16;
#endif
}
@@ -8245,7 +8249,7 @@ static int show_default_keycache(THD *thd, SHOW_VAR *var, char *buff,
{
struct st_data {
KEY_CACHE_STATISTICS stats;
- SHOW_VAR var[8];
+ SHOW_VAR var[9];
} *data;
SHOW_VAR *v;
@@ -9356,7 +9360,10 @@ mysql_getopt_value(const char *name, uint length,
return (uchar**) &key_cache->changed_blocks_hash_size;
}
}
+ /* We return in all cases above. Let us silence -Wimplicit-fallthrough */
+ DBUG_ASSERT(0);
#ifdef HAVE_REPLICATION
+ /* fall through */
case OPT_REPLICATE_DO_DB:
case OPT_REPLICATE_DO_TABLE:
case OPT_REPLICATE_IGNORE_DB:
diff --git a/sql/mysqld.h b/sql/mysqld.h
index b7de4ecc324..38e42dd61f1 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -133,7 +133,7 @@ extern ulong slave_retried_transactions;
extern ulong slave_run_triggers_for_rbr;
extern ulonglong slave_type_conversions_options;
extern my_bool read_only, opt_readonly;
-extern my_bool lower_case_file_system;
+extern MYSQL_PLUGIN_IMPORT my_bool lower_case_file_system;
extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
extern my_bool opt_secure_auth;
extern const char *current_dbug_option;
@@ -527,6 +527,8 @@ extern pthread_t signal_thread;
extern struct st_VioSSLFd * ssl_acceptor_fd;
#endif /* HAVE_OPENSSL */
+extern ulonglong my_pcre_frame_size;
+
/*
The following variables were under INNODB_COMPABILITY_HOOKS
*/
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 40184d7a421..9161dee7836 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -6955,7 +6955,10 @@ QUICK_SELECT_I *TRP_ROR_UNION::make_quick(PARAM *param,
{
if (!(quick= (*scan)->make_quick(param, FALSE, &quick_roru->alloc)) ||
quick_roru->push_quick_back(quick))
+ {
+ delete quick_roru;
DBUG_RETURN(NULL);
+ }
}
quick_roru->records= records;
quick_roru->read_time= read_cost;
@@ -10795,9 +10798,7 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
*/
thd->mem_root= old_root;
- if (!quick || create_err)
- return 0; /* no ranges found */
- if (quick->init())
+ if (!quick || create_err || quick->init())
goto err;
quick->records= records;
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index b18fb8f2ae5..1b245342f76 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -980,6 +980,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
@@ -1032,7 +1051,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())
@@ -1050,6 +1068,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++))
@@ -1068,8 +1169,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=
- MY_TEST(in_subq->emb_on_expr_nest != NO_JOIN_NEST) * MAX_TABLES * 2 +
+ MY_TEST(in_subq->do_not_convert_to_sj) * MAX_TABLES * 2 +
in_subq->is_correlated * MAX_TABLES + child_join->outer_tables;
}
@@ -1102,7 +1205,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)
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 9bc21ab3ac3..ab587b8b279 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 2008-2011 Monty Program Ab
+ 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
@@ -254,6 +254,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();
@@ -447,7 +449,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;
@@ -1042,6 +1051,7 @@ static int maxmin_in_range(bool max_fl, Field* field, COND *cond)
case Item_func::LT_FUNC:
case Item_func::LE_FUNC:
less_fl= 1;
+ /* fall through */
case Item_func::GT_FUNC:
case Item_func::GE_FUNC:
{
diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc
index a2617de2757..c385434e41e 100644
--- a/sql/rpl_gtid.cc
+++ b/sql/rpl_gtid.cc
@@ -2045,7 +2045,7 @@ gtid_waiting::wait_for_pos(THD *thd, String *gtid_str, longlong timeout_us)
{
case -1:
status_var_increment(thd->status_var.master_gtid_wait_timeouts);
- /* Deliberate fall through. */
+ /* fall through */
case 0:
status_var_add(thd->status_var.master_gtid_wait_time,
microsecond_interval_timer() - before);
diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc
index 60c887965fb..e90557efd0d 100644
--- a/sql/rpl_mi.cc
+++ b/sql/rpl_mi.cc
@@ -41,7 +41,7 @@ Master_info::Master_info(LEX_CSTRING *connection_name_arg,
master_id(0), prev_master_id(0),
using_gtid(USE_GTID_NO), events_queued_since_last_gtid(0),
gtid_reconnect_event_skip_count(0), gtid_event_seen(false),
- in_start_all_slaves(0), in_stop_all_slaves(0),
+ in_start_all_slaves(0), in_stop_all_slaves(0), in_flush_all_relay_logs(0),
users(0), killed(0)
{
char *tmp;
@@ -663,7 +663,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= MY_MIN(SLAVE_MAX_HEARTBEAT_PERIOD, master_heartbeat_period);
}
DBUG_PRINT("master_info",("log_file_name: %s position: %ld",
mi->master_log_name,
@@ -798,8 +798,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%s\n%d\n%s\n%s\n"
@@ -1979,4 +1979,53 @@ void prot_store_ids(THD *thd, DYNAMIC_ARRAY *ids)
return;
}
+bool Master_info_index::flush_all_relay_logs()
+{
+ DBUG_ENTER("flush_all_relay_logs");
+ bool result= false;
+ int error= 0;
+ mysql_mutex_lock(&LOCK_active_mi);
+ for (uint i= 0; i< master_info_hash.records; i++)
+ {
+ Master_info *mi;
+ mi= (Master_info *) my_hash_element(&master_info_hash, i);
+ mi->in_flush_all_relay_logs= 0;
+ }
+ for (uint i=0; i < master_info_hash.records;)
+ {
+ Master_info *mi;
+ mi= (Master_info *)my_hash_element(&master_info_hash, i);
+ DBUG_ASSERT(mi);
+
+ if (mi->in_flush_all_relay_logs)
+ {
+ i++;
+ continue;
+ }
+ mi->in_flush_all_relay_logs= 1;
+
+ mysql_mutex_lock(&mi->sleep_lock);
+ mi->users++; // Mark used
+ mysql_mutex_unlock(&mi->sleep_lock);
+ mysql_mutex_unlock(&LOCK_active_mi);
+
+ mysql_mutex_lock(&mi->data_lock);
+ error= rotate_relay_log(mi);
+ mysql_mutex_unlock(&mi->data_lock);
+ mi->release();
+ mysql_mutex_lock(&LOCK_active_mi);
+
+ if (error)
+ {
+ result= true;
+ break;
+ }
+ /* Restart from first element as master_info_hash may have changed */
+ i= 0;
+ continue;
+ }
+ mysql_mutex_unlock(&LOCK_active_mi);
+ DBUG_RETURN(result);
+}
+
#endif /* HAVE_REPLICATION */
diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h
index 535abd25f6d..ccc1be6e5ce 100644
--- a/sql/rpl_mi.h
+++ b/sql/rpl_mi.h
@@ -302,6 +302,7 @@ class Master_info : public Slave_reporting_capability
/* gtid_event_seen is false until we receive first GTID event from master. */
bool gtid_event_seen;
bool in_start_all_slaves, in_stop_all_slaves;
+ bool in_flush_all_relay_logs;
uint users; /* Active user for object */
uint killed;
@@ -354,6 +355,7 @@ public:
bool start_all_slaves(THD *thd);
bool stop_all_slaves(THD *thd);
void free_connections();
+ bool flush_all_relay_logs();
};
diff --git a/sql/slave.cc b/sql/slave.cc
index 641bdae9e31..a7f0f003e5c 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) 2009, 2017, MariaDB
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
@@ -6286,9 +6286,8 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
mi->last_queued_gtid.seq_no == 1000)
goto skip_relay_logging;
});
- /* Fall through to default case ... */
#endif
-
+ /* fall through */
default:
default_action:
DBUG_EXECUTE_IF("kill_slave_io_after_2_events",
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index f8ad3c305a7..c87a15ff927 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2002, 2016, Oracle and/or its affiliates.
- Copyright (c) 2011, 2016, MariaDB
+ Copyright (c) 2011, 2017, MariaDB
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_acl.cc b/sql/sql_acl.cc
index d63a2f2bc51..433d48a3de4 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -11698,12 +11698,6 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
/* global privileges */
grant->privilege= sctx->master_access;
- if (!sctx->priv_user[0] && !sctx->priv_role[0])
- {
- DBUG_PRINT("info", ("privilege 0x%lx", grant->privilege));
- DBUG_VOID_RETURN; // it is slave
- }
-
if (!thd->db || strcmp(db, thd->db))
{
/* db privileges */
diff --git a/sql/sql_audit.cc b/sql/sql_audit.cc
index 8a523ebbf4b..8134adca13f 100644
--- a/sql/sql_audit.cc
+++ b/sql/sql_audit.cc
@@ -240,7 +240,7 @@ void mysql_audit_finalize()
/**
Initialize an Audit plug-in
-
+
@param[in] plugin
@retval FALSE OK
@@ -251,12 +251,13 @@ int initialize_audit_plugin(st_plugin_int *plugin)
{
st_mysql_audit *data= (st_mysql_audit*) plugin->plugin->info;
- if (!data->event_notify || !data->class_mask[0]) {
+ if (!data->event_notify || !data->class_mask[0])
+ {
sql_print_error("Plugin '%s' has invalid data.",
plugin->name.str);
return 1;
}
-
+
if (plugin->plugin->init && plugin->plugin->init(NULL))
{
sql_print_error("Plugin '%s' init function returned error.",
@@ -266,7 +267,7 @@ int initialize_audit_plugin(st_plugin_int *plugin)
/* Make the interface info more easily accessible */
plugin->data= plugin->plugin->info;
-
+
/* Add the bits the plugin is interested in to the global mask */
mysql_mutex_lock(&LOCK_audit_mask);
add_audit_mask(mysql_global_audit_mask, data->class_mask);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 076ae8b9923..69c1770da39 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -5601,6 +5601,7 @@ bool xid_cache_insert(THD *thd, XID_STATE *xid_state)
break;
case 1:
my_error(ER_XAER_DUPID, MYF(0));
+ /* fall through */
default:
xid_state->xid_cache_element= 0;
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 58145703499..0aec247d7e6 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -4670,7 +4670,7 @@ public:
select_result(thd_arg), suppress_my_ok(false)
{
DBUG_ENTER("select_result_interceptor::select_result_interceptor");
- DBUG_PRINT("enter", ("this 0x%lx", (ulong) this));
+ DBUG_PRINT("enter", ("this %p", this));
DBUG_VOID_RETURN;
} /* Remove gcc warning */
uint field_count(List<Item> &fields) const { return 0; }
diff --git a/sql/sql_digest.cc b/sql/sql_digest.cc
index 18106a70475..27c33f1c64b 100644
--- a/sql/sql_digest.cc
+++ b/sql/sql_digest.cc
@@ -1,4 +1,5 @@
/* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 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
@@ -454,7 +455,8 @@ sql_digest_state* digest_add_token(sql_digest_state *state,
}
} while (found_unary);
}
- /* fall through, for case NULL_SYM below */
+ /* for case NULL_SYM below */
+ /* fall through */
case LEX_HOSTNAME:
case TEXT_STRING:
case NCHAR_STRING:
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index febd0931e48..3469ffcdbfe 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
- Copyright (c) 2009, 2016, MariaDB
+ Copyright (c) 2009, 2017, MariaDB
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
@@ -1477,12 +1477,14 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd)
state= MY_LEX_HEX_NUMBER;
break;
}
+ /* fall through */
case MY_LEX_IDENT_OR_BIN:
if (lip->yyPeek() == '\'')
{ // Found b'bin-number'
state= MY_LEX_BIN_NUMBER;
break;
}
+ /* fall through */
case MY_LEX_IDENT:
const char *start;
#if defined(USE_MB) && defined(USE_MB_IDENT)
@@ -1824,6 +1826,7 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd)
break;
}
/* " used for strings */
+ /* fall through */
case MY_LEX_STRING: // Incomplete text string
{
uint sep;
@@ -2182,6 +2185,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;
cond_pushed_into_where= cond_pushed_into_having= 0;
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 4ac407b260d..84ab8df0864 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -845,6 +845,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_parse.cc b/sql/sql_parse.cc
index 7169b5dd068..3b9c1c81fd7 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3534,8 +3534,8 @@ mysql_execute_command(THD *thd)
MYF(0));
goto error;
}
- /* no break; fall through */
}
+ /* fall through */
case SQLCOM_SHOW_STATUS_PROC:
case SQLCOM_SHOW_STATUS_FUNC:
case SQLCOM_SHOW_DATABASES:
@@ -3549,7 +3549,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_SELECT:
if (WSREP_CLIENT(thd) && wsrep_sync_wait(thd))
goto error;
-
+ /* fall through */
case SQLCOM_SHOW_PLUGINS:
case SQLCOM_SHOW_VARIABLES:
case SQLCOM_SHOW_CHARSETS:
@@ -4391,8 +4391,8 @@ end_with_restore_list:
/* mysql_update return 2 if we need to switch to multi-update */
if (up_result != 2)
break;
- /* Fall through */
}
+ /* Fall through */
case SQLCOM_UPDATE_MULTI:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
@@ -4510,6 +4510,7 @@ end_with_restore_list:
}
#endif
}
+ /* fall through */
case SQLCOM_INSERT:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
@@ -5442,6 +5443,7 @@ end_with_restore_list:
initialize this variable because RESET shares the same code as FLUSH
*/
lex->no_write_to_binlog= 1;
+ /* fall through */
case SQLCOM_FLUSH:
{
int write_to_binlog;
@@ -7354,12 +7356,6 @@ bool check_fk_parent_table_access(THD *thd,
****************************************************************************/
-#if STACK_DIRECTION < 0
-#define used_stack(A,B) (long) (A - B)
-#else
-#define used_stack(A,B) (long) (B - A)
-#endif
-
#ifndef DBUG_OFF
long max_stack_used;
#endif
@@ -7376,7 +7372,7 @@ bool check_stack_overrun(THD *thd, long margin,
{
long stack_used;
DBUG_ASSERT(thd == current_thd);
- if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >=
+ if ((stack_used= available_stack_size(thd->thread_stack, &stack_used)) >=
(long) (my_thread_stack_size - margin))
{
thd->is_fatal_error= 1;
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index d53ef34d1e8..919ced1a3eb 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2005, 2013, Oracle and/or its affiliates.
- Copyright (c) 2010, 2014, SkySQL 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
@@ -1864,8 +1864,8 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, const char *list)
switch ((*(p++)= *(list++))) {
case '\0':
list= NULL; /* terminate the loop */
- /* fall through */
#ifndef __WIN__
+ /* fall through */
case ':': /* can't use this as delimiter as it may be drive letter */
#endif
case ';':
@@ -1908,6 +1908,7 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, const char *list)
str->str= p;
continue;
}
+ /* fall through */
default:
str->length++;
continue;
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 0e15bf45cc7..e0d03fc3173 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2002, 2015, Oracle and/or its affiliates.
- Copyright (c) 2008, 2016, MariaDB
+ Copyright (c) 2008, 2017, MariaDB
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
@@ -2343,7 +2343,7 @@ static bool check_prepared_statement(Prepared_statement *stmt)
/* mysql_test_update returns 2 if we need to switch to multi-update */
if (res != 2)
break;
-
+ /* fall through */
case SQLCOM_UPDATE_MULTI:
res= mysql_test_multiupdate(stmt, tables, res == 2);
break;
@@ -3426,7 +3426,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
{
stmt->state= Query_arena::STMT_ERROR;
stmt->last_errno= thd->get_stmt_da()->sql_errno();
- strncpy(stmt->last_error, thd->get_stmt_da()->message(), MYSQL_ERRMSG_SIZE);
+ strmake_buf(stmt->last_error, thd->get_stmt_da()->message());
}
thd->set_stmt_da(save_stmt_da);
diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc
index 400c230ea43..f54c0b88110 100644
--- a/sql/sql_reload.cc
+++ b/sql/sql_reload.cc
@@ -181,8 +181,12 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
slave is not likely to have the same connection names.
*/
tmp_write_to_binlog= 0;
-
- if (!(mi= (get_master_info(&connection_name,
+ if (connection_name.length == 0)
+ {
+ if (master_info_index->flush_all_relay_logs())
+ *write_to_binlog= -1;
+ }
+ else if (!(mi= (get_master_info(&connection_name,
Sql_condition::WARN_LEVEL_ERROR))))
{
result= 1;
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 98009827cb4..c5fd142f620 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -3912,9 +3912,6 @@ bool mysql_show_binlog_events(THD* thd)
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
- Format_description_log_event *description_event= new
- Format_description_log_event(3); /* MySQL 4.0 by default */
-
DBUG_ASSERT(thd->lex->sql_command == SQLCOM_SHOW_BINLOG_EVENTS ||
thd->lex->sql_command == SQLCOM_SHOW_RELAYLOG_EVENTS);
@@ -3935,6 +3932,9 @@ bool mysql_show_binlog_events(THD* thd)
binary_log= &(mi->rli.relay_log);
}
+ Format_description_log_event *description_event= new
+ Format_description_log_event(3); /* MySQL 4.0 by default */
+
if (binary_log->is_open())
{
SELECT_LEX_UNIT *unit= &thd->lex->unit;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index ecffa2b4976..b8297af627b 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1991,7 +1991,8 @@ JOIN::optimize_inner()
having= new (thd->mem_root) Item_int(thd, (longlong) 0,1);
zero_result_cause= "Impossible HAVING noticed after reading const tables";
error= 0;
- DBUG_RETURN(0);
+ select_lex->mark_const_derived(zero_result_cause);
+ goto setup_subq_exit;
}
}
@@ -3384,7 +3385,8 @@ void JOIN::exec_inner()
condtions may be arbitrarily costly, and because the optimize phase
might not have produced a complete executable plan for EXPLAINs.
*/
- if (exec_const_cond && !(select_options & SELECT_DESCRIBE) &&
+ if (!zero_result_cause &&
+ exec_const_cond && !(select_options & SELECT_DESCRIBE) &&
!exec_const_cond->val_int())
zero_result_cause= "Impossible WHERE noticed after reading const tables";
@@ -9725,12 +9727,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++)
{
@@ -9769,7 +9779,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;
@@ -9809,10 +9819,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);
@@ -14517,7 +14527,8 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top,
table->table->maybe_null= FALSE;
table->outer_join= 0;
if (!(straight_join || table->straight))
- table->dep_tables= table->embedding? table->embedding->dep_tables: 0;
+ table->dep_tables= table->embedding && !table->embedding->sj_subq_pred ?
+ table->embedding->dep_tables : 0;
if (table->on_expr)
{
/* Add ON expression to the WHERE or upper-level ON condition. */
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 7f2a3c4cd0b..b2ee8a2eef0 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2009, 2016, MariaDB
+ Copyright (c) 2009, 2017, MariaDB
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
@@ -1095,6 +1095,7 @@ public:
is_handled= FALSE;
break;
}
+ /* fall through */
case ER_COLUMNACCESS_DENIED_ERROR:
case ER_VIEW_NO_EXPLAIN: /* Error was anonymized, ignore all the same. */
case ER_PROCACCESS_DENIED_ERROR:
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 462b78aeb62..90be57868cd 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -6896,7 +6896,8 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
case Alter_info::LEAVE_AS_IS:
if (!indexes_were_disabled)
break;
- /* fall-through: disabled indexes */
+ /* disabled indexes */
+ /* fall through */
case Alter_info::DISABLE:
error= table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
}
@@ -9002,7 +9003,9 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
TODO don't create the frm in the first place
*/
- deletefrm(alter_ctx.get_tmp_path());
+ const char *path= alter_ctx.get_tmp_path();
+ table->file->ha_create_partitioning_metadata(path, NULL, CHF_DELETE_FLAG);
+ deletefrm(path);
my_free(const_cast<uchar*>(frm.str));
goto end_inplace;
}
@@ -9807,7 +9810,9 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
}
if (to->file->ha_end_bulk_insert() && error <= 0)
{
- to->file->print_error(my_errno,MYF(0));
+ /* Give error, if not already given */
+ if (!thd->is_error())
+ to->file->print_error(my_errno,MYF(0));
error= 1;
}
to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index a92adc470ab..bda8d3fc7f3 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -4737,9 +4737,11 @@ size_number:
case 'g':
case 'G':
text_shift_number+=10;
+ /* fall through */
case 'm':
case 'M':
text_shift_number+=10;
+ /* fall through */
case 'k':
case 'K':
text_shift_number+=10;
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index e5fe26c6b94..6558d930e72 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -1740,7 +1740,10 @@ Sys_var_gtid_binlog_state::do_check(THD *thd, set_var *var)
return true;
}
if (res->length() == 0)
+ {
list= NULL;
+ list_len= 0;
+ }
else if (!(list= gtid_parse_string_to_list(res->ptr(), res->length(),
&list_len)))
{
diff --git a/sql/table.cc b/sql/table.cc
index 9c3613a879c..0a23d2f1f41 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -2056,6 +2056,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
keyinfo= share->key_info;
uint primary_key= my_strcasecmp(system_charset_info, share->keynames.type_names[0],
primary_key_name) ? MAX_KEY : 0;
+ KEY* key_first_info;
if (primary_key >= MAX_KEY && keyinfo->flags & HA_NOSAME)
{
@@ -2135,19 +2136,38 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
keyinfo->name_length+1);
}
+ if (!key)
+ key_first_info= keyinfo;
+
if (ext_key_parts > share->key_parts && key)
{
KEY_PART_INFO *new_key_part= (keyinfo-1)->key_part +
(keyinfo-1)->ext_key_parts;
uint add_keyparts_for_this_key= add_first_key_parts;
+ uint length_bytes= 0, len_null_byte= 0, ext_key_length= 0;
+ Field *field;
/*
Do not extend the key that contains a component
defined over the beginning of a field.
*/
for (i= 0; i < keyinfo->user_defined_key_parts; i++)
- {
+ {
uint fieldnr= keyinfo->key_part[i].fieldnr;
+ field= share->field[keyinfo->key_part[i].fieldnr-1];
+
+ if (field->null_ptr)
+ len_null_byte= HA_KEY_NULL_LENGTH;
+
+ if (field->type() == MYSQL_TYPE_BLOB ||
+ field->real_type() == MYSQL_TYPE_VARCHAR ||
+ field->type() == MYSQL_TYPE_GEOMETRY)
+ {
+ length_bytes= HA_KEY_BLOB_LENGTH;
+ }
+
+ ext_key_length+= keyinfo->key_part[i].length + len_null_byte
+ + length_bytes;
if (share->field[fieldnr-1]->key_length() !=
keyinfo->key_part[i].length)
{
@@ -2156,6 +2176,23 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
}
}
+ if (add_keyparts_for_this_key)
+ {
+ for (i= 0; i < add_keyparts_for_this_key; i++)
+ {
+ uint pk_part_length= key_first_info->key_part[i].store_length;
+ if (keyinfo->ext_key_part_map & 1<<i)
+ {
+ if (ext_key_length + pk_part_length > MAX_KEY_LENGTH)
+ {
+ add_keyparts_for_this_key= i;
+ break;
+ }
+ ext_key_length+= pk_part_length;
+ }
+ }
+ }
+
if (add_keyparts_for_this_key < (keyinfo->ext_key_parts -
keyinfo->user_defined_key_parts))
{
diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc
index 4acf8a3bf1e..f8db20ace99 100644
--- a/sql/wsrep_thd.cc
+++ b/sql/wsrep_thd.cc
@@ -384,7 +384,8 @@ static void wsrep_replication_process(THD *thd)
case WSREP_TRX_MISSING:
/* these suggests a bug in provider code */
WSREP_WARN("bad return from recv() call: %d", rcode);
- /* fall through to node shutdown */
+ /* Shut down this node. */
+ /* fall through */
case WSREP_FATAL:
/* Cluster connectivity is lost.
*