From 9be994ba693483b240a49c2e6e72bae9fa8cbcca Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Mon, 13 Mar 2017 05:30:02 +0530 Subject: MW-309 Fix wsrep_max_ws_rows so that it does not affect queries Option wsrep_max_ws_rows is intended to limit the maximum number of rows in a writeset. To enforce this limit, we increment THD::wsrep_affected_rows on every INSERT, UPDATE or DELETE. The problem is that we do so even on insertion to internal temporary tables used for SELECTs and such. THD::wsrep_affected_rows is now incremented only for rows that are actually replicated. Signed-off-by: Sachin Setiya --- sql/handler.cc | 69 ++++++++++++++++------------------------------------------ 1 file changed, 19 insertions(+), 50 deletions(-) (limited to 'sql') diff --git a/sql/handler.cc b/sql/handler.cc index 6749dd0257e..2aaaff3500c 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5933,15 +5933,26 @@ static int binlog_log_row(TABLE* table, THD *const thd= table->in_use; #ifdef WITH_WSREP - /* only InnoDB tables will be replicated through binlog emulation */ - if (WSREP_EMULATE_BINLOG(thd) && - table->file->ht->db_type != DB_TYPE_INNODB && - !(table->file->ht->db_type == DB_TYPE_PARTITION_DB && - (((ha_partition*)(table->file))->wsrep_db_type() == DB_TYPE_INNODB))) - // !strcmp(table->file->table_type(), "InnoDB")) + if (WSREP_EMULATE_BINLOG(thd)) { - return 0; - } + /* only InnoDB tables will be replicated through binlog emulation */ + if (table->file->ht->db_type != DB_TYPE_INNODB && + !(table->file->ht->db_type == DB_TYPE_PARTITION_DB && + (((ha_partition*)(table->file))->wsrep_db_type() == DB_TYPE_INNODB))) + { + return 0; + } + + 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 /* WITH_WSREP */ if (check_table_binlog_row_based(thd, table)) { @@ -6108,20 +6119,6 @@ int handler::ha_write_row(uchar *buf) rows_changed++; if (unlikely(error= binlog_log_row(table, 0, buf, log_func))) DBUG_RETURN(error); /* purecov: inspected */ -#ifdef WITH_WSREP - if (WSREP(current_thd)) - { - current_thd->wsrep_affected_rows++; - if (wsrep_max_ws_rows && - current_thd->wsrep_exec_mode != REPL_RECV && - current_thd->wsrep_affected_rows > wsrep_max_ws_rows) - { - trans_rollback_stmt(current_thd) || trans_rollback(current_thd); - my_message(ER_ERROR_DURING_COMMIT, "wsrep_max_ws_rows exceeded", MYF(0)); - DBUG_RETURN(ER_ERROR_DURING_COMMIT); - } - } -#endif /* WITH_WSREP */ DEBUG_SYNC_C("ha_write_row_end"); DBUG_RETURN(0); @@ -6155,20 +6152,6 @@ int handler::ha_update_row(const uchar *old_data, uchar *new_data) rows_changed++; if (unlikely(error= binlog_log_row(table, old_data, new_data, log_func))) return error; -#ifdef WITH_WSREP - if (WSREP(current_thd)) - { - current_thd->wsrep_affected_rows++; - if (wsrep_max_ws_rows && - current_thd->wsrep_exec_mode != REPL_RECV && - current_thd->wsrep_affected_rows > wsrep_max_ws_rows) - { - trans_rollback_stmt(current_thd) || trans_rollback(current_thd); - my_message(ER_ERROR_DURING_COMMIT, "wsrep_max_ws_rows exceeded", MYF(0)); - return ER_ERROR_DURING_COMMIT; - } - } -#endif /* WITH_WSREP */ return 0; } @@ -6196,20 +6179,6 @@ int handler::ha_delete_row(const uchar *buf) rows_changed++; if (unlikely(error= binlog_log_row(table, buf, 0, log_func))) return error; -#ifdef WITH_WSREP - if (WSREP(current_thd)) - { - current_thd->wsrep_affected_rows++; - if (wsrep_max_ws_rows && - current_thd->wsrep_exec_mode != REPL_RECV && - current_thd->wsrep_affected_rows > wsrep_max_ws_rows) - { - trans_rollback_stmt(current_thd) || trans_rollback(current_thd); - my_message(ER_ERROR_DURING_COMMIT, "wsrep_max_ws_rows exceeded", MYF(0)); - return ER_ERROR_DURING_COMMIT; - } - } -#endif /* WITH_WSREP */ return 0; } -- cgit v1.2.1 From 9dda6cb08d3509a83a0897f890e48d7e5a98fdf7 Mon Sep 17 00:00:00 2001 From: Daniele Sciascia Date: Thu, 3 Nov 2016 16:04:22 +0100 Subject: MW-313 Enforce wsrep_max_ws_rows also when binlog is enabled --- sql/handler.cc | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'sql') diff --git a/sql/handler.cc b/sql/handler.cc index 2aaaff3500c..f920686231b 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5933,16 +5933,18 @@ static int binlog_log_row(TABLE* table, THD *const thd= table->in_use; #ifdef WITH_WSREP - if (WSREP_EMULATE_BINLOG(thd)) + /* only InnoDB tables will be replicated through binlog emulation */ + if (WSREP_EMULATE_BINLOG(thd) && + table->file->ht->db_type != DB_TYPE_INNODB && + !(table->file->ht->db_type == DB_TYPE_PARTITION_DB && + (((ha_partition*)(table->file))->wsrep_db_type() == DB_TYPE_INNODB))) { - /* only InnoDB tables will be replicated through binlog emulation */ - if (table->file->ht->db_type != DB_TYPE_INNODB && - !(table->file->ht->db_type == DB_TYPE_PARTITION_DB && - (((ha_partition*)(table->file))->wsrep_db_type() == DB_TYPE_INNODB))) - { return 0; - } + } + /* enforce wsrep_max_ws_rows */ + if (table->s->tmp_table == NO_TMP_TABLE) + { thd->wsrep_affected_rows++; if (wsrep_max_ws_rows && thd->wsrep_exec_mode != REPL_RECV && -- cgit v1.2.1 From 471dd1138185210b47f11cf6333a989861254105 Mon Sep 17 00:00:00 2001 From: sjaakola Date: Mon, 21 Nov 2016 10:38:20 +0200 Subject: refs: MW-319 * silenced the WSREP_ERROR, this fires for all replication filtered DDL, and is false positive --- sql/wsrep_hton.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc index 9f8c328c353..78d189fbd61 100644 --- a/sql/wsrep_hton.cc +++ b/sql/wsrep_hton.cc @@ -313,7 +313,7 @@ wsrep_run_wsrep_commit(THD *thd, handlerton *hton, bool all) int replay_round= 0; if (thd->get_stmt_da()->is_error()) { - WSREP_ERROR("commit issue, error: %d %s", + WSREP_DEBUG("commit issue, error: %d %s", thd->get_stmt_da()->sql_errno(), thd->get_stmt_da()->message()); } -- cgit v1.2.1 From 00f1ed6655b51b8cb496a452471c76b16d50e8e7 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Tue, 14 Mar 2017 14:42:52 +0530 Subject: Galera MTR Tests: fix variable output in galera_as_slave_gtid_replicate_do_db.result Signed-off-by: Sachin Setiya --- sql/sql_class.h | 1 + sql/wsrep_thd.cc | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_class.h b/sql/sql_class.h index 56ae659797c..aed75d94972 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -69,6 +69,7 @@ struct wsrep_thd_shadow { char *db; size_t db_length; my_hrtime_t user_time; + longlong row_count_func; }; #endif class Reprepare_observer; diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index 5e530e84d43..307745ff1b0 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -164,6 +164,7 @@ static void wsrep_prepare_bf_thd(THD *thd, struct wsrep_thd_shadow* shadow) shadow->db = thd->db; shadow->db_length = thd->db_length; shadow->user_time = thd->user_time; + shadow->row_count_func= thd->get_row_count_func(); thd->reset_db(NULL, 0); } @@ -184,6 +185,7 @@ static void wsrep_return_from_bf_mode(THD *thd, struct wsrep_thd_shadow* shadow) thd->wsrep_rgi->cleanup_after_session(); delete thd->wsrep_rgi; thd->wsrep_rgi = NULL; + thd->set_row_count_func(shadow->row_count_func); } void wsrep_replay_transaction(THD *thd) @@ -198,12 +200,31 @@ void wsrep_replay_transaction(THD *thd) WSREP_ERROR("replay issue, thd has reported status already"); } + /* PS reprepare observer should have been removed already. open_table() will fail if we have dangling observer here. */ DBUG_ASSERT(thd->m_reprepare_observer == NULL); + struct da_shadow + { + enum Diagnostics_area::enum_diagnostics_status status; + ulonglong affected_rows; + ulonglong last_insert_id; + char message[MYSQL_ERRMSG_SIZE]; + }; + struct da_shadow da_status; + da_status.status= thd->get_stmt_da()->status(); + if (da_status.status == Diagnostics_area::DA_OK) + { + da_status.affected_rows= thd->get_stmt_da()->affected_rows(); + da_status.last_insert_id= thd->get_stmt_da()->last_insert_id(); + strmake(da_status.message, + thd->get_stmt_da()->message(), + sizeof(da_status.message)-1); + } + thd->get_stmt_da()->reset_diagnostics_area(); thd->wsrep_conflict_state= REPLAYING; @@ -270,7 +291,17 @@ void wsrep_replay_transaction(THD *thd) } else { - my_ok(thd); + if (da_status.status == Diagnostics_area::DA_OK) + { + my_ok(thd, + da_status.affected_rows, + da_status.last_insert_id, + da_status.message); + } + else + { + my_ok(thd); + } } break; case WSREP_TRX_FAIL: -- cgit v1.2.1 From 5bb765366710848e8cda3f7cca6bd50467b9b947 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Thu, 16 Mar 2017 02:13:31 +0530 Subject: Fix wsrep_affected_rows. The value of wsrep_affected_rows were not reseted properly for slave. Now we also wsrep_affected_rows in Xid_log_event::do_apply_event also , apart from THD::cleanup_after_query(). Signed-off-by: Sachin Setiya --- sql/handler.cc | 2 +- sql/log_event.cc | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/handler.cc b/sql/handler.cc index f920686231b..79649316e73 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5943,7 +5943,7 @@ static int binlog_log_row(TABLE* table, } /* enforce wsrep_max_ws_rows */ - if (table->s->tmp_table == NO_TMP_TABLE) + if (table->s->tmp_table == NO_TMP_TABLE && WSREP(thd)) { thd->wsrep_affected_rows++; if (wsrep_max_ws_rows && diff --git a/sql/log_event.cc b/sql/log_event.cc index ba1981d3318..d2f3b2c60f6 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -7422,6 +7422,10 @@ int Xid_log_event::do_apply_event(rpl_group_info *rgi) Record any GTID in the same transaction, so slave state is transactionally consistent. */ + + /*Set wsrep_affected_rows = 0 */ + thd->wsrep_affected_rows= 0; + if (rgi->gtid_pending) { sub_id= rgi->gtid_sub_id; -- cgit v1.2.1 From 09b28b3d10af1dfca7d9f97d7a11a44873a61e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 5 Apr 2017 14:35:41 +0300 Subject: Fix compiler warnings on gcc 6.x. --- sql/sql_class.cc | 2 +- sql/wsrep_mysqld.h | 2 +- sql/wsrep_sst.cc | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 57c228900fe..a8db8463e8e 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2177,7 +2177,7 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use, #ifdef WITH_WSREP { signalled|= mysql_lock_abort_for_thread(this, thd_table); - if (this && WSREP(this) && wsrep_thd_is_BF((void *)this, FALSE)) + if (WSREP(this) && wsrep_thd_is_BF((void *)this, FALSE)) { WSREP_DEBUG("remove_table_from_cache: %llu", (unsigned long long) this->real_id); diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 5ec183f7186..7f574cb996a 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -207,7 +207,7 @@ extern wsrep_seqno_t wsrep_locked_seqno; strcmp(wsrep_provider, WSREP_NONE)) #define WSREP(thd) \ - (WSREP_ON && wsrep && (thd && thd->variables.wsrep_on)) + (WSREP_ON && wsrep && (thd->variables.wsrep_on)) #define WSREP_CLIENT(thd) \ (WSREP(thd) && thd->wsrep_client_thread) diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index 877a93eec44..11698089582 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -814,7 +814,7 @@ static int sst_donate_mysqldump (const char* addr, "%s", host, port, mysqld_port, mysqld_unix_port, wsrep_defaults_file, uuid_str, - (long long)seqno, bypass ? " "WSREP_SST_OPT_BYPASS : ""); + (long long)seqno, bypass ? " " WSREP_SST_OPT_BYPASS : ""); if (ret < 0 || ret >= cmd_len) { @@ -1125,7 +1125,7 @@ static int sst_donate_other (const char* method, wsrep_defaults_file, wsrep_defaults_group_suffix, binlog_opt, binlog_opt_val, uuid, (long long) seqno, - bypass ? " "WSREP_SST_OPT_BYPASS : ""); + bypass ? " " WSREP_SST_OPT_BYPASS : ""); my_free(binlog_opt_val); if (ret < 0 || ret >= cmd_len) -- cgit v1.2.1 From e4a52670f495c01307b124d729c29c7ef21be2ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 5 Apr 2017 08:54:20 +0300 Subject: fix warning "ignoring return value" of fwrite. Merge pull request https://github.com/MariaDB/server/pull/343 contributed by Eric Herman. --- sql/wsrep_binlog.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/wsrep_binlog.cc b/sql/wsrep_binlog.cc index 5cb910248a2..5c5ebb9f780 100644 --- a/sql/wsrep_binlog.cc +++ b/sql/wsrep_binlog.cc @@ -309,9 +309,13 @@ void wsrep_dump_rbr_buf(THD *thd, const void* rbr_buf, size_t buf_len) } FILE *of= fopen(filename, "wb"); + if (of) { - fwrite (rbr_buf, buf_len, 1, of); + if (fwrite(rbr_buf, buf_len, 1, of) == 0) + WSREP_ERROR("Failed to write buffer of length %llu to '%s'", + (unsigned long long)buf_len, filename); + fclose(of); } else -- cgit v1.2.1 From 10d7a2f8e0e9076596ecbe9531d0448837cabf63 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Mon, 8 May 2017 16:00:23 +0530 Subject: Fix galera test failures. --- sql/sql_class.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index a8db8463e8e..92bccadc84b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2177,7 +2177,7 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use, #ifdef WITH_WSREP { signalled|= mysql_lock_abort_for_thread(this, thd_table); - if (WSREP(this) && wsrep_thd_is_BF((void *)this, FALSE)) + if (this && WSREP(this) && wsrep_thd_is_BF((void *)this, FALSE)) { WSREP_DEBUG("remove_table_from_cache: %llu", (unsigned long long) this->real_id); -- cgit v1.2.1 From 0e3170e30d2a4e8f1ed6fd4bbe935355f7370a34 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Mon, 8 May 2017 16:29:41 +0530 Subject: Fix galera tests part II(Fix previous commit) --- sql/sql_class.cc | 2 +- sql/wsrep_mysqld.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 92bccadc84b..a8db8463e8e 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2177,7 +2177,7 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use, #ifdef WITH_WSREP { signalled|= mysql_lock_abort_for_thread(this, thd_table); - if (this && WSREP(this) && wsrep_thd_is_BF((void *)this, FALSE)) + if (WSREP(this) && wsrep_thd_is_BF((void *)this, FALSE)) { WSREP_DEBUG("remove_table_from_cache: %llu", (unsigned long long) this->real_id); diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index 7f574cb996a..5ec183f7186 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -207,7 +207,7 @@ extern wsrep_seqno_t wsrep_locked_seqno; strcmp(wsrep_provider, WSREP_NONE)) #define WSREP(thd) \ - (WSREP_ON && wsrep && (thd->variables.wsrep_on)) + (WSREP_ON && wsrep && (thd && thd->variables.wsrep_on)) #define WSREP_CLIENT(thd) \ (WSREP(thd) && thd->wsrep_client_thread) -- cgit v1.2.1 From 6b97fe067db1b1d8e8dee56508e6d78a36e92481 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 9 May 2017 00:41:45 -0700 Subject: Fixed the bugs mdev-12670 and mdev-12675. The code that blocked conversion of a IN subselect pedicate to a semi-join if it occurred in the ON expression of an outer join did not do it correctly. As a result, the conversion was blocked for IN subselect predicates encountered in ON expressions of INNER joins or in WHERE conditions of mergeable views / derived tables. This patch fixes this problem. --- sql/item_subselect.cc | 2 +- sql/item_subselect.h | 10 +++++-- sql/opt_subselect.cc | 81 +++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 86 insertions(+), 7 deletions(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 78dcfc4215c..12337ec2b1c 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1366,7 +1366,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) 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/opt_subselect.cc b/sql/opt_subselect.cc index 5137d8a0986..645afa6744a 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 *join_list) } +void find_and_block_conversion_to_sj(Item *to_find, + List_iterator_fast &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 ti(join->select_lex->leaf_tables); DBUG_ENTER("convert_join_subqueries_to_semijoins"); if (join->select_lex->sj_subselects.is_empty()) @@ -1070,6 +1089,60 @@ 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 ti(join->select_lex->leaf_tables); + while ((tbl= ti++)) + { + TABLE_LIST *embedded; + TABLE_LIST *embedding= tbl; + do + { + embedded= embedding; + if (test(embedded->outer_join)) + { + 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 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(); + } + } + li.rewind(); /* First, convert child join's subqueries. We proceed bottom-up here */ while ((in_subq= li++)) @@ -1088,8 +1161,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 +1197,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) -- cgit v1.2.1 From e0352fb07961f09ff6481136dc22f3c0db376def Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 15 May 2017 09:51:01 -0700 Subject: Fixed the bug mdev-7599. At some conditions the function opt_sum_query() can apply MIN/MAX optimizations to to Item_sum objects of a select These optimizations becomes invalid if this select is the subquery of an IN subquery predicate that is converted to a EXISTS subquery. Thus in this case the MIX/MAX optimizations that have been applied in opt_sum_query() must be rolled back. This bug appeared in 5.3 when the code for the cost base choice between materialization and in-to-exists transformation of non-correlated IN subqueries was introduced. Before this code in-to-exists transformations were always performed before the call of opt_sum_query(). --- sql/item_subselect.cc | 21 +++++++++++++++++++++ sql/item_sum.h | 1 + sql/opt_sum.cc | 9 +++++++++ sql/sql_lex.cc | 1 + sql/sql_lex.h | 5 +++++ 5 files changed, 37 insertions(+) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 12337ec2b1c..e0da946d190 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -2493,6 +2493,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 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 *and_args= NULL; 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/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/sql_lex.cc b/sql/sql_lex.cc index fa866bc7008..6611fd43876 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1875,6 +1875,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 *ftfunc_list; List 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 min_max_opt_list; JOIN *join; /* after JOIN::prepare it is pointer to corresponding JOIN */ List top_join_list; /* join list of the top level */ List *join_list; /* list for the currently parsed join */ -- cgit v1.2.1 From 2e1428c0b552f2c80aa4b27edaaab8bde8966b22 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 15 May 2017 13:33:59 +0200 Subject: MDEV-12799 Buffer overflow with a specially corrupted master.info one can get an invalid heartbeat_period that will trigger a heap overflow. --- sql/rpl_mi.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 3c5a99121fa..13284308f04 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -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", -- cgit v1.2.1 From d672f88ef73e3fc566a382600968c3e51249de1a Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 8 Apr 2017 22:47:56 +1000 Subject: MDEV-12420: PCRE stack overflow It was possible to construct a PCRE expression that exceeded the stack. resulting in a crash: With fix: MariaDB [(none)]> SELECT 1 -> FROM dual -> WHERE ('Alpha,Bravo,Charlie,Delta,Echo,Foxtrot,StrataCentral,Golf,Hotel,India,Juliet,Kilo,Lima,Mike,StrataL3,November,Oscar,StrataL2,Sand,P3,P4SwitchTest,Arsys,Poppa,ExtensionMgr,Arp,Quebec,Romeo,StrataApiV2,PtReyes,Sierra,SandAcl,Arrow,Artools,BridgeTest,Tango,SandT,PAlaska,Namespace,Agent,Qos,PatchPanel,ProjectReport,Ark,Gimp,Agent,SliceAgent,Arnet,Bgp,Ale,Tommy,Central,AsicPktTestLib,Hsc,SandL3,Abuild,Pca9555,Standby,ControllerDut,CalSys,SandLib,Sb820,PointV2,BfnLib,Evpn,BfnSdk,Sflow,ManagementActive,AutoTest,GatedTest,Bgp,Sand,xinetd,BfnAgentLib,bf-utils,Hello,BfnState,Eos,Artest,Qos,Scd,ThermoMgr,Uniform,EosUtils,Eb,FanController,Central,BfnL3,BfnL2,tcp_wrappers,Victor,Environment,Route,Failover,Whiskey,Xray,Gimp,BfnFixed,Strata,SoCal,XApi,Msrp,XpProfile,tcpdump,PatchPanel,ArosTest,FhTest,Arbus,XpAcl,MacConc,XpApi,telnet,QosTest,Alpha2,BfnVlan,Stp,VxlanControllerTest,MplsAgent,Bravo2,Lanz,BfnMbb,Intf,XCtrl,Unicast,SandTunnel,L3Unicast,Ipsec,MplsTest,Rsvp,EthIntf,StageMgr,Sol,MplsUtils,Nat,Ira,P4NamespaceDut,Counters,Charlie2,Aqlc,Mlag,Power,OpenFlow,Lag,RestApi,BfdTest,strongs,Sfa,CEosUtils,Adt746,MaintenanceMode,MlagDut,EosImage,IpEth,MultiProtocol,Launcher,Max3179,Snmp,Acl,IpEthTest,PhyEee,bf-syslibs,tacc,XpL2,p4-ar-switch,p4-bf-switch,LdpTest,BfnPhy,Mirroring,Phy6,Ptp' -> -> REGEXP '^((?!\b(Strata|StrataApi|StrataApiV2)\b).)*$'); Empty set, 1 warning (0.00 sec) MariaDB [(none)]> show warnings; +---------+------+---------------------------------------------------------+ | Level | Code | Message | +---------+------+---------------------------------------------------------+ | Warning | 1139 | Got error 'pcre_exec: Internal error (-21)' from regexp | +---------+------+---------------------------------------------------------+ --- sql/item_cmpfunc.cc | 4 ++-- sql/item_cmpfunc.h | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 192e06566ff..5a3e028260f 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5237,7 +5237,7 @@ 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_pcre_exec_rc= pcre_exec_with_warn(m_pcre, &m_pcre_extra, str, length, offset, 0, m_SubStrVec, m_subpatterns_needed * 3); return false; } @@ -5248,7 +5248,7 @@ 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); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index b84cb26fb9c..bd552bfc952 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1550,6 +1550,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; @@ -1574,7 +1575,10 @@ public: m_data_charset(&my_charset_utf8_general_ci), m_library_charset(&my_charset_utf8_general_ci), m_subpatterns_needed(0) - {} + { + 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) { -- cgit v1.2.1 From fbc057ad3642884f5af1851bd46bcc2060e75404 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sun, 9 Apr 2017 12:54:33 +1000 Subject: MDEV-12420: add full list of pcre error messages --- sql/item_cmpfunc.cc | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'sql') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 5a3e028260f..bfad63f21f8 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5193,15 +5193,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, -- cgit v1.2.1 From 602b5e4c498ad2e2d045adfa4fd1478ac437582a Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 18 Apr 2017 17:20:34 +1000 Subject: WIP: global readonly variable pcre_frame_size --- sql/item_cmpfunc.h | 8 +++++++- sql/mysqld.cc | 4 ++++ sql/sql_parse.cc | 8 ++++++++ sql/sql_parse.h | 1 + sql/sys_vars.cc | 8 ++++++++ 5 files changed, 28 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index bd552bfc952..b5b94888330 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -25,6 +25,7 @@ #include "thr_malloc.h" /* sql_calloc */ #include "item_func.h" /* Item_int_func, Item_bool_func */ +long check_stack_available(long margin, uchar *dummy); #define PCRE_STATIC 1 /* Important on Windows */ #include "pcre.h" /* pcre header file */ @@ -1576,8 +1577,13 @@ public: m_library_charset(&my_charset_utf8_general_ci), m_subpatterns_needed(0) { +#ifndef EMBEDDED_LIBRARY + uchar dummy; m_pcre_extra.flags= PCRE_EXTRA_MATCH_LIMIT_RECURSION; - m_pcre_extra.match_limit_recursion= 100L; + m_pcre_extra.match_limit_recursion= check_stack_available(100, &dummy) / my_pcre_frame_size; +#else + m_pcre_extra.flags= 0L; +#endif } int default_regex_flags(); void init(CHARSET_INFO *data_charset, int extra_flags, uint nsubpatterns) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 79966f6f5e6..f6c6778e906 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -100,6 +100,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 @@ -3503,6 +3504,9 @@ static void init_pcre() pcre_free= pcre_stack_free= my_str_free_mysqld; #ifndef EMBEDDED_LIBRARY pcre_stack_guard= check_enough_stack_size_slow; + /* my_pcre_frame_size= -pcre_exec(NULL, NULL, NULL, -999, -999, 0, NULL, 0) + 16; + http://pcre.org/original/doc/html/pcrestack.html has reason for + 16 + my_pcre_frame_size= -pcre_match(NULL, NULL, NULL, 0, NULL, NULL, 0) + 16; */ #endif } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e059be4860b..edeb34418b2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6208,6 +6208,14 @@ bool check_stack_overrun(THD *thd, long margin, return 0; } +long check_stack_available(long margin, + uchar *buf __attribute__((unused))) +{ + long stack_top; + DBUG_ASSERT(current_thd); + return my_thread_stack_size - margin \ + - used_stack(current_thd->thread_stack,(char*) &stack_top); +} #define MY_YACC_INIT 1000 // Start with big alloc #define MY_YACC_MAX 32000 // Because of 'short' diff --git a/sql/sql_parse.h b/sql/sql_parse.h index fa414911093..b67692fec90 100644 --- a/sql/sql_parse.h +++ b/sql/sql_parse.h @@ -134,6 +134,7 @@ bool check_simple_select(); Item *normalize_cond(Item *cond); Item *negate_expression(THD *thd, Item *expr); bool check_stack_overrun(THD *thd, long margin, uchar *dummy); +long check_stack_available(long margin, uchar *dummy); /* Variables */ diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 5ff79a2f235..e50217a4459 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -2493,6 +2493,14 @@ static Sys_var_ulonglong Sys_thread_stack( VALID_RANGE(128*1024, ULONGLONG_MAX), DEFAULT(DEFAULT_THREAD_STACK), BLOCK_SIZE(1024)); +#ifndef EMBEDDED_LIBRARY +static Sys_var_ulonglong Sys_my_pcre_frame_size( + "pcre_frame_size", "Frame size for pcre_recursion", + GLOBAL_VAR(my_pcre_frame_size), NO_CMD_LINE, + VALID_RANGE(500,1024), DEFAULT(640 + 16), 1, NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0)); +#endif + static Sys_var_charptr Sys_tmpdir( "tmpdir", "Path for temporary files. Several paths may " "be specified, separated by a " -- cgit v1.2.1 From 52aa200919b1fd9357c05bcdfc66a42e51f242b3 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 11 May 2017 19:48:42 +0200 Subject: MDEV-12420 max_recursive_iterations did not prevent a stack-overflow and segfault post-review fixes * move pcre-specific variable out of mysys * don't use current_thd * move a commonly used macro to my_sys.h * remove new sysvar --- sql/item_cmpfunc.cc | 9 +++++++++ sql/item_cmpfunc.h | 11 +++-------- sql/mysqld.cc | 6 +++--- sql/mysqld.h | 2 ++ sql/sql_parse.cc | 16 +--------------- sql/sql_parse.h | 1 - sql/sys_vars.cc | 8 -------- 7 files changed, 18 insertions(+), 35 deletions(-) (limited to 'sql') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index bfad63f21f8..038a0ebabc2 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5104,6 +5104,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. diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index b5b94888330..17ad1bd8c7d 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -25,7 +25,6 @@ #include "thr_malloc.h" /* sql_calloc */ #include "item_func.h" /* Item_int_func, Item_bool_func */ -long check_stack_available(long margin, uchar *dummy); #define PCRE_STATIC 1 /* Important on Windows */ #include "pcre.h" /* pcre header file */ @@ -1577,15 +1576,11 @@ public: m_library_charset(&my_charset_utf8_general_ci), m_subpatterns_needed(0) { -#ifndef EMBEDDED_LIBRARY - uchar dummy; - m_pcre_extra.flags= PCRE_EXTRA_MATCH_LIMIT_RECURSION; - m_pcre_extra.match_limit_recursion= check_stack_available(100, &dummy) / my_pcre_frame_size; -#else - m_pcre_extra.flags= 0L; -#endif + m_pcre_extra.flags= PCRE_EXTRA_MATCH_LIMIT_RECURSION; + m_pcre_extra.match_limit_recursion= 100L; } int default_regex_flags(); + void set_recursion_limit(THD *); void init(CHARSET_INFO *data_charset, int extra_flags, uint nsubpatterns) { m_library_flags= default_regex_flags() | extra_flags | diff --git a/sql/mysqld.cc b/sql/mysqld.cc index f6c6778e906..a8fef1bd8a3 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3497,6 +3497,7 @@ static void init_libstrings() #endif } +ulonglong my_pcre_frame_size; static void init_pcre() { @@ -3504,9 +3505,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; - /* my_pcre_frame_size= -pcre_exec(NULL, NULL, NULL, -999, -999, 0, NULL, 0) + 16; - http://pcre.org/original/doc/html/pcrestack.html has reason for + 16 - my_pcre_frame_size= -pcre_match(NULL, NULL, NULL, 0, NULL, NULL, 0) + 16; */ + /* 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 } diff --git a/sql/mysqld.h b/sql/mysqld.h index 28ac871d858..e771a0c0da2 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -488,6 +488,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/sql_parse.cc b/sql/sql_parse.cc index edeb34418b2..e57756217ca 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6163,12 +6163,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 @@ -6185,7 +6179,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; @@ -6208,14 +6202,6 @@ bool check_stack_overrun(THD *thd, long margin, return 0; } -long check_stack_available(long margin, - uchar *buf __attribute__((unused))) -{ - long stack_top; - DBUG_ASSERT(current_thd); - return my_thread_stack_size - margin \ - - used_stack(current_thd->thread_stack,(char*) &stack_top); -} #define MY_YACC_INIT 1000 // Start with big alloc #define MY_YACC_MAX 32000 // Because of 'short' diff --git a/sql/sql_parse.h b/sql/sql_parse.h index b67692fec90..fa414911093 100644 --- a/sql/sql_parse.h +++ b/sql/sql_parse.h @@ -134,7 +134,6 @@ bool check_simple_select(); Item *normalize_cond(Item *cond); Item *negate_expression(THD *thd, Item *expr); bool check_stack_overrun(THD *thd, long margin, uchar *dummy); -long check_stack_available(long margin, uchar *dummy); /* Variables */ diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index e50217a4459..5ff79a2f235 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -2493,14 +2493,6 @@ static Sys_var_ulonglong Sys_thread_stack( VALID_RANGE(128*1024, ULONGLONG_MAX), DEFAULT(DEFAULT_THREAD_STACK), BLOCK_SIZE(1024)); -#ifndef EMBEDDED_LIBRARY -static Sys_var_ulonglong Sys_my_pcre_frame_size( - "pcre_frame_size", "Frame size for pcre_recursion", - GLOBAL_VAR(my_pcre_frame_size), NO_CMD_LINE, - VALID_RANGE(500,1024), DEFAULT(640 + 16), 1, NO_MUTEX_GUARD, - NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0)); -#endif - static Sys_var_charptr Sys_tmpdir( "tmpdir", "Path for temporary files. Several paths may " "be specified, separated by a " -- cgit v1.2.1 From f9264280d68dcbca2f9312c7d8620b2bcc9d0694 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 12 May 2017 14:27:49 +0200 Subject: MDEV-12761 Error return from external_lock make the server crash bunch of bugs when external_lock() fails on unlock: * mi_lock_database() used mi_mark_crashed() under share->intern_lock, but mi_mark_crashed() itself locks this mutex. * handler::close() required table to be unlocked, but failed external_lock didn't count as unlock * mysql_unlock_tables() ignored all unlock errors, but they still set the error status in stmt_da. --- sql/handler.cc | 2 +- sql/lock.cc | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/handler.cc b/sql/handler.cc index fc70ed5affc..e51f17f1712 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5944,7 +5944,7 @@ int handler::ha_external_lock(THD *thd, int lock_type) MYSQL_TABLE_LOCK_WAIT(m_psi, PSI_TABLE_EXTERNAL_LOCK, lock_type, { error= external_lock(thd, lock_type); }) - if (error == 0) + if (error == 0 || lock_type == F_UNLCK) { m_lock_type= lock_type; cached_table_flags= table_flags(); diff --git a/sql/lock.cc b/sql/lock.cc index 614341fcc43..29afcc8f578 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -380,12 +380,15 @@ static int lock_external(THD *thd, TABLE **tables, uint count) void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock, bool free_lock) { DBUG_ENTER("mysql_unlock_tables"); + bool errors= thd->is_error(); if (sql_lock->table_count) unlock_external(thd, sql_lock->table, sql_lock->table_count); if (sql_lock->lock_count) 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; } -- cgit v1.2.1 From 71b45032421fe47fceabe419c63e79c44794428d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 12 May 2017 15:10:17 +0200 Subject: MDEV-9998 Fix issues caught by Clang's -Wpointer-bool-conversion warning remove useless checks and a couple of others --- sql/log.cc | 2 +- sql/log_event_old.cc | 6 ++---- sql/slave.cc | 5 ++--- sql/sql_acl.cc | 6 ------ sql/sql_audit.cc | 3 +-- 5 files changed, 6 insertions(+), 16 deletions(-) (limited to 'sql') diff --git a/sql/log.cc b/sql/log.cc index e99eefe4970..b80d65e20db 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1294,7 +1294,7 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length, /* fill in user_host value: the format is "%s[%s] @ %s [%s]" */ user_host_len= (strxnmov(user_host_buff, MAX_USER_HOST_SIZE, - sctx->priv_user ? sctx->priv_user : "", "[", + sctx->priv_user, "[", sctx->user ? sctx->user : (thd->slave_thread ? "SQL_SLAVE" : ""), "] @ ", sctx->host ? sctx->host : "", " [", sctx->ip ? sctx->ip : "", "]", NullS) - diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 8bdb81f5283..73869e82f72 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -1681,8 +1681,7 @@ int Old_rows_log_event::do_apply_event(rpl_group_info *rgi) default: 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->net.last_error : ""); + get_type_str(), thd->net.last_error); thd->is_slave_error= 1; break; } @@ -1721,8 +1720,7 @@ int Old_rows_log_event::do_apply_event(rpl_group_info *rgi) "Error in %s event: error during transaction execution " "on table %s.%s. %s", get_type_str(), table->s->db.str, - table->s->table_name.str, - thd->net.last_error ? thd->net.last_error : ""); + table->s->table_name.str, thd->net.last_error); /* If one day we honour --skip-slave-errors in row-based replication, and diff --git a/sql/slave.cc b/sql/slave.cc index 8801e9e9ab5..3dd17fd7276 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -5647,8 +5647,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) TODO: handling `when' for SHOW SLAVE STATUS' snds behind */ - if ((memcmp(mi->master_log_name, hb.get_log_ident(), hb.get_ident_len()) - && mi->master_log_name != NULL) + if (memcmp(mi->master_log_name, hb.get_log_ident(), hb.get_ident_len()) || mi->master_log_pos > hb.log_pos) { /* missed events of heartbeat from the past */ @@ -6153,7 +6152,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi, mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir_ptr); /* we disallow empty users */ - if (mi->user == NULL || mi->user[0] == 0) + if (mi->user[0] == 0) { mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL, ER(ER_SLAVE_FATAL_ERROR), diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index ac833e01ba7..c7e47c84db0 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -10639,12 +10639,6 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant, /* global privileges */ grant->privilege= sctx->master_access; - if (!sctx->priv_user) - { - 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 b659054a50b..60a75cb06e7 100644 --- a/sql/sql_audit.cc +++ b/sql/sql_audit.cc @@ -369,8 +369,7 @@ int initialize_audit_plugin(st_plugin_int *plugin) { st_mysql_audit *data= (st_mysql_audit*) plugin->plugin->info; - if (!data->class_mask || !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); -- cgit v1.2.1 From 934b8312817d4e8e0387fae0bd9cca3ffafbc7de Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 16 May 2017 08:24:42 -0700 Subject: Fixed the bug mdev-7791. When an IN subquery predicate was converted to a semi-join that were materialized and the result of the materialization happened to be the last in the execution plan then any conjunctive condition with RAND() turned out to be lost. Fixed by attaching this condition to the last top base table. --- sql/sql_select.cc | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 09e6ece7807..bad57aeac87 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8761,12 +8761,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++) { @@ -8804,7 +8812,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; @@ -8843,10 +8851,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); -- cgit v1.2.1 From f7dab76aa286560d167c666e058a494e93c04da5 Mon Sep 17 00:00:00 2001 From: Monty Date: Wed, 17 May 2017 00:00:27 +0300 Subject: MDEV-12756 rpl.rpl_killed_ddl fails in buildbot with 'Can't find record' The issue was that my_errno was not set properly when a repair was killed, which confused the rpl_killed_ddl script. I also added an extra test line in varchar.inc to ensure we don't give duplicate error rows. --- sql/sql_table.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 84e4018c3d8..f66aff1c516 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -9938,7 +9938,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); -- cgit v1.2.1 From 7972da8aa1c52121f60fb8fdae534a46892b4e07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 16 May 2017 20:08:47 +0300 Subject: Silence bogus GCC 7 warnings -Wimplicit-fallthrough Do not silence uncertain cases, or fix any bugs. The only functional change should be that ha_federated::extra() is not calling DBUG_PRINT to report an unhandled case for HA_EXTRA_PREPARE_FOR_DROP. --- sql/events.cc | 2 ++ sql/field.cc | 2 +- sql/item.cc | 4 ++-- sql/item_func.cc | 3 ++- sql/item_strfunc.cc | 4 ++-- sql/log.cc | 7 ++++++- sql/mysqld.cc | 3 +++ sql/opt_sum.cc | 3 ++- sql/slave.cc | 5 ++--- sql/sp_head.cc | 3 ++- sql/sql_digest.cc | 4 +++- sql/sql_lex.cc | 5 ++++- sql/sql_parse.cc | 6 ++++-- sql/sql_plugin.cc | 5 +++-- sql/sql_prepare.cc | 4 ++-- sql/sql_show.cc | 3 ++- sql/sql_table.cc | 3 ++- sql/sql_yacc.yy | 2 ++ 18 files changed, 46 insertions(+), 22 deletions(-) (limited to 'sql') diff --git a/sql/events.cc b/sql/events.cc index 75780cd94c5..8d78497a29e 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 @@ -242,6 +243,7 @@ common_1_lev_code: break; case INTERVAL_WEEK: expr/= 7; + /* fall through */ default: close_quote= FALSE; break; diff --git a/sql/field.cc b/sql/field.cc index dec89e16674..7d7fad2d84d 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -9464,7 +9464,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, case MYSQL_TYPE_DATE: /* We don't support creation of MYSQL_TYPE_DATE anymore */ sql_type= MYSQL_TYPE_NEWDATE; - /* fall trough */ + /* fall through */ case MYSQL_TYPE_NEWDATE: length= MAX_DATE_WIDTH; break; diff --git a/sql/item.cc b/sql/item.cc index ceb8d984d9e..4ce8396f71e 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 @@ -5925,7 +5925,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length) collation.collation); break; } - /* Fall through to make_string_field() */ + /* Fall through */ case MYSQL_TYPE_ENUM: case MYSQL_TYPE_SET: case MYSQL_TYPE_VAR_STRING: diff --git a/sql/item_func.cc b/sql/item_func.cc index 2c43181e8bb..13ea5291edc 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 @@ -2034,6 +2034,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; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 9baa5d52319..7cd712cc5e1 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -5090,7 +5090,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) { @@ -5103,7 +5103,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(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/log.cc b/sql/log.cc index b80d65e20db..6ebfda67ecf 100644 --- a/sql/log.cc +++ b/sql/log.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 @@ -8822,8 +8822,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++) { @@ -8832,10 +8834,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/mysqld.cc b/sql/mysqld.cc index a8fef1bd8a3..0aa917cb7fe 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8724,6 +8724,9 @@ 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); + /* fall through */ case OPT_REPLICATE_DO_DB: case OPT_REPLICATE_DO_TABLE: case OPT_REPLICATE_IGNORE_DB: diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 1ff1f4a6449..ed729cb1734 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 @@ -1041,6 +1041,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/slave.cc b/sql/slave.cc index 3dd17fd7276..8c3627514ac 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 @@ -5798,9 +5798,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: if (mi->using_gtid != Master_info::USE_GTID_NO && mi->gtid_event_seen) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index fb0f3132816..ea9e1c1c822 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 @@ -142,6 +142,7 @@ sp_get_item_value(THD *thd, Item *item, String *str) if (item->field_type() != MYSQL_TYPE_BIT) return item->val_str(str); else {/* Bit type is handled as binary string */} + /* fall through */ case STRING_RESULT: { String *result= item->val_str(str); diff --git a/sql/sql_digest.cc b/sql/sql_digest.cc index c8ba371ea7e..0cc969b3758 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 @@ -453,7 +454,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 de450b8ede8..99f43ebda22 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 @@ -1174,12 +1174,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) @@ -1527,6 +1529,7 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) break; } /* " used for strings */ + /* fall through */ case MY_LEX_STRING: // Incomplete text string if (!(yylval->lex_str.str = get_text(lip, 1, 1))) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e57756217ca..b054dd3f5ed 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2518,8 +2518,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: @@ -3323,8 +3323,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); @@ -3434,6 +3434,7 @@ end_with_restore_list: DBUG_PRINT("debug", ("Just after generate_incident()")); } #endif + /* fall through */ case SQLCOM_INSERT: { DBUG_ASSERT(first_table == all_tables && first_table != 0); @@ -4273,6 +4274,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; diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 23b795cdf7f..63c3933db93 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 @@ -1816,8 +1816,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 ';': @@ -1858,6 +1858,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 03624647970..a88e6d776c7 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, 2015, 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 @@ -2108,7 +2108,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; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index ea9f9ec2cca..ae074eee556 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 @@ -983,6 +983,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 503048f9f6a..2eff8fd5e2f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6851,7 +6851,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); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index cd5b9657730..95a683165e2 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4681,9 +4681,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; -- cgit v1.2.1 From 71cd205956818d29edb6bf09002ecf2fe8303f64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 16 May 2017 20:08:47 +0300 Subject: Silence bogus GCC 7 warnings -Wimplicit-fallthrough Do not silence uncertain cases, or fix any bugs. The only functional change should be that ha_federated::extra() is not calling DBUG_PRINT to report an unhandled case for HA_EXTRA_PREPARE_FOR_DROP. --- sql/events.cc | 2 ++ sql/field.cc | 2 +- sql/item.cc | 4 ++-- sql/item_func.cc | 3 ++- sql/item_strfunc.cc | 8 ++++---- sql/log.cc | 7 ++++++- sql/mysqld.cc | 3 +++ sql/opt_sum.cc | 3 ++- sql/rpl_gtid.cc | 2 +- sql/slave.cc | 5 ++--- sql/sp_head.cc | 3 ++- sql/sql_class.cc | 1 + sql/sql_digest.cc | 4 +++- sql/sql_lex.cc | 5 ++++- sql/sql_parse.cc | 8 +++++--- sql/sql_plugin.cc | 5 +++-- sql/sql_prepare.cc | 4 ++-- sql/sql_show.cc | 3 ++- sql/sql_table.cc | 3 ++- sql/sql_yacc.yy | 2 ++ sql/wsrep_thd.cc | 3 ++- 21 files changed, 53 insertions(+), 27 deletions(-) (limited to 'sql') diff --git a/sql/events.cc b/sql/events.cc index 77dbb8b82e5..728d15e60f6 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 @@ -242,6 +243,7 @@ common_1_lev_code: break; case INTERVAL_WEEK: expr/= 7; + /* fall through */ default: close_quote= FALSE; break; diff --git a/sql/field.cc b/sql/field.cc index ea56489543d..8eb37c56c7e 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -10126,7 +10126,7 @@ bool Create_field::check(THD *thd) case MYSQL_TYPE_DATE: /* We don't support creation of MYSQL_TYPE_DATE anymore */ sql_type= MYSQL_TYPE_NEWDATE; - /* fall trough */ + /* fall through */ case MYSQL_TYPE_NEWDATE: length= MAX_DATE_WIDTH; break; diff --git a/sql/item.cc b/sql/item.cc index fb7c52df812..631ecb44b30 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 @@ -5824,7 +5824,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, Field_string(max_length, maybe_null, name, collation.collation); break; } - /* Fall through to make_string_field() */ + /* Fall through */ case MYSQL_TYPE_ENUM: case MYSQL_TYPE_SET: case MYSQL_TYPE_VAR_STRING: diff --git a/sql/item_func.cc b/sql/item_func.cc index ee3fd2f6026..5ad55e99b5b 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 @@ -1944,6 +1944,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; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 6c897712317..40c2ab8f231 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -226,7 +226,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; @@ -272,7 +272,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: @@ -5060,7 +5060,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) { @@ -5073,7 +5073,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(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/log.cc b/sql/log.cc index 4a1e9f26c4c..f1ab5db286b 100644 --- a/sql/log.cc +++ b/sql/log.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 @@ -9186,8 +9186,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++) { @@ -9196,10 +9198,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/mysqld.cc b/sql/mysqld.cc index 0bf57d9543b..8aaaa434314 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -9269,6 +9269,9 @@ 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); + /* fall through */ #ifdef HAVE_REPLICATION case OPT_REPLICATE_DO_DB: case OPT_REPLICATE_DO_TABLE: diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index f36887eb137..e7d7c81b638 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 @@ -1042,6 +1042,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 dfec97bf021..51df8f1a789 100644 --- a/sql/rpl_gtid.cc +++ b/sql/rpl_gtid.cc @@ -2046,7 +2046,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/slave.cc b/sql/slave.cc index f95dd60287b..159377ab243 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 @@ -6072,9 +6072,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 58f5082ab14..bf25d45ffaf 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 @@ -142,6 +142,7 @@ sp_get_item_value(THD *thd, Item *item, String *str) if (item->field_type() != MYSQL_TYPE_BIT) return item->val_str(str); else {/* Bit type is handled as binary string */} + /* fall through */ case STRING_RESULT: { String *result= item->val_str(str); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 68006b7c1e9..304036a67ff 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -5532,6 +5532,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_digest.cc b/sql/sql_digest.cc index 7f6f3bbfe9b..6605d0af0a9 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 e401e96194c..691adb4896c 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 @@ -1395,12 +1395,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) @@ -1745,6 +1747,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; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index aee81d7740c..044c3257872 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2932,8 +2932,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: @@ -2947,7 +2947,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: @@ -3776,8 +3776,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); @@ -3895,6 +3895,7 @@ end_with_restore_list: } #endif } + /* fall through */ case SQLCOM_INSERT: { DBUG_ASSERT(first_table == all_tables && first_table != 0); @@ -4809,6 +4810,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; diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 469e96c5fee..78caa79c8ed 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 @@ -1848,8 +1848,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 ';': @@ -1890,6 +1890,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 09b87a3b1d1..97513e9e6b8 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, 2015, 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 @@ -2298,7 +2298,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; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index e915a78d54a..c44a281af9d 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 @@ -1079,6 +1079,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 ad0a6b3c2c7..57fa732251f 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6880,7 +6880,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); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a55966636aa..b4c0c4d45c3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4680,9 +4680,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/wsrep_thd.cc b/sql/wsrep_thd.cc index c55b79a999f..53632f56167 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -382,7 +382,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. * -- cgit v1.2.1 From 0e3ca225ad65f14da79c9a73aeadcc2a3e1c0c2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Wed, 17 May 2017 22:09:58 +0300 Subject: Change lower_case_file_system definition to feature MYSQL_PLUGIN_IMPORT --- sql/mysqld.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/mysqld.h b/sql/mysqld.h index e771a0c0da2..78e832e4abc 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -106,7 +106,7 @@ extern ulong slave_run_triggers_for_rbr; #endif //RBR_TRIGGERS 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 char* opt_secure_file_priv; -- cgit v1.2.1 From 7e9716310261bce124585cbffd85f3402390ec9d Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Wed, 17 May 2017 14:29:13 -0700 Subject: Fixed the bug mdev-12817/mdev-12820. This patch is a correction of the patch for bug mdev-12670. With the current code handling semi-joins the following must be taken into account. Conversion of an IN subquery predicate into semi-join has to be blocked if the predicate occurs: (a) in the ON expression of an outer join (b) in the ON expression of an inner join embedded directly or indirectly in the inner nest of an outer join. The patch for mdev-12670 blocked conversion to semi-joins only in the case (a), but not in the case (b). This patch blocks the conversion in both cases. --- sql/opt_subselect.cc | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 645afa6744a..84e06fda852 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -1103,7 +1103,26 @@ bool convert_join_subqueries_to_semijoins(JOIN *join) do { embedded= embedding; - if (test(embedded->outer_join)) + 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) -- cgit v1.2.1 From efb9f2617bde1654006a99af625859eb509d5448 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Wed, 17 May 2017 16:16:54 -0700 Subject: Fixed the bug mdev-12812. This is another correction of the patch for bug mdev-12670. If a derived table is merged into a select with STRAIGHT_JOIN modifier all IN subquery predicates contained in the specification of the derived table cannot be subject to conversion to semi-joins. --- sql/opt_subselect.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'sql') diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 84e06fda852..d8b4de29f47 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -1161,6 +1161,16 @@ bool convert_join_subqueries_to_semijoins(JOIN *join) 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 */ -- cgit v1.2.1 From b5cdf01404dd352bb9aa7b58cad76f7a500b32d2 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Thu, 18 May 2017 17:13:37 +0530 Subject: MDEV-11092 Assertion `!writer.checksum_len || writer.remains == 0' failed Problem:- This crash happens because logged stmt is quite big and while writing Annotate_rows_log_event it throws EFBIG error but we ignore this error and do not call cache_data->set_incident(). Solution:- When we normally write Binlog_log_event we check for error EFBIG, but we did do this for Annotate_rows_log_event. We check for this error and call cache_data->set_incident() accordingly. # Conflicts: # sql/log.cc --- sql/log.cc | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sql') diff --git a/sql/log.cc b/sql/log.cc index dc87c39730c..f8c256e645f 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -4887,13 +4887,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); -- cgit v1.2.1 From 5e9d6511088e4435470b37bcc07825a77cc99539 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 18 May 2017 23:54:43 -0700 Subject: Fixed the bug mdev-12788. In some rare cases queries with UNION ALL using a derived table specified by a grouping select with a subquery in WHERE and impossible HAVING detected after constant row substitution could hang. The cause was not a proper return from the function subselect_single_select_engine::exec() in the case when the subquery was not optimized beforehand and the optimization performed in this function requested for a change of the subquery engine. This was fixed. Also a change was applied that avoided execution of a subquery if impossible having was detected for the main query at the optimization stage. --- sql/item_subselect.cc | 3 +++ sql/sql_select.cc | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 5f15e386b8d..82fcfff70e1 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -3776,7 +3776,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/sql_select.cc b/sql/sql_select.cc index 2d819d3207c..5e35224fe63 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1984,7 +1984,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; } } @@ -3377,7 +3378,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"; -- cgit v1.2.1 From 7c03edf2fe66855a8ce8f2575c3aaf66af975377 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 17 May 2017 15:16:24 +0200 Subject: MDEV-6262 analyze the coverity report on mariadb uploaded 10.0, analyzed everything with the Impact=High (and a couple of Medium) --- sql/discover.cc | 3 +-- sql/filesort.cc | 1 + sql/mysqld.cc | 2 +- sql/opt_range.cc | 7 ++++--- sql/records.cc | 2 +- sql/sql_prepare.cc | 2 +- sql/sql_repl.cc | 6 +++--- sql/sql_show.cc | 2 +- sql/sys_vars.cc | 3 +++ 9 files changed, 16 insertions(+), 12 deletions(-) (limited to 'sql') 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 73a6c89e53f..8a7d5610dc2 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -914,6 +914,7 @@ write_keys(Sort_param *param, Filesort_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/mysqld.cc b/sql/mysqld.cc index 0aa917cb7fe..32cdda9debc 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7702,7 +7702,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/opt_range.cc b/sql/opt_range.cc index 8f9d5abfa4d..481d8445fa8 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -7549,7 +7549,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; @@ -11194,9 +11197,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/records.cc b/sql/records.cc index a37f7a18c11..940fd97d123 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -69,7 +69,7 @@ static int rr_index_desc(READ_RECORD *info); bool init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, bool print_error, uint idx, bool reverse) { - int error; + int error= 0; DBUG_ENTER("init_read_record_idx"); empty_record(table); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index a88e6d776c7..1a02a2ae84c 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -3022,7 +3022,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 560b7ede183..ebe89e2b4a0 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -3685,9 +3685,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); @@ -3713,6 +3710,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()) { LEX_MASTER_INFO *lex_mi= &thd->lex->mi; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index ae074eee556..3f161fb8aec 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3016,7 +3016,7 @@ static bool show_status_array(THD *thd, const char *wild, for (; variables->name; variables++) { - bool wild_checked; + bool wild_checked= 0; strnmov(prefix_end, variables->name, len); name_buffer[sizeof(name_buffer)-1]=0; /* Safety */ if (ucase_names) diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 5ff79a2f235..99248457bb8 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1660,7 +1660,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))) { -- cgit v1.2.1 From 70630e3c92f72f39666dedaa7733cb0c22e66d62 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 19 May 2017 15:55:35 +0000 Subject: Workaround dependency problems (constant rebuilds) in Visual Studio generator --- sql/CMakeLists.txt | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 2e581b1acbe..ca2b059eeef 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -38,15 +38,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) @@ -295,7 +302,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) -- cgit v1.2.1 From b8405c853fa30002d164d5fe2b4f8ea8979c09b8 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Mon, 22 May 2017 07:09:49 +0200 Subject: MDEV-11958: LEFT JOIN with stored routine produces incorrect result Added forgoten method of Item_func_sp to make it correctly work with LEFT/RIGHT JOIN. Fixed inconsistency with the null table caches. --- sql/item_func.h | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'sql') 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(); -- cgit v1.2.1 From 7e0c8fc3fb284a38a4640ffaa2ddbfb282240832 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 21 May 2017 16:21:15 +0200 Subject: MDEV-12389 ADD CHECK leaves an orphaned .par file --- sql/sql_table.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 57fa732251f..db0d6d4f377 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -8856,7 +8856,9 @@ bool mysql_alter_table(THD *thd,char *new_db, 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(frm.str)); goto end_inplace; } -- cgit v1.2.1 From ae76ff45245d16212854e1b2c7e3e53c9dce9073 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 22 May 2017 09:34:39 +0200 Subject: compiler warning on Win64 cast pointer(64)->long(32) --- sql/sql_class.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_class.h b/sql/sql_class.h index 9ae1e5cf23b..db1214ab26b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -4283,7 +4283,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 &fields) const { return 0; } -- cgit v1.2.1 From b430133bb9549681147f806ba3048c382837a595 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 23 May 2017 15:35:32 +0200 Subject: MDEV-12844 numerous issues in MASTER_GTID_WAIT() --- sql/item_func.cc | 2 +- sql/item_func.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/item_func.cc b/sql/item_func.cc index 5ad55e99b5b..b544f78fc12 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3959,6 +3959,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) { @@ -3970,7 +3971,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 4d58e974a75..f44c5d14cda 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1669,7 +1669,7 @@ public: Item_master_gtid_wait(THD *thd, Item *a, Item *b): Item_int_func(thd, a, b) {} longlong val_int(); const char *func_name() const { return "master_gtid_wait"; } - void fix_length_and_dec() { max_length=10+1+10+1+20+1; maybe_null=0;} + void fix_length_and_dec() { max_length=2; } bool check_vcol_func_processor(uchar *int_arg) { return trace_unsupported_by_check_vcol_func_processor(func_name()); -- cgit v1.2.1 From e4d10e09cf318aad237143254c45458d16009f70 Mon Sep 17 00:00:00 2001 From: Varun Gupta Date: Sun, 28 May 2017 00:40:36 +0530 Subject: MDEV-11196: Error:Run-Time Check Failure #2 - Stack around the variable 'key_buff' was corrupted, server crashes in opt_sum_query Extended keys feature disabled if the length of extended key is longer than MAX_KEY_LEN --- sql/table.cc | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/table.cc b/sql/table.cc index 37c0b630efc..a1e9ebfc0cc 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1721,6 +1721,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) { @@ -1800,19 +1801,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) { @@ -1821,6 +1841,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< 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)) { -- cgit v1.2.1 From af4421e82d3d458ea8f19cda6376503be6c49143 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 29 May 2017 00:27:14 -0700 Subject: Fixed the bug mdev-12931. This corrects the patch for mdev-10006. The current code supports only those semi-join nests that are placed at the join top level. So such nests cannot depend on other tables or nests. --- sql/sql_select.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 559473b8c19..50f121ce47f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -14493,7 +14493,8 @@ simplify_joins(JOIN *join, 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. */ -- cgit v1.2.1 From 2372bfaa7b4b9a40e418cbfec480d30eb84eaf21 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 29 May 2017 20:49:36 +0200 Subject: MDEV-12942 REGEXP_INSTR returns 1 when using brackets always use full m_SubStrVec length in pcre_exec, we don't know how many subexpressions user's regexp will have --- sql/item_cmpfunc.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 4c17da46e1e..369cdeda62d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5518,7 +5518,7 @@ 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, &m_pcre_extra, str, length, offset, 0, - m_SubStrVec, m_subpatterns_needed * 3); + m_SubStrVec, array_elements(m_SubStrVec)); return false; } @@ -5531,7 +5531,7 @@ bool Regexp_processor_pcre::exec(String *str, int offset, 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; -- cgit v1.2.1 From 5e0038b376b79ee5a2f47da1e0d71caa7d8fa99c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 29 May 2017 20:57:34 +0200 Subject: cleanup: remove Regexp_processor_pcre::m_subpatterns_needed it's unused now. --- sql/item_cmpfunc.cc | 4 ++-- sql/item_cmpfunc.h | 7 ++----- sql/item_strfunc.cc | 4 ++-- 3 files changed, 6 insertions(+), 9 deletions(-) (limited to 'sql') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 369cdeda62d..fe79e5f083d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -5589,7 +5589,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]); } @@ -5613,7 +5613,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]); } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 964a174f330..56c5a4afe54 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1901,7 +1901,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, @@ -1915,15 +1914,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 set_recursion_limit(THD *); - void init(CHARSET_INFO *data_charset, int extra_flags, uint nsubpatterns_arg) + void init(CHARSET_INFO *data_charset, int extra_flags) { m_library_flags= default_regex_flags() | extra_flags | (data_charset != &my_charset_bin ? @@ -1937,7 +1935,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_strfunc.cc b/sql/item_strfunc.cc index 40c2ab8f231..c54128db964 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1278,7 +1278,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]); } @@ -1413,7 +1413,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]); } -- cgit v1.2.1 From 3356e42d01dbef2bfa9a02ec08c7756760385e1e Mon Sep 17 00:00:00 2001 From: Monty Date: Fri, 2 Jun 2017 13:52:47 +0300 Subject: Improved warning "xxx is not BASE TABLE/SEQUENCE" - Changed warning to "'%-.192s.%-.192s' is not of type '%s'" to make the english a bit more correct --- sql/share/errmsg-utf8.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 1f282e6aee5..cfc544cc1bd 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -5202,7 +5202,7 @@ ER_FRM_UNKNOWN_TYPE rus "Файл '%-.192s' содержит неизвестный тип '%-.64s' в заголовке" ukr "Файл '%-.192s' має невідомий тип '%-.64s' у заголовку" ER_WRONG_OBJECT - eng "'%-.192s.%-.192s' is not %s" + eng "'%-.192s.%-.192s' is not of type '%s'" ger "'%-.192s.%-.192s' ist nicht %s" rus "'%-.192s.%-.192s' - не %s" ukr "'%-.192s.%-.192s' не є %s" -- cgit v1.2.1 From 36ae8846ca86bc82900f8c1b2bbad2666a3e9945 Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 3 Jun 2017 16:08:23 +0300 Subject: Fixed sequences based on comments from Peter Gulutzan and Andrii Nikitin - Changed names of SEQUENCE table columns to be more close to ANSI - Fixed error message for SHOW SEQUENCE non_existing_sequence - Allow syntax CACHE +1 - Fixed ALTER TABLE for TEMPORARY sequences. --- sql/ha_sequence.cc | 14 +++++++++++++- sql/sql_sequence.cc | 26 +++++++++++++++----------- sql/sql_sequence.h | 4 +++- sql/sql_show.cc | 10 ++++++---- sql/sql_yacc.yy | 29 +++++++++++++++++------------ 5 files changed, 54 insertions(+), 29 deletions(-) (limited to 'sql') diff --git a/sql/ha_sequence.cc b/sql/ha_sequence.cc index e0e9e2a42e7..7f2248bf3cb 100644 --- a/sql/ha_sequence.cc +++ b/sql/ha_sequence.cc @@ -198,6 +198,18 @@ int ha_sequence::write_row(uchar *buf) /* This calls is from ha_open() as part of create table */ DBUG_RETURN(file->write_row(buf)); } + if (unlikely(sequence->initialized == SEQUENCE::SEQ_IN_ALTER)) + { + int error= 0; + /* This is called from alter table */ + tmp_seq.read_fields(table); + if (tmp_seq.check_and_adjust(0)) + DBUG_RETURN(HA_ERR_SEQUENCE_INVALID_DATA); + sequence->copy(&tmp_seq); + if (!(error= file->write_row(buf))) + sequence->initialized= SEQUENCE::SEQ_READY_TO_USE; + DBUG_RETURN(error); + } if (unlikely(sequence->initialized != SEQUENCE::SEQ_READY_TO_USE)) DBUG_RETURN(HA_ERR_WRONG_COMMAND); @@ -280,7 +292,7 @@ int ha_sequence::extra(enum ha_extra_function operation) if (operation == HA_EXTRA_PREPARE_FOR_ALTER_TABLE) { /* In case of ALTER TABLE allow ::write_row() to copy rows */ - sequence->initialized= SEQUENCE::SEQ_IN_PREPARE; + sequence->initialized= SEQUENCE::SEQ_IN_ALTER; } return file->extra(operation); } diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc index 35792bfe72e..be360c59e34 100644 --- a/sql/sql_sequence.cc +++ b/sql/sql_sequence.cc @@ -47,18 +47,19 @@ struct Field_definition static Field_definition sequence_structure[]= { - {"next_value", 21, &type_handler_longlong, {STRING_WITH_LEN("next not cached value")}, - FL}, - {"min_value", 21, &type_handler_longlong, {STRING_WITH_LEN("min value")}, FL}, - {"max_value", 21, &type_handler_longlong, {STRING_WITH_LEN("max value")}, FL}, - {"start", 21, &type_handler_longlong, {STRING_WITH_LEN("start value")}, FL}, + {"next_not_cached_value", 21, &type_handler_longlong, + {STRING_WITH_LEN("")}, FL}, + {"minimum_value", 21, &type_handler_longlong, STRING_WITH_LEN(""), FL}, + {"maximum_value", 21, &type_handler_longlong, STRING_WITH_LEN(""), FL}, + {"start_value", 21, &type_handler_longlong, {STRING_WITH_LEN("start value when sequences is created or value if RESTART is used")}, FL}, {"increment", 21, &type_handler_longlong, {C_STRING_WITH_LEN("increment value")}, FL}, - {"cache", 21, &type_handler_longlong, {STRING_WITH_LEN("cache size")}, FL}, - {"cycle", 1, &type_handler_tiny, {STRING_WITH_LEN("cycle state")}, + {"cache_size", 21, &type_handler_longlong, STRING_WITH_LEN(""), + FL | UNSIGNED_FLAG}, + {"cycle_option", 1, &type_handler_tiny, {STRING_WITH_LEN("0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed")}, FL | UNSIGNED_FLAG }, - {"round", 21, &type_handler_longlong, - {STRING_WITH_LEN("How many cycles has been done")}, FL}, + {"cycle_count", 21, &type_handler_longlong, + {STRING_WITH_LEN("How many cycles have been done")}, FL}, {NULL, 0, &type_handler_longlong, {STRING_WITH_LEN("")}, 0} }; @@ -458,9 +459,12 @@ int SEQUENCE::read_initial_values(TABLE *table_arg) DBUG_RETURN(error); } + /* - Read data from sequence table and update values - Done when table is opened + Do the actiual reading of data from sequence table and + update values in the sequence object. + + Called once from when table is opened */ int SEQUENCE::read_stored_values() diff --git a/sql/sql_sequence.h b/sql/sql_sequence.h index b560d03ca52..1dc777657d5 100644 --- a/sql/sql_sequence.h +++ b/sql/sql_sequence.h @@ -88,7 +88,8 @@ protected: class SEQUENCE :public sequence_definition { public: - enum seq_init { SEQ_UNINTIALIZED, SEQ_IN_PREPARE, SEQ_READY_TO_USE }; + enum seq_init { SEQ_UNINTIALIZED, SEQ_IN_PREPARE, SEQ_IN_ALTER, + SEQ_READY_TO_USE }; SEQUENCE(); ~SEQUENCE(); int read_initial_values(TABLE *table); @@ -101,6 +102,7 @@ public: { sequence_definition::operator= (*seq); adjust_values(reserved_until); + all_values_used= 0; } longlong next_value(TABLE *table, bool second_round, int *error); bool set_value(TABLE *table, longlong next_value, ulonglong round_arg, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 1fbd631b754..7f2a3c4cd0b 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1181,8 +1181,8 @@ mysqld_show_create_get_fields(THD *thd, TABLE_LIST *table_list, else if (thd->lex->table_type == TABLE_TYPE_SEQUENCE && table_list->table->s->table_type != TABLE_TYPE_SEQUENCE) { - my_error(ER_WRONG_OBJECT, MYF(0), - table_list->db, table_list->table_name, "SEQUENCE"); + my_error(ER_NOT_SEQUENCE, MYF(0), + table_list->db, table_list->table_name); goto exit; } @@ -4372,7 +4372,8 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, */ if (!is_show_fields_or_keys && result && (thd->get_stmt_da()->sql_errno() == ER_NO_SUCH_TABLE || - thd->get_stmt_da()->sql_errno() == ER_WRONG_OBJECT)) + thd->get_stmt_da()->sql_errno() == ER_WRONG_OBJECT || + thd->get_stmt_da()->sql_errno() == ER_NOT_SEQUENCE)) { /* Hide error for a non-existing table. @@ -4699,7 +4700,8 @@ static int fill_schema_table_from_frm(THD *thd, TABLE *table, if (!share) { if (thd->get_stmt_da()->sql_errno() == ER_NO_SUCH_TABLE || - thd->get_stmt_da()->sql_errno() == ER_WRONG_OBJECT) + thd->get_stmt_da()->sql_errno() == ER_WRONG_OBJECT || + thd->get_stmt_da()->sql_errno() == ER_NOT_SEQUENCE) { res= 0; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 9feccb3b12a..a92adc470ab 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -11969,17 +11969,22 @@ delete_limit_clause: | LIMIT limit_option ROWS_SYM EXAMINED_SYM { thd->parse_error(); MYSQL_YYABORT; } ; +opt_plus: + /* empty */ + | '+' + ; + int_num: - NUM { int error; $$= (int) my_strtoll10($1.str, (char**) 0, &error); } + opt_plus NUM { int error; $$= (int) my_strtoll10($2.str, (char**) 0, &error); } | '-' NUM { int error; $$= -(int) my_strtoll10($2.str, (char**) 0, &error); } ulong_num: - NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } + opt_plus NUM { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); } | HEX_NUM { $$= (ulong) strtol($1.str, (char**) 0, 16); } - | LONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } - | ULONGLONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } - | DECIMAL_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } - | FLOAT_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } + | opt_plus LONG_NUM { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus ULONGLONG_NUM { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus DECIMAL_NUM { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus FLOAT_NUM { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); } ; real_ulong_num: @@ -11991,18 +11996,18 @@ real_ulong_num: ; longlong_num: - NUM { int error; $$= (longlong) my_strtoll10($1.str, (char**) 0, &error); } + opt_plus NUM { int error; $$= (longlong) my_strtoll10($2.str, (char**) 0, &error); } | LONG_NUM { int error; $$= (longlong) my_strtoll10($1.str, (char**) 0, &error); } | '-' NUM { int error; $$= -(longlong) my_strtoll10($2.str, (char**) 0, &error); } | '-' LONG_NUM { int error; $$= -(longlong) my_strtoll10($2.str, (char**) 0, &error); } ulonglong_num: - NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } - | ULONGLONG_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } - | LONG_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } - | DECIMAL_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } - | FLOAT_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } + opt_plus NUM { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus ULONGLONG_NUM { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus LONG_NUM { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus DECIMAL_NUM { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus FLOAT_NUM { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); } ; real_ulonglong_num: -- cgit v1.2.1 From 3d428e017dbc51ebbaace4b13802b5bab6a2b16a Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 3 Jun 2017 16:16:18 +0300 Subject: Cleanups (LINT_INIT & --debug-mutex-deadlock-detector - Removed duplicate entry for --debug-mutex-deadlock-detector - Fixed wrong usage of LINT_INIT --- sql/mysqld.cc | 7 ------- sql/opt_range.cc | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d7c46071c38..74efb91cbd1 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7297,13 +7297,6 @@ struct my_option my_long_options[]= &max_binlog_dump_events, &max_binlog_dump_events, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif /* HAVE_REPLICATION */ -#ifdef SAFE_MUTEX - {"debug-mutex-deadlock-detector", 0, - "Enable checking of wrong mutex usage.", - &safe_mutex_deadlock_detector, - &safe_mutex_deadlock_detector, - 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, -#endif {"debug-no-sync", 0, "Disables system sync calls. Only for running tests or debugging!", &my_disable_sync, &my_disable_sync, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 284f4348080..40184d7a421 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -7501,7 +7501,7 @@ SEL_TREE *Item_bool_func::get_full_func_mm_tree(RANGE_OPT_PARAM *param, param->current_table); #ifdef HAVE_SPATIAL Field::geometry_type sav_geom_type; - LINT_INIT(sav_geom_type); + LINT_INIT_STRUCT(sav_geom_type); if (field_item->field->type() == MYSQL_TYPE_GEOMETRY) { -- cgit v1.2.1 From da61107fc8481b03ae858188dd03b3114e7aa084 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Mon, 5 Jun 2017 13:10:24 +0530 Subject: MDEV-9544 FLUSH [RELAY] LOGS does not rotate logs for a named slave Problem:- In the case of multisource replication/named slave when we run "FLUSH LOGS" , it does not flush logs. Solution:- A new function Master_info_index->flush_all_relay_logs() is created which will rotate relay logs for all named slave. This will be called in reload_acl_and_cache function when connection_name.length == 0 --- sql/rpl_mi.cc | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- sql/rpl_mi.h | 2 ++ sql/sql_reload.cc | 8 ++++++-- 3 files changed, 58 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index c9dcf7b8fd7..ed756a996ca 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -41,7 +41,7 @@ Master_info::Master_info(LEX_STRING *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) { host[0] = 0; user[0] = 0; password[0] = 0; @@ -1980,4 +1980,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 31c0f280ac1..d0f6171815c 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/sql_reload.cc b/sql/sql_reload.cc index 995c4c0a838..376dfeb1542 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; -- cgit v1.2.1 From 8a65b49c4320e906bafb0cbcc561f4ef72efbfec Mon Sep 17 00:00:00 2001 From: Monty Date: Wed, 7 Jun 2017 16:09:33 +0300 Subject: Update sql_yacc_ora.yy with latest changes of sql_yacc.yy --- sql/sql_yacc_ora.yy | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'sql') diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 7834eb8af4c..acf6c0b1326 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -12050,17 +12050,22 @@ delete_limit_clause: | LIMIT limit_option ROWS_SYM EXAMINED_SYM { thd->parse_error(); MYSQL_YYABORT; } ; +opt_plus: + /* empty */ + | '+' + ; + int_num: - NUM { int error; $$= (int) my_strtoll10($1.str, (char**) 0, &error); } + opt_plus NUM { int error; $$= (int) my_strtoll10($2.str, (char**) 0, &error); } | '-' NUM { int error; $$= -(int) my_strtoll10($2.str, (char**) 0, &error); } ulong_num: - NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } + opt_plus NUM { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); } | HEX_NUM { $$= (ulong) strtol($1.str, (char**) 0, 16); } - | LONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } - | ULONGLONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } - | DECIMAL_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } - | FLOAT_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } + | opt_plus LONG_NUM { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus ULONGLONG_NUM { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus DECIMAL_NUM { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus FLOAT_NUM { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); } ; real_ulong_num: @@ -12072,18 +12077,18 @@ real_ulong_num: ; longlong_num: - NUM { int error; $$= (longlong) my_strtoll10($1.str, (char**) 0, &error); } + opt_plus NUM { int error; $$= (longlong) my_strtoll10($2.str, (char**) 0, &error); } | LONG_NUM { int error; $$= (longlong) my_strtoll10($1.str, (char**) 0, &error); } | '-' NUM { int error; $$= -(longlong) my_strtoll10($2.str, (char**) 0, &error); } | '-' LONG_NUM { int error; $$= -(longlong) my_strtoll10($2.str, (char**) 0, &error); } ulonglong_num: - NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } - | ULONGLONG_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } - | LONG_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } - | DECIMAL_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } - | FLOAT_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } + opt_plus NUM { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus ULONGLONG_NUM { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus LONG_NUM { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus DECIMAL_NUM { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus FLOAT_NUM { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); } ; real_ulonglong_num: -- cgit v1.2.1 From 7a12894de11ab04b93c9e96359008386b3b41cbb Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 10 Jun 2017 16:39:39 -0700 Subject: Fixed the bug mdev12992. When the SELECT query from a trigger that used a subquery in its SELECT list was prepared the counter select_n_having_items was incremented in the constructor Item::Item(THD *thd). As a result each invocation of the trigger required more and more memory for the ref_pointer_array for this SELECT. Made sure that the counter st_select_lex::select_n_having_items would be incremented only at the first execution of such trigger. --- sql/item.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index a130cfdc0f2..afdef1ac57c 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -490,7 +490,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; -- cgit v1.2.1 From 91ae1258ee29405c0e7c6c196aef2e870c11ec01 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 7 Apr 2017 15:38:01 +0200 Subject: MDEV-12471: BULK Command BULK execution moved to a new command. --- sql/item.cc | 2 +- sql/item.h | 4 +- sql/sql_insert.cc | 10 +-- sql/sql_parse.cc | 7 +- sql/sql_prepare.cc | 222 ++++++++++++++++++++++++++++++++++++++--------------- sql/sql_prepare.h | 3 +- 6 files changed, 173 insertions(+), 75 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index afdef1ac57c..8db5cfc6442 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3347,7 +3347,7 @@ Item_param::Item_param(THD *thd, uint pos_in_query_arg): state(NO_VALUE), /* Don't pretend to be a literal unless value for this item is set. */ item_type(PARAM_ITEM), - indicators(0), indicator(STMT_INDICATOR_NONE), + indicator(STMT_INDICATOR_NONE), set_param_func(default_set_param_func), m_out_param_info(NULL), /* diff --git a/sql/item.h b/sql/item.h index 42e9fd94331..5ed3e8acb82 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2873,10 +2873,8 @@ public: }; /* - Used for bulk protocol. Indicates if we should expect - indicators byte before value of the parameter + Used for bulk protocol only. */ - my_bool indicators; enum enum_indicator_type indicator; /* diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 8e5dfb4f69c..24e4c07fdb9 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -697,9 +697,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, bool using_bulk_insert= 0; uint value_count; ulong counter = 1; - ulong iteration= 0; + /* counter of iteration in bulk PS operation*/ + ulonglong iteration= 0; ulonglong id; - ulong bulk_iterations= bulk_parameters_iterations(thd); COPY_INFO info; TABLE *table= 0; List_iterator_fast its(values_list); @@ -767,7 +767,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, DBUG_RETURN(TRUE); value_count= values->elements; - DBUG_ASSERT(bulk_iterations > 0); if (mysql_prepare_insert(thd, table_list, table, fields, values, update_fields, update_values, duplic, &unused_conds, FALSE)) @@ -939,6 +938,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, } do { + DBUG_PRINT("info", ("iteration %llu", iteration)); if (iteration && bulk_parameters_set(thd)) goto abort; @@ -1059,7 +1059,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, } its.rewind(); iteration++; - } while (iteration < bulk_iterations); + } while (bulk_parameters_iterations(thd)); values_loop_end: free_underlaid_joins(thd, &thd->lex->select_lex); @@ -1206,7 +1206,7 @@ values_loop_end: retval= thd->lex->explain->send_explain(thd); goto abort; } - if ((bulk_iterations * values_list.elements) == 1 && (!(thd->variables.option_bits & OPTION_WARNINGS) || + if ((iteration * values_list.elements) == 1 && (!(thd->variables.option_bits & OPTION_WARNINGS) || !thd->cuted_fields)) { my_ok(thd, info.copied + info.deleted + diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e97871e3dcf..412cd1dac70 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -391,7 +391,7 @@ const LEX_STRING command_name[257]={ { 0, 0 }, //247 { 0, 0 }, //248 { 0, 0 }, //249 - { 0, 0 }, //250 + { C_STRING_WITH_LEN("Bulk_execute") }, //250 { C_STRING_WITH_LEN("Slave_worker") }, //251 { C_STRING_WITH_LEN("Slave_IO") }, //252 { C_STRING_WITH_LEN("Slave_SQL") }, //253 @@ -1749,6 +1749,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } break; } + case COM_STMT_BULK_EXECUTE: + { + mysqld_stmt_bulk_execute(thd, packet, packet_length); + break; + } case COM_STMT_EXECUTE: { mysqld_stmt_execute(thd, packet, packet_length); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index cd330d8ee26..11274fbbaa2 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -164,7 +164,6 @@ public: Server_side_cursor *cursor; uchar *packet; uchar *packet_end; - ulong iterations; uint param_count; uint last_errno; uint flags; @@ -183,7 +182,9 @@ public: */ uint select_number_after_prepare; char last_error[MYSQL_ERRMSG_SIZE]; + my_bool iterations; my_bool start_param; + my_bool read_types; #ifndef EMBEDDED_LIBRARY bool (*set_params)(Prepared_statement *st, uchar *data, uchar *data_end, uchar *read_pos, String *expanded_query); @@ -213,11 +214,10 @@ public: uchar *packet_arg, uchar *packet_end_arg); bool execute_bulk_loop(String *expanded_query, bool open_cursor, - uchar *packet_arg, uchar *packet_end_arg, - ulong iterations); + uchar *packet_arg, uchar *packet_end_arg); bool execute_server_runnable(Server_runnable *server_runnable); my_bool set_bulk_parameters(bool reset); - ulong bulk_iterations(); + bool bulk_iterations() { return iterations; }; /* Destroy this statement */ void deallocate(); bool execute_immediate(const char *query, uint query_length); @@ -935,6 +935,7 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array, for (Item_param **it= begin; it < end; ++it) { Item_param *param= *it; + param->indicator= STMT_INDICATOR_NONE; // only for bulk parameters if (!param->has_long_data_value()) { if (is_param_null(null_array, (uint) (it - begin))) @@ -979,10 +980,7 @@ static bool insert_bulk_params(Prepared_statement *stmt, param->reset(); if (!param->has_long_data_value()) { - if (param->indicators) - param->indicator= (enum_indicator_type) *((*read_pos)++); - else - param->indicator= STMT_INDICATOR_NONE; + param->indicator= (enum_indicator_type) *((*read_pos)++); if ((*read_pos) > data_end) DBUG_RETURN(1); switch (param->indicator) @@ -993,6 +991,8 @@ static bool insert_bulk_params(Prepared_statement *stmt, param->set_param_func(param, read_pos, (uint) (data_end - (*read_pos))); if (param->has_no_value()) DBUG_RETURN(1); + if (param->convert_str_value(stmt->thd)) + DBUG_RETURN(1); /* out of memory */ break; case STMT_INDICATOR_NULL: param->set_null(); @@ -1011,6 +1011,36 @@ static bool insert_bulk_params(Prepared_statement *stmt, DBUG_RETURN(0); } +static bool set_conversion_functions(Prepared_statement *stmt, + uchar **data, uchar *data_end) +{ + uchar *read_pos= *data; + const uint signed_bit= 1 << 15; + DBUG_ENTER("set_conversion_functions"); + /* + First execute or types altered by the client, setup the + conversion routines for all parameters (one time) + */ + Item_param **it= stmt->param_array; + Item_param **end= it + stmt->param_count; + THD *thd= stmt->thd; + for (; it < end; ++it) + { + ushort typecode; + + if (read_pos >= data_end) + DBUG_RETURN(1); + + typecode= sint2korr(read_pos); + read_pos+= 2; + (**it).unsigned_flag= MY_TEST(typecode & signed_bit); + setup_one_conversion_function(thd, *it, (uchar) (typecode & 0xff)); + } + *data= read_pos; + DBUG_RETURN(0); +} + + static bool setup_conversion_functions(Prepared_statement *stmt, uchar **data, uchar *data_end, bool bulk_protocol= 0) @@ -1024,30 +1054,9 @@ static bool setup_conversion_functions(Prepared_statement *stmt, if (*read_pos++) //types supplied / first execute { - /* - First execute or types altered by the client, setup the - conversion routines for all parameters (one time) - */ - Item_param **it= stmt->param_array; - Item_param **end= it + stmt->param_count; - THD *thd= stmt->thd; - for (; it < end; ++it) - { - ushort typecode; - const uint signed_bit= 1 << 15; - const uint indicators_bit= 1 << 14; - - if (read_pos >= data_end) - DBUG_RETURN(1); - - typecode= sint2korr(read_pos); - read_pos+= 2; - (**it).unsigned_flag= MY_TEST(typecode & signed_bit); - if (bulk_protocol) - (**it).indicators= MY_TEST(typecode & indicators_bit); - setup_one_conversion_function(thd, *it, - (uchar) (typecode & 0xff)); - } + *data= read_pos; + bool res= set_conversion_functions(stmt, data, data_end); + DBUG_RETURN(res); } *data= read_pos; DBUG_RETURN(0); @@ -3032,6 +3041,14 @@ static void reset_stmt_params(Prepared_statement *stmt) } +static void mysql_stmt_execute_common(THD *thd, + ulong stmt_id, + uchar *packet, + uchar *packet_end, + ulong cursor_flags, + bool iteration, + bool types); + /** COM_STMT_EXECUTE handler: execute a previously prepared statement. @@ -3054,20 +3071,91 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length) uchar *packet= (uchar*)packet_arg; // GCC 4.0.1 workaround ulong stmt_id= uint4korr(packet); ulong flags= (ulong) packet[4]; -#ifndef EMBEDDED_LIBRARY - ulong iterations= uint4korr(packet + 5); -#else - ulong iterations= 0; // no support -#endif + uchar *packet_end= packet + packet_length; + DBUG_ENTER("mysqld_stmt_execute"); + + packet+= 9; /* stmt_id + 5 bytes of flags */ + + mysql_stmt_execute_common(thd, stmt_id, packet, packet_end, flags, FALSE, + FALSE); + DBUG_VOID_RETURN; +} + + +/** + COM_STMT_BULK_EXECUTE handler: execute a previously prepared statement. + + If there are any parameters, then replace parameter markers with the + data supplied from the client, and then execute the statement. + This function uses binary protocol to send a possible result set + to the client. + + @param thd current thread + @param packet_arg parameter types and data, if any + @param packet_length packet length, including the terminator character. + + @return + none: in case of success OK packet or a result set is sent to the + client, otherwise an error message is set in THD. +*/ + +void mysqld_stmt_bulk_execute(THD *thd, char *packet_arg, uint packet_length) +{ + uchar *packet= (uchar*)packet_arg; // GCC 4.0.1 workaround + ulong stmt_id= uint4korr(packet); + uint flags= (uint) uint2korr(packet + 4); + uchar *packet_end= packet + packet_length; + DBUG_ENTER("mysqld_stmt_execute_bulk"); + + if (!(thd->client_capabilities & + MARIADB_CLIENT_STMT_BULK_OPERATIONS)) + { + DBUG_PRINT("error", + ("An attempt to execute bulk operation without support")); + my_error(ER_UNSUPPORTED_PS, MYF(0)); + } + /* Check for implemented parameters */ + if (flags & (~STMT_BULK_FLAG_CLIENT_SEND_TYPES)) + { + DBUG_PRINT("error", ("unsupported bulk execute flags %x", flags)); + my_error(ER_UNSUPPORTED_PS, MYF(0)); + } + + /* stmt id and two bytes of flags */ + packet+= 4 + 2; + mysql_stmt_execute_common(thd, stmt_id, packet, packet_end, 0, TRUE, + (flags & STMT_BULK_FLAG_CLIENT_SEND_TYPES)); + DBUG_VOID_RETURN; +} + + +/** + Common part of prepared statement execution + + @param thd THD handle + @param stmt_id id of the prepared statement + @param paket packet with parameters to bind + @param packet_end pointer to the byte after parameters end + @param cursor_flags cursor flags + @param bulk_op id it bulk operation + @param read_types flag say that types muast been read +*/ + +static void mysql_stmt_execute_common(THD *thd, + ulong stmt_id, + uchar *packet, + uchar *packet_end, + ulong cursor_flags, + bool bulk_op, + bool read_types) +{ /* Query text for binary, general or slow log, if any of them is open */ String expanded_query; - uchar *packet_end= packet + packet_length; Prepared_statement *stmt; Protocol *save_protocol= thd->protocol; bool open_cursor; - DBUG_ENTER("mysqld_stmt_execute"); - - packet+= 9; /* stmt_id + 5 bytes of flags */ + DBUG_ENTER("mysqld_stmt_execute_common"); + DBUG_ASSERT((!read_types) || (read_types && bulk_op)); /* First of all clear possible warnings from the previous command */ thd->reset_for_next_command(); @@ -3079,21 +3167,21 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length) llstr(stmt_id, llbuf), "mysqld_stmt_execute"); DBUG_VOID_RETURN; } + stmt->read_types= read_types; #if defined(ENABLED_PROFILING) thd->profiling.set_query_source(stmt->query(), stmt->query_length()); #endif DBUG_PRINT("exec_query", ("%s", stmt->query())); - DBUG_PRINT("info",("stmt: %p iterations: %lu", stmt, iterations)); + DBUG_PRINT("info",("stmt: %p bulk_op %d", stmt, bulk_op)); - open_cursor= MY_TEST(flags & (ulong) CURSOR_TYPE_READ_ONLY); + open_cursor= MY_TEST(cursor_flags & (ulong) CURSOR_TYPE_READ_ONLY); thd->protocol= &thd->protocol_binary; - if (iterations <= 1) + if (!bulk_op) stmt->execute_loop(&expanded_query, open_cursor, packet, packet_end); else - stmt->execute_bulk_loop(&expanded_query, open_cursor, packet, packet_end, - iterations); + stmt->execute_bulk_loop(&expanded_query, open_cursor, packet, packet_end); thd->protocol= save_protocol; sp_cache_enforce_limit(thd->sp_proc_cache, stored_program_cache_size); @@ -3600,11 +3688,12 @@ Prepared_statement::Prepared_statement(THD *thd_arg) cursor(0), packet(0), packet_end(0), - iterations(0), param_count(0), last_errno(0), flags((uint) IS_IN_USE), + iterations(0), start_param(0), + read_types(0), m_sql_mode(thd->variables.sql_mode) { init_sql_alloc(&main_mem_root, thd_arg->variables.query_alloc_block_size, @@ -3641,7 +3730,7 @@ void Prepared_statement::setup_set_params() set_params_from_actual_params= insert_params_from_actual_params_with_log; #ifndef EMBEDDED_LIBRARY set_params= insert_params_with_log; - set_bulk_params= insert_bulk_params; // TODO: add binlog support + set_bulk_params= insert_bulk_params; // RBR is on for bulk operation #else //TODO: add bulk support for bulk parameters set_params_data= emb_insert_params_with_log; @@ -4023,7 +4112,7 @@ Prepared_statement::execute_loop(String *expanded_query, Reprepare_observer reprepare_observer; bool error; int reprepare_attempt= 0; - iterations= 0; + iterations= FALSE; /* - In mysql_sql_stmt_execute() we hide all "external" Items @@ -4126,11 +4215,11 @@ my_bool bulk_parameters_set(THD *thd) DBUG_RETURN(FALSE); } -ulong bulk_parameters_iterations(THD *thd) +my_bool bulk_parameters_iterations(THD *thd) { Prepared_statement *stmt= (Prepared_statement *) thd->bulk_param; if (!stmt) - return 1; + return FALSE; return stmt->bulk_iterations(); } @@ -4138,7 +4227,8 @@ ulong bulk_parameters_iterations(THD *thd) my_bool Prepared_statement::set_bulk_parameters(bool reset) { DBUG_ENTER("Prepared_statement::set_bulk_parameters"); - DBUG_PRINT("info", ("iteration: %lu", iterations)); + DBUG_PRINT("info", ("iteration: %d", iterations)); + if (iterations) { #ifndef EMBEDDED_LIBRARY @@ -4152,31 +4242,24 @@ my_bool Prepared_statement::set_bulk_parameters(bool reset) reset_stmt_params(this); DBUG_RETURN(true); } - iterations--; + if (packet >= packet_end) + iterations= FALSE; } start_param= 0; DBUG_RETURN(false); } -ulong Prepared_statement::bulk_iterations() -{ - if (iterations) - return iterations; - return start_param ? 1 : 0; -} - bool Prepared_statement::execute_bulk_loop(String *expanded_query, bool open_cursor, uchar *packet_arg, - uchar *packet_end_arg, - ulong iterations_arg) + uchar *packet_end_arg) { Reprepare_observer reprepare_observer; bool error= 0; packet= packet_arg; packet_end= packet_end_arg; - iterations= iterations_arg; + iterations= TRUE; start_param= true; #ifndef DBUG_OFF Item *free_list_state= thd->free_list; @@ -4190,16 +4273,26 @@ Prepared_statement::execute_bulk_loop(String *expanded_query, thd->set_bulk_execution(0); return TRUE; } + /* Check for non zero parameter count*/ + if (param_count == 0) + { + DBUG_PRINT("error", ("Statement with no parameters for bulk execution.")); + my_error(ER_UNSUPPORTED_PS, MYF(0)); + thd->set_bulk_execution(0); + return TRUE; + } if (!(sql_command_flags[lex->sql_command] & CF_SP_BULK_SAFE)) { + DBUG_PRINT("error", ("Command is not supported in bulk execution.")); my_error(ER_UNSUPPORTED_PS, MYF(0)); thd->set_bulk_execution(0); return TRUE; } #ifndef EMBEDDED_LIBRARY - if (setup_conversion_functions(this, &packet, packet_end, TRUE)) + if (read_types && + set_conversion_functions(this, &packet, packet_end)) #else // bulk parameters are not supported for embedded, so it will an error #endif @@ -4210,6 +4303,7 @@ Prepared_statement::execute_bulk_loop(String *expanded_query, thd->set_bulk_execution(0); return true; } + read_types= FALSE; #ifdef NOT_YET_FROM_MYSQL_5_6 if (unlikely(thd->security_ctx->password_expired && diff --git a/sql/sql_prepare.h b/sql/sql_prepare.h index 820cb43e6d5..203b37b3b26 100644 --- a/sql/sql_prepare.h +++ b/sql/sql_prepare.h @@ -72,6 +72,7 @@ private: void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length); void mysqld_stmt_execute(THD *thd, char *packet, uint packet_length); +void mysqld_stmt_execute_bulk(THD *thd, char *packet, uint packet_length); void mysqld_stmt_bulk_execute(THD *thd, char *packet, uint packet_length); void mysqld_stmt_close(THD *thd, char *packet); void mysql_sql_stmt_prepare(THD *thd); @@ -83,7 +84,7 @@ void mysqld_stmt_reset(THD *thd, char *packet); void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length); void reinit_stmt_before_use(THD *thd, LEX *lex); -ulong bulk_parameters_iterations(THD *thd); +my_bool bulk_parameters_iterations(THD *thd); my_bool bulk_parameters_set(THD *thd); /** Execute a fragment of server code in an isolated context, so that -- cgit v1.2.1 From e5980bf1b12f6dc4fa4ab44feb1b6a734dcc84d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 16 Jun 2017 11:05:09 +0300 Subject: Remove the unnecessary method handlerton::release_temporary_latches() The sole purpose of handlerton::release_temporary_latches and its wrapper function was to release the InnoDB adaptive hash index latch (btr_search_latch). When the btr_search_latch was split into an array of latches in MySQL 5.7.8 as part of the Oracle Bug#20985298 fix, the "caching" of the latch across storage engine API calls was removed. As part of that, the function trx_search_latch_release_if_reserved() was changed to an assertion and the function trx_reserve_search_latch_if_not_reserved() was removed, and handlerton::release_temporary_latches() practically became a no-op. Note: MDEV-12121 replaced the function trx_search_latch_release_if_reserved() with the more appropriately named macro trx_assert_no_search_latch(). --- sql/filesort.cc | 6 ------ sql/handler.cc | 38 -------------------------------------- sql/handler.h | 4 ---- sql/sql_cache.cc | 8 +------- sql/sql_class.cc | 14 -------------- sql/sql_insert.cc | 5 +---- 6 files changed, 2 insertions(+), 73 deletions(-) (limited to 'sql') diff --git a/sql/filesort.cc b/sql/filesort.cc index 5d5b210e62d..83c8442937e 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -182,12 +182,6 @@ SORT_INFO *filesort(THD *thd, TABLE *table, Filesort *filesort, outfile= &sort->io_cache; - /* - Release InnoDB's adaptive hash index latch (if holding) before - running a sort. - */ - ha_release_temporary_latches(thd); - my_b_clear(&tempfile); my_b_clear(&buffpek_pointers); buffpek=0; diff --git a/sql/handler.cc b/sql/handler.cc index 919fd74191e..95b16a51980 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2015,44 +2015,6 @@ commit_checkpoint_notify_ha(handlerton *hton, void *cookie) } -/** - @details - This function should be called when MySQL sends rows of a SELECT result set - or the EOF mark to the client. It releases a possible adaptive hash index - S-latch held by thd in InnoDB and also releases a possible InnoDB query - FIFO ticket to enter InnoDB. To save CPU time, InnoDB allows a thd to - keep them over several calls of the InnoDB handler interface when a join - is executed. But when we let the control to pass to the client they have - to be released because if the application program uses mysql_use_result(), - it may deadlock on the S-latch if the application on another connection - performs another SQL query. In MySQL-4.1 this is even more important because - there a connection can have several SELECT queries open at the same time. - - @param thd the thread handle of the current connection - - @return - always 0 -*/ - -int ha_release_temporary_latches(THD *thd) -{ - Ha_trx_info *info; - - /* - Note that below we assume that only transactional storage engines - may need release_temporary_latches(). If this will ever become false, - we could iterate on thd->open_tables instead (and remove duplicates - as if (!seen[hton->slot]) { seen[hton->slot]=1; ... }). - */ - for (info= thd->transaction.stmt.ha_list; info; info= info->next()) - { - handlerton *hton= info->ht(); - if (hton && hton->release_temporary_latches) - hton->release_temporary_latches(hton, thd); - } - return 0; -} - /** Check if all storage engines used in transaction agree that after rollback to savepoint it is safe to release MDL locks acquired after diff --git a/sql/handler.h b/sql/handler.h index 7750c8ad7fb..ee4836dcc34 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1211,7 +1211,6 @@ struct handlerton enum_binlog_command binlog_command, const char *query, uint query_length, const char *db, const char *table_name); - int (*release_temporary_latches)(handlerton *hton, THD *thd); /* Get log status. @@ -4282,9 +4281,6 @@ int ha_change_key_cache_param(KEY_CACHE *key_cache); int ha_repartition_key_cache(KEY_CACHE *key_cache); int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache); -/* report to InnoDB that control passes to the client */ -int ha_release_temporary_latches(THD *thd); - /* transactions: interface to handlerton functions */ int ha_start_consistent_snapshot(THD *thd); int ha_commit_or_rollback_by_xid(XID *xid, bool commit); diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 0bf83915ba8..18a75dd9024 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2013, 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 @@ -1465,12 +1465,6 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d", (int)flags.in_trans, (int)flags.autocommit)); - /* - Make InnoDB to release the adaptive hash index latch before - acquiring the query cache mutex. - */ - ha_release_temporary_latches(thd); - /* A table- or a full flush operation can potentially take a long time to finish. We choose not to wait for them and skip caching statements diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 26674829f2b..f8cf8295881 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2751,13 +2751,6 @@ int select_send::send_data(List &items) if (thd->killed == ABORT_QUERY) DBUG_RETURN(FALSE); - /* - We may be passing the control from mysqld to the client: release the - InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved - by thd - */ - ha_release_temporary_latches(thd); - protocol->prepare_for_resend(); if (protocol->send_result_set_row(&items)) { @@ -2776,13 +2769,6 @@ int select_send::send_data(List &items) bool select_send::send_eof() { - /* - We may be passing the control from mysqld to the client: release the - InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved - by thd - */ - ha_release_temporary_latches(thd); - /* Don't send EOF if we're in error condition (which implies we've already sent or are sending an error) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 24e4c07fdb9..5d6cf96a9a3 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.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 @@ -3751,9 +3751,6 @@ int select_insert::send_data(List &values) } } - // Release latches in case bulk insert takes a long time - ha_release_temporary_latches(thd); - error= write_record(thd, table, &info); table->auto_increment_field_not_null= FALSE; -- cgit v1.2.1 From 056bab0880544d91ea67d18fe8db65b4f6625482 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 16 Jun 2017 15:47:46 +0400 Subject: MDEV-12620 - set lock_wait_timeout = 1;flush tables with read lock; lock not released after timeout Release GRL if FLUSH TABLES phase failed. --- sql/sql_reload.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 376dfeb1542..d68ce96dc85 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -253,7 +253,8 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options, NOTE: my_error() has been already called by reopen_tables() within close_cached_tables(). */ - result= 1; + thd->global_read_lock.unlock_global_read_lock(thd); + return 1; } if (thd->global_read_lock.make_global_read_lock_block_commit(thd)) // Killed -- cgit v1.2.1 From cf4a6abea12fcc957c81753be084104455f3cd9b Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 15 Jun 2017 14:43:22 -0700 Subject: Fixed the bug mdev-13064. This is another attempt to fix the bug mdev-12992. This patch introduces st_select_lex::context_analysis_place for the place in SELECT where context analysis is currently performed. It's similar to st_select_lex::parsing_place, but it is used at the preparation stage. --- sql/item.cc | 5 ++--- sql/item_windowfunc.cc | 2 +- sql/sql_lex.h | 1 + sql/sql_select.cc | 33 ++++++++++++++++++--------------- 4 files changed, 22 insertions(+), 19 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 8db5cfc6442..df615b5ace9 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -490,8 +490,7 @@ Item::Item(THD *thd): command => we should check thd->lex->current_select on zero (thd->lex can be uninitialised) */ - if (thd->lex->current_select && - thd->stmt_arena->is_stmt_prepare_or_first_sp_execute()) + if (thd->lex->current_select) { enum_parsing_place place= thd->lex->current_select->parsing_place; @@ -5513,7 +5512,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) SELECT_LEX *select= thd->lex->current_select; thd->change_item_tree(reference, - select->parsing_place == IN_GROUP_BY && + select->context_analysis_place == IN_GROUP_BY && alias_name_used ? *rf->ref : rf); /* diff --git a/sql/item_windowfunc.cc b/sql/item_windowfunc.cc index 59a22c63ed5..27b007201c5 100644 --- a/sql/item_windowfunc.cc +++ b/sql/item_windowfunc.cc @@ -71,7 +71,7 @@ Item_window_func::fix_fields(THD *thd, Item **ref) { DBUG_ASSERT(fixed == 0); - enum_parsing_place place= thd->lex->current_select->parsing_place; + enum_parsing_place place= thd->lex->current_select->context_analysis_place; if (!(place == SELECT_LIST || place == IN_ORDER_BY)) { diff --git a/sql/sql_lex.h b/sql/sql_lex.h index face3bcc378..0c55ffc5892 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -855,6 +855,7 @@ public: /* reserved for exists 2 in */ uint select_n_reserved; enum_parsing_place parsing_place; /* where we are parsing expression */ + enum_parsing_place context_analysis_place; /* where we are in prepare */ bool with_sum_func; /* sum function indicator */ ulong table_join_options; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4c64cf29467..6c56f0115ca 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -648,17 +648,15 @@ setup_without_group(THD *thd, Ref_ptr_array ref_pointer_array, thd->lex->allow_sum_func|= (nesting_map)1 << select->nest_level; - save_place= thd->lex->current_select->parsing_place; - thd->lex->current_select->parsing_place= IN_ORDER_BY; + save_place= thd->lex->current_select->context_analysis_place; + thd->lex->current_select->context_analysis_place= IN_ORDER_BY; res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields, order); - thd->lex->current_select->parsing_place= save_place; - thd->lex->allow_sum_func&= ~((nesting_map)1 << select->nest_level); - save_place= thd->lex->current_select->parsing_place; - thd->lex->current_select->parsing_place= IN_GROUP_BY; + thd->lex->allow_sum_func&= ~((nesting_map)1 << select->nest_level); + thd->lex->current_select->context_analysis_place= IN_GROUP_BY; res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields, group, hidden_group_fields); - thd->lex->current_select->parsing_place= save_place; + thd->lex->current_select->context_analysis_place= save_place; thd->lex->allow_sum_func|= (nesting_map)1 << select->nest_level; res= res || setup_windows(thd, ref_pointer_array, tables, fields, all_fields, win_specs, win_funcs); @@ -712,6 +710,7 @@ JOIN::prepare(TABLE_LIST *tables_init, if (select_lex->handle_derived(thd->lex, DT_PREPARE)) DBUG_RETURN(1); + thd->lex->current_select->context_analysis_place= NO_MATTER; thd->lex->current_select->is_item_list_lookup= 1; /* If we have already executed SELECT, then it have not sense to prevent @@ -801,12 +800,13 @@ JOIN::prepare(TABLE_LIST *tables_init, ref_ptrs= ref_ptr_array_slice(0); - enum_parsing_place save_place= thd->lex->current_select->parsing_place; - thd->lex->current_select->parsing_place= SELECT_LIST; + enum_parsing_place save_place= + thd->lex->current_select->context_analysis_place; + thd->lex->current_select->context_analysis_place= SELECT_LIST; if (setup_fields(thd, ref_ptrs, fields_list, MARK_COLUMNS_READ, &all_fields, 1)) DBUG_RETURN(-1); - thd->lex->current_select->parsing_place= save_place; + thd->lex->current_select->context_analysis_place= save_place; if (setup_without_group(thd, ref_ptrs, tables_list, select_lex->leaf_tables, fields_list, @@ -22235,14 +22235,16 @@ int setup_order(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables, List &fields, List &all_fields, ORDER *order, bool from_window_spec) { - enum_parsing_place parsing_place= thd->lex->current_select->parsing_place; + enum_parsing_place context_analysis_place= + thd->lex->current_select->context_analysis_place; thd->where="order clause"; for (; order; order=order->next) { if (find_order_in_list(thd, ref_pointer_array, tables, order, fields, all_fields, FALSE, from_window_spec)) return 1; - if ((*order->item)->with_window_func && parsing_place != IN_ORDER_BY) + if ((*order->item)->with_window_func && + context_analysis_place != IN_ORDER_BY) { my_error(ER_WINDOW_FUNCTION_IN_WINDOW_SPEC, MYF(0)); return 1; @@ -22284,7 +22286,8 @@ setup_group(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables, List &fields, List &all_fields, ORDER *order, bool *hidden_group_fields, bool from_window_spec) { - enum_parsing_place parsing_place= thd->lex->current_select->parsing_place; + enum_parsing_place context_analysis_place= + thd->lex->current_select->context_analysis_place; *hidden_group_fields=0; ORDER *ord; @@ -22300,14 +22303,14 @@ setup_group(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables, all_fields, TRUE, from_window_spec)) return 1; (*ord->item)->marker= UNDEF_POS; /* Mark found */ - if ((*ord->item)->with_sum_func && parsing_place == IN_GROUP_BY) + if ((*ord->item)->with_sum_func && context_analysis_place == IN_GROUP_BY) { my_error(ER_WRONG_GROUP_FIELD, MYF(0), (*ord->item)->full_name()); return 1; } if ((*ord->item)->with_window_func) { - if (parsing_place == IN_GROUP_BY) + if (context_analysis_place == IN_GROUP_BY) my_error(ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION, MYF(0)); else my_error(ER_WINDOW_FUNCTION_IN_WINDOW_SPEC, MYF(0)); -- cgit v1.2.1