summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2017-05-23 11:09:47 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2017-05-23 11:09:47 +0300
commit8f643e2063c9890a353149f39ef85b2cf3151fd0 (patch)
treec5468b905c8858dc1cc80ccb2072a923b28c8783 /sql
parent3aecedb2f8f99c446a5ba0b02efcf422a252c9e8 (diff)
parentb61700c22104b513caa9a85e5c6529aa5f2bf4e4 (diff)
downloadmariadb-git-8f643e2063c9890a353149f39ef85b2cf3151fd0.tar.gz
Merge 10.1 into 10.2
Diffstat (limited to 'sql')
-rw-r--r--sql/discover.cc3
-rw-r--r--sql/filesort.cc1
-rw-r--r--sql/item_subselect.cc26
-rw-r--r--sql/item_subselect.h8
-rw-r--r--sql/item_sum.h1
-rw-r--r--sql/log.cc7
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/mysqld.h2
-rw-r--r--sql/opt_range.cc7
-rw-r--r--sql/opt_subselect.cc109
-rw-r--r--sql/opt_sum.cc9
-rw-r--r--sql/rpl_mi.cc6
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_lex.h5
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_repl.cc6
-rw-r--r--sql/sql_select.cc18
-rw-r--r--sql/sys_vars.cc3
18 files changed, 190 insertions, 26 deletions
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/filesort.cc b/sql/filesort.cc
index baeb75b3b0b..5d5b210e62d 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -951,6 +951,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/item_subselect.cc b/sql/item_subselect.cc
index 82fcfff70e1..3c967b6f7e5 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1440,8 +1440,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");
@@ -2599,6 +2600,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;
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 72ea63612f0..7f827bbe982 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -508,6 +508,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
@@ -598,8 +600,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()
@@ -654,6 +656,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 57375b29114..852df778087 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -486,6 +486,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/log.cc b/sql/log.cc
index d11b7f9f35a..e2308f46ad4 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -5636,13 +5636,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));
Log_event_writer writer(file);
+ 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(table->in_use, is_transactional, false);
/* 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);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index b483d92b774..5ef01d5b26f 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -8249,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;
diff --git a/sql/mysqld.h b/sql/mysqld.h
index 0d01779474f..c1f4cac9956 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;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index d5de96b860a..ec59c0acf86 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;
@@ -10773,9 +10776,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 15b803ac49a..027d696a14f 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -1005,6 +1005,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
@@ -1057,7 +1076,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())
@@ -1075,6 +1093,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++))
@@ -1093,8 +1194,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;
}
@@ -1127,7 +1230,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 cb1a705ad0c..ab587b8b279 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -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;
diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc
index f30b7e161f2..15b2907c95b 100644
--- a/sql/rpl_mi.cc
+++ b/sql/rpl_mi.cc
@@ -664,7 +664,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,
@@ -799,8 +799,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"
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 1a06aa97ac0..e3ead45447f 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -2097,6 +2097,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 3b45b1ad40c..face3bcc378 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -789,6 +789,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_prepare.cc b/sql/sql_prepare.cc
index 7de11b11ad3..cd330d8ee26 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -3436,7 +3436,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_repl.cc b/sql/sql_repl.cc
index 7c30aa38f1a..e312e9f35e4 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -3913,9 +3913,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);
@@ -3936,6 +3933,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 5e35224fe63..7bdc99cdbc2 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -9720,12 +9720,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++)
{
@@ -9764,7 +9772,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;
@@ -9804,10 +9812,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/sys_vars.cc b/sql/sys_vars.cc
index 209b17ff377..9ab5e42755e 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)))
{