Skip to content

Commit

Permalink
Bug #33037007: PRELIMINARY FIXES FOR WL #14488 [return AccessPath, no…
Browse files Browse the repository at this point in the history
…close]

Make the range optimizer return AccessPaths instead of TABLE_READ_PLAN.
This is the first step of getting rid of TABLE_READ_PLAN and moving
everything into AccessPath; currently, it's just a very thin shell:

 1. TRPs are still used internally, and AccessPath is created
    at the very end.
 2. Child TRPs are still child TRPs (ie., there are no child
    AccessPaths).
 3. All returned AccessPaths are still of the type INDEX_RANGE_SCAN,
    wrapping a TRP.
 4. Some callers still reach directly into the TRP, assuming #3.

Most callers (save for the aforemented #4) use a set of simple wrapper
functions to access TRP-derived properties from AccessPaths; as we
continue the transformation, this is the main place we'll change the
interaction (ie., most of the calling code will remain unchanged).

Change-Id: I3d9dc9e33c53d1e5124ea9c47b7d6d9270cd1906
  • Loading branch information
Steinar H. Gunderson committed Sep 1, 2021
1 parent fea34e8 commit ff4b554
Show file tree
Hide file tree
Showing 18 changed files with 469 additions and 296 deletions.
36 changes: 17 additions & 19 deletions sql/abstract_query_plan.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@
#include "my_inttypes.h"
#include "sql/handler.h"
#include "sql/item.h"
#include "sql/join_optimizer/access_path.h"
#include "sql/key.h"
#include "sql/range_optimizer/table_read_plan.h"
#include "sql/range_optimizer/trp_helpers.h"
#include "sql/sql_const.h"
#include "sql/sql_executor.h" // QEP_TAB
#include "sql/sql_opt_exec_shared.h"
Expand All @@ -52,7 +54,7 @@ Join_plan::Join_plan(const JOIN *join)
be written to handle it.
*/
assert(!m_qep_tabs[0].dynamic_range() || (m_qep_tabs[0].type() == JT_ALL) ||
(m_qep_tabs[0].trp() == nullptr));
(m_qep_tabs[0].range_scan() == nullptr));

