summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2022-12-28 16:42:27 +0200
committerMonty <monty@mariadb.org>2023-02-10 12:58:50 +0200
commit4be0bfad98c41acb6a2a7d5722051081ab5d239a (patch)
tree748b69795be7dbcbbbd9794229b7fd4fab9272f0
parent9a4110aa5799d63faced5f986fab9035785a9310 (diff)
downloadmariadb-git-4be0bfad98c41acb6a2a7d5722051081ab5d239a.tar.gz
Simplified code in generate_derived_keys() and when using pos_in_tables
Added comments that not used keys of derivied tables will be deleted. Added some comments about checking if pos_in_table_list is 0. Other things: - Added a marker (DBTYPE_IN_PREDICATE) in TABLE_LIST->derived_type to indicate that the table was generated from IN (list). This is useful for debugging and can later be used by explain if needed. - Removed a not needed test of table->pos_in_table_list as it should always be valid at this point in time.
-rw-r--r--sql/sql_select.cc44
-rw-r--r--sql/sql_show.cc8
-rw-r--r--sql/sql_tvc.cc4
-rw-r--r--sql/table.h3
4 files changed, 41 insertions, 18 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index df5eb3afd38..520780080ef 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -4266,7 +4266,6 @@ JOIN::add_sorting_to_table(JOIN_TAB *tab, ORDER *order)
TABLE *table= tab->table;
if ((tab == join_tab + const_tables) &&
- table->pos_in_table_list &&
table->pos_in_table_list->is_sjm_scan_table())
{
tab->filesort->set_all_read_bits= TRUE;
@@ -7391,6 +7390,10 @@ static void remember_if_eq_ref_key(JOIN *join, KEYUSE *use)
Special treatment for ft-keys.
Update join->eq_ref_tables with a bitmap of all tables that can possible
have a EQ_REF key.
+
+ Note that the keys are generated to be used by best_access_path() during
+ the optimization stage. Unused keys will later be deleted by
+ JOIN::drop_unused_derived_keys().
*/
bool sort_and_filter_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse,
@@ -7440,7 +7443,9 @@ bool sort_and_filter_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse,
}
else
{
- /* Key changed, check if previous key was a primary/unique key lookup */
+ /*
+ Key changed, check if previous key was a primary/unique key lookup
+ */
if (prev != &key_end && !found_unprefixed_key_part)
remember_if_eq_ref_key(join, prev);
found_unprefixed_key_part= 0;
@@ -13794,36 +13799,45 @@ bool generate_derived_keys_for_table(KEYUSE *keyuse, uint count, uint keys)
static
bool generate_derived_keys(DYNAMIC_ARRAY *keyuse_array)
{
- KEYUSE *keyuse= dynamic_element(keyuse_array, 0, KEYUSE*);
+ KEYUSE *keyuse, *end_keyuse;
size_t elements= keyuse_array->elements;
TABLE *prev_table= 0;
- for (size_t i= 0; i < elements; i++, keyuse++)
+
+ DBUG_ASSERT(elements > 0);
+ /* The last element is an end marker */
+ DBUG_ASSERT(dynamic_element(keyuse_array, elements-1,
+ KEYUSE*)[0].table == 0);
+
+ for (keyuse= dynamic_element(keyuse_array, 0, KEYUSE*),
+ end_keyuse= keyuse + elements - 1;
+ keyuse < end_keyuse;
+ keyuse++)
{
- if (!keyuse->table)
- break;
+ DBUG_ASSERT(keyuse->table);
+
KEYUSE *first_table_keyuse= NULL;
table_map last_used_tables= 0;
uint count= 0;
uint keys= 0;
TABLE_LIST *derived= NULL;
+
if (keyuse->table != prev_table)
derived= keyuse->table->pos_in_table_list;
- while (derived && derived->is_materialized_derived())
+
+ if (!derived->is_materialized_derived())
+ continue;
+
+ for (;;)
{
if (keyuse->table != prev_table)
{
prev_table= keyuse->table;
while (keyuse->table == prev_table && keyuse->key != MAX_KEY)
- {
keyuse++;
- i++;
- }
if (keyuse->table != prev_table)
{
keyuse--;
- i--;
- derived= NULL;
- continue;
+ break;
}
first_table_keyuse= keyuse;
last_used_tables= keyuse->used_tables;
@@ -13837,14 +13851,12 @@ bool generate_derived_keys(DYNAMIC_ARRAY *keyuse_array)
}
count++;
keyuse++;
- i++;
if (keyuse->table != prev_table)
{
if (generate_derived_keys_for_table(first_table_keyuse, count, ++keys))
return TRUE;
keyuse--;
- i--;
- derived= NULL;
+ break;
}
}
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index a716cae6955..05d0f601434 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -8899,6 +8899,10 @@ bool optimize_schema_tables_reads(JOIN *join)
tab;
tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
+ /*
+ The following is true for the temporary table that will hold the
+ final result.
+ */
if (!tab->table || !tab->table->pos_in_table_list)
continue;
@@ -8970,6 +8974,10 @@ bool get_schema_tables_result(JOIN *join,
tab;
tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
+ /*
+ The following is true for the temporary table that will hold the
+ final result.
+ */
if (!tab->table || !tab->table->pos_in_table_list)
break;
diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc
index bb5914a78a6..b4a7a0d5091 100644
--- a/sql/sql_tvc.cc
+++ b/sql/sql_tvc.cc
@@ -1047,7 +1047,9 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd,
sq_select->add_where_field(derived_unit->first_select());
sq_select->context.table_list= sq_select->table_list.first;
sq_select->context.first_name_resolution_table= sq_select->table_list.first;
- sq_select->table_list.first->derived_type= DTYPE_TABLE | DTYPE_MATERIALIZE;
+ sq_select->table_list.first->derived_type= (DTYPE_TABLE |
+ DTYPE_MATERIALIZE |
+ DTYPE_IN_PREDICATE);
lex->derived_tables|= DERIVED_SUBQUERY;
sq_select->where= 0;
diff --git a/sql/table.h b/sql/table.h
index c27c653f479..add1871e899 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1993,7 +1993,8 @@ class IS_table_read_plan;
#define DTYPE_MERGE 4U
#define DTYPE_MATERIALIZE 8U
#define DTYPE_MULTITABLE 16U
-#define DTYPE_MASK (DTYPE_VIEW|DTYPE_TABLE|DTYPE_MULTITABLE)
+#define DTYPE_IN_PREDICATE 32U
+#define DTYPE_MASK (DTYPE_VIEW|DTYPE_TABLE|DTYPE_MULTITABLE|DTYPE_IN_PREDICATE)
/*
Phases of derived tables/views handling, see sql_derived.cc