diff options
author | Sergei Golubchik <serg@mariadb.org> | 2020-05-09 20:43:36 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2020-05-09 20:43:36 +0200 |
commit | 13038e4705ed55e24362dfad977a1ee454cfebfd (patch) | |
tree | ac3d37fe69e802dec8008748b86cc901f116eead /sql | |
parent | 72c7b4eb4cc86ca2f6bdb9e105b67d39df018a40 (diff) | |
parent | f5844e7c4bc693783f088a5fc9c399b786ddc8c1 (diff) | |
download | mariadb-git-13038e4705ed55e24362dfad977a1ee454cfebfd.tar.gz |
Merge branch '10.4' into 10.5
Diffstat (limited to 'sql')
-rw-r--r-- | sql/handler.cc | 34 | ||||
-rw-r--r-- | sql/handler.h | 7 | ||||
-rw-r--r-- | sql/rowid_filter.cc | 8 | ||||
-rw-r--r-- | sql/session_tracker.cc | 3 | ||||
-rw-r--r-- | sql/sql_base.cc | 9 | ||||
-rw-r--r-- | sql/table.h | 3 |
6 files changed, 52 insertions, 12 deletions
diff --git a/sql/handler.cc b/sql/handler.cc index 3eb29a1f9fe..ffb89b30d92 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -6161,22 +6161,22 @@ int handler::compare_key2(key_range *range) const /** ICP callback - to be called by an engine to check the pushed condition */ -extern "C" enum icp_result handler_index_cond_check(void* h_arg) +extern "C" check_result_t handler_index_cond_check(void* h_arg) { handler *h= (handler*)h_arg; THD *thd= h->table->in_use; - enum icp_result res; + check_result_t res; enum thd_kill_levels abort_at= h->has_transactions() ? THD_ABORT_SOFTLY : THD_ABORT_ASAP; if (thd_kill_level(thd) > abort_at) - return ICP_ABORTED_BY_USER; + return CHECK_ABORTED_BY_USER; if (h->end_range && h->compare_key2(h->end_range) > 0) - return ICP_OUT_OF_RANGE; + return CHECK_OUT_OF_RANGE; h->increment_statistics(&SSV::ha_icp_attempts); - if ((res= h->pushed_idx_cond->val_int()? ICP_MATCH : ICP_NO_MATCH) == - ICP_MATCH) + if ((res= h->pushed_idx_cond->val_int()? CHECK_POS : CHECK_NEG) == + CHECK_POS) h->increment_statistics(&SSV::ha_icp_match); return res; } @@ -6187,12 +6187,30 @@ extern "C" enum icp_result handler_index_cond_check(void* h_arg) keys of the rows whose data is to be fetched against the used rowid filter */ -extern "C" int handler_rowid_filter_check(void *h_arg) +extern "C" +check_result_t handler_rowid_filter_check(void *h_arg) { handler *h= (handler*) h_arg; TABLE *tab= h->get_table(); + + /* + Check for out-of-range and killed conditions only if we haven't done it + already in the pushed index condition check + */ + if (!h->pushed_idx_cond) + { + THD *thd= h->table->in_use; + enum thd_kill_levels abort_at= h->has_transactions() ? + THD_ABORT_SOFTLY : THD_ABORT_ASAP; + if (thd_kill_level(thd) > abort_at) + return CHECK_ABORTED_BY_USER; + + if (h->end_range && h->compare_key2(h->end_range) > 0) + return CHECK_OUT_OF_RANGE; + } + h->position(tab->record[0]); - return h->pushed_rowid_filter->check((char *) h->ref); + return h->pushed_rowid_filter->check((char*)h->ref)? CHECK_POS: CHECK_NEG; } diff --git a/sql/handler.h b/sql/handler.h index afad986c883..0eff7bd930d 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -2956,9 +2956,9 @@ public: {} }; -extern "C" enum icp_result handler_index_cond_check(void* h_arg); +extern "C" check_result_t handler_index_cond_check(void* h_arg); -extern "C" int handler_rowid_filter_check(void* h_arg); +extern "C" check_result_t handler_rowid_filter_check(void* h_arg); extern "C" int handler_rowid_filter_is_active(void* h_arg); uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map); @@ -4975,7 +4975,8 @@ public: virtual void set_lock_type(enum thr_lock_type lock); - friend enum icp_result handler_index_cond_check(void* h_arg); + friend check_result_t handler_index_cond_check(void* h_arg); + friend check_result_t handler_rowid_filter_check(void *h_arg); /** Find unique record by index or unique constrain diff --git a/sql/rowid_filter.cc b/sql/rowid_filter.cc index 1d9363693cb..d8d0890e1f9 100644 --- a/sql/rowid_filter.cc +++ b/sql/rowid_filter.cc @@ -469,6 +469,14 @@ TABLE::best_range_rowid_filter_for_partial_join(uint access_key_no, covering_keys.is_set(access_key_no)) return 0; + // Disallow use of range filter if the key contains partially-covered + // columns. + for (uint i= 0; i < key_info[access_key_no].usable_key_parts; i++) + { + if (key_info[access_key_no].key_part[i].field->type() == MYSQL_TYPE_BLOB) + return 0; + } + /* Currently we do not support usage of range filters if the table is accessed by the clustered primary key. It does not make sense diff --git a/sql/session_tracker.cc b/sql/session_tracker.cc index c12653bef07..a0919d825bf 100644 --- a/sql/session_tracker.cc +++ b/sql/session_tracker.cc @@ -1269,7 +1269,7 @@ void Session_tracker::store(THD *thd, String *buf) if ((size= net_length_size(length)) != 1) { - if (buf->reserve(size - 1, EXTRA_ALLOC)) + if (buf->reserve(size - 1, 0)) { buf->length(start); // it is safer to have 0-length block in case of error return; @@ -1279,6 +1279,7 @@ void Session_tracker::store(THD *thd, String *buf) The 'buf->reserve()' can change the buf->ptr() so we cannot calculate the 'data' earlier. */ + buf->length(buf->length() + (size - 1)); data= (uchar *)(buf->ptr() + start); memmove(data + (size - 1), data, length); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 08dd03dc7f6..b5064fe9fd9 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4756,10 +4756,19 @@ bool Lock_tables_prelocking_strategy:: handle_table(THD *thd, Query_tables_list *prelocking_ctx, TABLE_LIST *table_list, bool *need_prelocking) { + TABLE_LIST **last= prelocking_ctx->query_tables_last; + if (DML_prelocking_strategy::handle_table(thd, prelocking_ctx, table_list, need_prelocking)) return TRUE; + /* + normally we don't need to open FK-prelocked tables for RESTRICT, + MDL is enough. But under LOCK TABLES we have to open everything + */ + for (TABLE_LIST *tl= *last; tl; tl= tl->next_global) + tl->open_strategy= TABLE_LIST::OPEN_NORMAL; + /* We rely on a caller to check that table is going to be changed. */ DBUG_ASSERT(table_list->lock_type >= TL_WRITE_ALLOW_WRITE); diff --git a/sql/table.h b/sql/table.h index d93f466077f..b1c23337cce 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2078,6 +2078,9 @@ struct TABLE_LIST OT_BASE_ONLY); belong_to_view= belong_to_view_arg; trg_event_map= trg_event_map_arg; + /* MDL is enough for read-only FK checks, we don't need the table */ + if (prelocking_type == PRELOCK_FK && lock_type < TL_WRITE_ALLOW_WRITE) + open_strategy= OPEN_STUB; **last_ptr= this; prev_global= *last_ptr; |