// Discard trailing allocated, but unused, tables.
while (m_qep_tabs[m_access_count - 1].position() == nullptr) {
Expand Down Expand Up @@ -162,10 +164,12 @@ void Table_access::dbug_print() const {

DBUG_PRINT("info", ("dynamic_range:%d", (int)get_qep_tab()->dynamic_range()));
DBUG_PRINT("info", ("index:%d", get_qep_tab()->index()));
DBUG_PRINT("info", ("trp:%p", get_qep_tab()->trp()));
if (get_qep_tab()->trp()) {
DBUG_PRINT("info",
("trp->get_type():%d", get_qep_tab()->trp()->get_type()));
DBUG_PRINT("info", ("trp:%p", get_qep_tab()->range_scan()));
if (get_qep_tab()->range_scan()) {
DBUG_PRINT(
"info",
("trp->get_type():%d",
get_qep_tab()->range_scan()->index_range_scan().trp->get_type()));
}
}

Expand Down Expand Up @@ -253,8 +257,8 @@ void Table_access::compute_type_and_index() const {
m_access_type = AT_UNDECIDED;
m_index_no = -1;
} else {
if (qep_tab->trp() != nullptr) {
TABLE_READ_PLAN *trp = qep_tab->trp();
if (qep_tab->range_scan() != nullptr) {
AccessPath *trp = qep_tab->range_scan();

/** QUICK_SELECT results in execution of MRR (Multi Range Read).
* Depending on each range, it may require execution of
Expand All @@ -266,33 +270,27 @@ void Table_access::compute_type_and_index() const {
**/

const KEY *key_info = qep_tab->table()->s->key_info;
DBUG_EXECUTE("info", trp->dbug_dump(0, true););

// Temporary assert as we are still investigation the relation between
// 'trp->index == MAX_KEY' and the different quick_types
assert((trp->index == MAX_KEY) ==
(trp->get_type() == QS_TYPE_INDEX_MERGE ||
trp->get_type() == QS_TYPE_ROR_INTERSECT ||
trp->get_type() == QS_TYPE_ROR_UNION));
DBUG_EXECUTE("info",
trp->index_range_scan().trp->dbug_dump(0, true););

// JT_INDEX_MERGE: We have a set of qualifying PKs as root of pushed
// joins
if (trp->index == MAX_KEY) {
if (used_index(trp) == MAX_KEY) {
m_index_no = qep_tab->table()->s->primary_key;
m_access_type =
AT_MULTI_PRIMARY_KEY; // Multiple PKs are produced by merge
}

// Else JT_RANGE: May be both exact PK and/or index scans when sorted
// index available
else if (trp->index == qep_tab->table()->s->primary_key) {
m_index_no = trp->index;
else if (used_index(trp) == qep_tab->table()->s->primary_key) {
m_index_no = used_index(trp);
if (key_info[m_index_no].algorithm == HA_KEY_ALG_HASH)
m_access_type = AT_MULTI_PRIMARY_KEY; // MRR w/ multiple PK's
else
m_access_type = AT_MULTI_MIXED; // MRR w/ both range and PKs
} else {
m_index_no = trp->index;
m_index_no = used_index(trp);
if (key_info[m_index_no].algorithm == HA_KEY_ALG_HASH)
m_access_type =
AT_MULTI_UNIQUE_KEY; // MRR with multiple unique keys
Expand Down
84 changes: 46 additions & 38 deletions sql/opt_explain.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
#include "sql/item.h"
#include "sql/item_func.h"
#include "sql/item_subselect.h"
#include "sql/join_optimizer/access_path.h"
#include "sql/join_optimizer/bit_utils.h"
#include "sql/join_optimizer/explain_access_path.h"
#include "sql/join_optimizer/join_optimizer.h"
Expand All @@ -81,6 +82,7 @@
#include "sql/range_optimizer/rowid_ordered_retrieval.h"
#include "sql/range_optimizer/rowid_ordered_retrieval_plan.h"
#include "sql/range_optimizer/table_read_plan.h"
#include "sql/range_optimizer/trp_helpers.h"
#include "sql/row_iterator.h"
#include "sql/sql_bitmap.h"
#include "sql/sql_class.h"
Expand Down Expand Up @@ -395,7 +397,7 @@ class Explain_table_base : public Explain {

const TABLE *table{nullptr};
join_type type{JT_UNKNOWN};
TABLE_READ_PLAN *trp{nullptr};
AccessPath *range_scan_path{nullptr};
Item *condition{nullptr};
bool dynamic_range{false};
TABLE_LIST *table_ref{nullptr};
Expand All @@ -416,7 +418,7 @@ class Explain_table_base : public Explain {
bool explain_possible_keys() override;

bool explain_key_parts(int key, uint key_parts);
bool explain_key_and_len_quick(TABLE_READ_PLAN *trp);
bool explain_key_and_len_quick(AccessPath *trp);
bool explain_key_and_len_index(int key);
bool explain_key_and_len_index(int key, uint key_length, uint key_parts);
bool explain_extra_common(int quick_type, uint keyno);
Expand Down Expand Up @@ -501,7 +503,7 @@ class Explain_table : public Explain_table_base {
public:
Explain_table(THD *const explain_thd_arg, const THD *query_thd_arg,
Query_block *query_block_arg, TABLE *const table_arg,
enum join_type type_arg, TABLE_READ_PLAN *trp_arg,
enum join_type type_arg, AccessPath *range_scan_arg,
Item *condition_arg, uint key_arg, ha_rows limit_arg,
bool need_tmp_table_arg, bool need_sort_arg,
enum_mod_type mod_type_arg, bool used_key_is_modified_arg,
Expand All @@ -516,7 +518,7 @@ class Explain_table : public Explain_table_base {
used_key_is_modified(used_key_is_modified_arg),
message(msg) {
type = type_arg;
trp = trp_arg;
range_scan_path = range_scan_arg;
condition = condition_arg;
usable_keys = table->possible_quick_keys;
if (can_walk_clauses())
Expand Down Expand Up @@ -887,14 +889,15 @@ bool Explain_table_base::explain_key_parts(int key, uint key_parts) {
return false;
}

bool Explain_table_base::explain_key_and_len_quick(TABLE_READ_PLAN *trp) {
bool Explain_table_base::explain_key_and_len_quick(AccessPath *path) {
bool ret = false;
StringBuffer<512> str_key(cs);
StringBuffer<512> str_key_len(cs);

if (trp->index != MAX_KEY)
ret = explain_key_parts(trp->index, trp->used_key_parts);
trp->add_keys_and_lengths(&str_key, &str_key_len);
if (used_index(path) != MAX_KEY)
ret = explain_key_parts(used_index(range_scan_path),
path->index_range_scan().trp->used_key_parts);
path->index_range_scan().trp->add_keys_and_lengths(&str_key, &str_key_len);
return (ret || fmt->entry()->col_key.set(str_key) ||
fmt->entry()->col_key_len.set(str_key_len));
}
Expand Down Expand Up @@ -965,7 +968,7 @@ bool Explain_table_base::explain_extra_common(int quick_type, uint keyno) {
case QS_TYPE_ROR_INTERSECT:
case QS_TYPE_INDEX_MERGE: {
StringBuffer<32> buff(cs);
trp->add_info_string(&buff);
range_scan_path->index_range_scan().trp->add_info_string(&buff);
if (fmt->is_hierarchical()) {
/*
We are replacing existing col_key value with a quickselect info,
Expand Down Expand Up @@ -1011,15 +1014,18 @@ bool Explain_table_base::explain_extra_common(int quick_type, uint keyno) {
pushed_cond->print(explain_thd, &buff, cond_print_flags);
if (push_extra(ET_USING_PUSHED_CONDITION, buff)) return true;
}
if (((quick_type >= 0 && trp->reverse_sorted()) || reversed_access) &&
if (((quick_type >= 0 && is_reverse_sorted_range(range_scan_path)) ||
reversed_access) &&
push_extra(ET_BACKWARD_SCAN))
return true;
}
if (table->reginfo.not_exists_optimize && push_extra(ET_NOT_EXISTS))
return true;

if (quick_type == QS_TYPE_RANGE) {
uint mrr_flags = down_cast<TRP_RANGE *>(trp)->get_mrr_flags();
uint mrr_flags =
down_cast<TRP_RANGE *>(range_scan_path->index_range_scan().trp)
->get_mrr_flags();

/*
During normal execution of a query, multi_range_read_init() is
Expand Down Expand Up @@ -1303,7 +1309,7 @@ bool Explain_join::shallow_explain() {
bool Explain_join::explain_qep_tab(size_t tabnum) {
tab = join->qep_tab + tabnum;
type = tab->type();
trp = tab->trp();
range_scan_path = tab->range_scan();
condition = tab->condition_optim();
dynamic_range = tab->dynamic_range();
skip_records_in_range = tab->skip_records_in_range();
Expand All @@ -1316,8 +1322,8 @@ bool Explain_join::explain_qep_tab(size_t tabnum) {
quick_type = -1;

if (tab->type() == JT_RANGE || tab->type() == JT_INDEX_MERGE) {
assert(trp);
quick_type = trp->get_type();
assert(range_scan_path);
quick_type = get_range_scan_type(range_scan_path);
}

if (tab->starts_weedout()) fmt->begin_context(CTX_DUPLICATES_WEEDOUT);
Expand Down Expand Up @@ -1447,8 +1453,8 @@ bool Explain_join::explain_key_and_len() {
else if (type == JT_INDEX_SCAN || type == JT_FT)
return explain_key_and_len_index(tab->index());
else if (type == JT_RANGE || type == JT_INDEX_MERGE ||
((type == JT_REF || type == JT_REF_OR_NULL) && trp))
return explain_key_and_len_quick(trp);
((type == JT_REF || type == JT_REF_OR_NULL) && range_scan_path))
return explain_key_and_len_quick(range_scan_path);
return false;
}

Expand Down Expand Up @@ -1513,14 +1519,15 @@ bool Explain_join::explain_extra() {
if (tab->ref().key_parts)
keyno = tab->ref().key;
else if (tab->type() == JT_RANGE || tab->type() == JT_INDEX_MERGE)
keyno = trp->index;
keyno = used_index(range_scan_path);

if (explain_extra_common(quick_type, keyno)) return true;

if (((tab->type() == JT_INDEX_SCAN || tab->type() == JT_CONST) &&
table->covering_keys.is_set(tab->index())) ||
(quick_type == QS_TYPE_ROR_INTERSECT &&
down_cast<TRP_ROR_INTERSECT *>(trp)->get_is_covering()) ||
down_cast<TRP_ROR_INTERSECT *>(range_scan_path->index_range_scan().trp)
->get_is_covering()) ||
/*
Notice that table->key_read can change on the fly (grep
for set_keyread); so EXPLAIN CONNECTION reads a changing variable,
Expand All @@ -1529,7 +1536,8 @@ bool Explain_join::explain_extra() {
*/
table->key_read || tab->keyread_optim()) {
if (quick_type == QS_TYPE_GROUP_MIN_MAX) {
TRP_GROUP_MIN_MAX *qgs = down_cast<TRP_GROUP_MIN_MAX *>(trp);
TRP_GROUP_MIN_MAX *qgs = down_cast<TRP_GROUP_MIN_MAX *>(
range_scan_path->index_range_scan().trp);
StringBuffer<64> buff(cs);
if (qgs->get_is_index_scan()) buff.append(STRING_WITH_LEN("scanning"));
if (push_extra(ET_USING_INDEX_FOR_GROUP_BY, buff)) return true;
Expand Down Expand Up @@ -1688,8 +1696,8 @@ bool Explain_table::explain_table_name() {

bool Explain_table::explain_join_type() {
join_type jt;
if (trp)
jt = calc_join_type(trp->get_type());
if (range_scan_path)
jt = calc_join_type(range_scan_path);
else if (key != MAX_KEY)
jt = JT_INDEX_SCAN;
else
Expand All @@ -1700,8 +1708,8 @@ bool Explain_table::explain_join_type() {
}

bool Explain_table::explain_ref() {
if (trp) {
int key_parts = trp->used_key_parts;
if (range_scan_path) {
int key_parts = get_used_key_parts(range_scan_path);
while (key_parts--) {
fmt->entry()->col_ref.push_back("const");
}
Expand All @@ -1710,8 +1718,8 @@ bool Explain_table::explain_ref() {
}

bool Explain_table::explain_key_and_len() {
if (trp)
return explain_key_and_len_quick(trp);
if (range_scan_path)
return explain_key_and_len_quick(range_scan_path);
else if (key != MAX_KEY)
return explain_key_and_len_index(key);
return false;
Expand Down Expand Up @@ -1741,9 +1749,9 @@ bool Explain_table::explain_extra() {

uint keyno;
int quick_type;
if (trp) {
keyno = trp->index;
quick_type = trp->get_type();
if (range_scan_path) {
keyno = used_index(range_scan_path);
quick_type = get_range_scan_type(range_scan_path);
} else {
keyno = key;
quick_type = -1;
Expand Down Expand Up @@ -1889,13 +1897,13 @@ bool explain_single_table_modification(THD *explain_thd, const THD *query_thd,
check_acl_for_explain(query_thd->query_plan.get_lex()->query_tables))
ret = true;
else
ret =
Explain_table(explain_thd, query_thd, select, plan->table, plan->type,
plan->trp, plan->condition, plan->key, plan->limit,
plan->need_tmp_table, plan->need_sort, plan->mod_type,
plan->used_key_is_modified, plan->message)
.send() ||
explain_thd->is_error();
ret = Explain_table(explain_thd, query_thd, select, plan->table,
plan->type, plan->range_scan, plan->condition,
plan->key, plan->limit, plan->need_tmp_table,
plan->need_sort, plan->mod_type,
plan->used_key_is_modified, plan->message)
.send() ||
explain_thd->is_error();
}
if (ret)
result.abort_result_set(explain_thd);
Expand Down Expand Up @@ -2471,7 +2479,7 @@ void Modification_plan::register_in_thd() {
@param mt modification type - MT_INSERT/MT_UPDATE/etc
@param table_arg Table to modify
@param type_arg Access type (JT_*) for this table
@param trp_arg Range index scan used, if any
@param range_scan_arg Range index scan used, if any
@param condition_arg Condition applied, if any
@param key_arg MAX_KEY or and index number of the key that was chosen
to access table data.
Expand All @@ -2487,14 +2495,14 @@ void Modification_plan::register_in_thd() {

Modification_plan::Modification_plan(
THD *thd_arg, enum_mod_type mt, TABLE *table_arg, enum join_type type_arg,
TABLE_READ_PLAN *trp_arg, Item *condition_arg, uint key_arg,
AccessPath *range_scan_arg, Item *condition_arg, uint key_arg,
ha_rows limit_arg, bool need_tmp_table_arg, bool need_sort_arg,
bool used_key_is_modified_arg, ha_rows rows)
: thd(thd_arg),
mod_type(mt),
table(table_arg),
type(type_arg),
trp(trp_arg),
range_scan(range_scan_arg),
condition(condition_arg),
key(key_arg),
limit(limit_arg),
Expand Down
5 changes: 2 additions & 3 deletions sql/opt_explain.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ struct AccessPath;
struct TABLE;
template <class T>
class List;
class TABLE_READ_PLAN;

extern const char *join_type_str[];

Expand All @@ -87,7 +86,7 @@ class Modification_plan {
TABLE *table; ///< Table to modify

enum join_type type = JT_UNKNOWN;
TABLE_READ_PLAN *trp{nullptr};
AccessPath *range_scan{nullptr};
Item *condition{nullptr};
uint key; ///< Key to use
ha_rows limit; ///< Limit
Expand All @@ -99,7 +98,7 @@ class Modification_plan {
ha_rows examined_rows; ///< # of rows expected to be examined in the table

Modification_plan(THD *thd_arg, enum_mod_type mt, TABLE *table_arg,
enum join_type type_arg, TABLE_READ_PLAN *quick_arg,
enum join_type type_arg, AccessPath *quick_arg,
Item *condition_arg, uint key_arg, ha_rows limit_arg,
bool need_tmp_table_arg, bool need_sort_arg,
bool used_key_is_modified_arg, ha_rows rows);
Expand Down
Loading

0 comments on commit ff4b554

Please sign in to comment.