summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2020-05-09 20:43:36 +0200
committerSergei Golubchik <serg@mariadb.org>2020-05-09 20:43:36 +0200
commit13038e4705ed55e24362dfad977a1ee454cfebfd (patch)
treeac3d37fe69e802dec8008748b86cc901f116eead /sql
parent72c7b4eb4cc86ca2f6bdb9e105b67d39df018a40 (diff)
parentf5844e7c4bc693783f088a5fc9c399b786ddc8c1 (diff)
downloadmariadb-git-13038e4705ed55e24362dfad977a1ee454cfebfd.tar.gz
Merge branch '10.4' into 10.5
Diffstat (limited to 'sql')
-rw-r--r--sql/handler.cc34
-rw-r--r--sql/handler.h7
-rw-r--r--sql/rowid_filter.cc8
-rw-r--r--sql/session_tracker.cc3
-rw-r--r--sql/sql_base.cc9
-rw-r--r--sql/table.h3
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;