MySQL  8.0.18
Source Code Documentation
sql_opt_exec_shared.h File Reference

Common types of the Optimizer, used by optimization and execution. More...

#include "item.h"
#include "my_base.h"
#include "my_dbug.h"

Go to the source code of this file.

Classes

struct  TABLE_REF
 
class  QEP_shared
 Holds members common to JOIN_TAB and QEP_TAB. More...
 
class  QEP_shared_owner
 Owner of a QEP_shared; parent of JOIN_TAB and QEP_TAB. More...
 

Macros

#define NO_PLAN_IDX   (-2)
 undefined index More...
 
#define PRE_FIRST_PLAN_IDX   (-1)
 right before the first (first's index is 0) More...
 

Typedefs

typedef int8 plan_idx
 This represents the index of a JOIN_TAB/QEP_TAB in an array. More...
 

Enumerations

enum  join_type {
  JT_UNKNOWN, JT_SYSTEM, JT_CONST, JT_EQ_REF,
  JT_REF, JT_ALL, JT_RANGE, JT_INDEX_SCAN,
  JT_FT, JT_REF_OR_NULL, JT_INDEX_MERGE
}
 
enum  {
  REF_SLICE_ACTIVE = 0, REF_SLICE_TMP1, REF_SLICE_TMP2, REF_SLICE_ORDERED_GROUP_BY,
  REF_SLICE_SAVED_BASE, REF_SLICE_WIN_1
}
 Symbolic slice numbers into JOIN's arrays ref_items, tmp_fields and tmp_all_fields. More...
 

Detailed Description

Common types of the Optimizer, used by optimization and execution.

Macro Definition Documentation

◆ NO_PLAN_IDX

#define NO_PLAN_IDX   (-2)

undefined index

◆ PRE_FIRST_PLAN_IDX

#define PRE_FIRST_PLAN_IDX   (-1)

right before the first (first's index is 0)

Typedef Documentation

◆ plan_idx

typedef int8 plan_idx

This represents the index of a JOIN_TAB/QEP_TAB in an array.

"plan_idx": "Plan Table Index". It is signed, because:

  • firstmatch_return may be PRE_FIRST_PLAN_IDX (it can happen that the first table of the plan uses FirstMatch: SELECT ... WHERE literal IN (SELECT ...)).
  • it must hold the invalid value NO_PLAN_IDX (which means "no JOIN_TAB/QEP_TAB", equivalent of NULL pointer); this invalid value must itself be different from PRE_FIRST_PLAN_IDX, to distinguish "FirstMatch to before-first-table" (firstmatch_return==PRE_FIRST_PLAN_IDX) from "No FirstMatch" (firstmatch_return==NO_PLAN_IDX).

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Symbolic slice numbers into JOIN's arrays ref_items, tmp_fields and tmp_all_fields.

See also the comments on JOIN::ref_items.

Enumerator
REF_SLICE_ACTIVE 

The slice which is used during evaluation of expressions; Item_ref::ref points there.

This is the only slice that is not allocated on the heap; it always points to select_lex->base_ref_items.

If we have a simple query (no temporary tables or GROUP BY needed), this slice always contains the base slice, i.e., the actual Items used in the original query.

However, if we have temporary tables, there are cases where we need to swap out those Items, because they refer to Fields that are no longer in use. As a simple case, consider

SELECT REVERSE(t1), COUNT(*) FROM t1 GROUP BY REVERSE(t1);

Assuming no index on t1, this will require creating a temporary table consisting only of REVERSE(t1), and then sorting it before grouping. During execution of the query creating the temporary table, we will have an Item_func_reverse pointing to a Field for t1, and the result of this will be stored in the temporary table "tmp". However, when reading from "tmp", it would be wrong to use that Item_func_reverse, as the Field no longer exists. Thus, we create a slice (in REF_SLICE_TMP1) with new Item pointers, where Item_func_reverse is replaced by an Item_field that reads from the right field in the temporary table. Similar logic applies for windowing functions etc.; see below.

In such cases, the pointers in this slice are overwritten (using memcpy) by e.g. REF_SLICE_TMP1 for as long as we read from the temporary table. Switch_ref_item_slice provides an encapsulation of the overwriting, and the optimizer stores a copy of the original Item pointers in the REF_SLICE_SAVED_BASE slice so that it is possible to copy them back when we are done.

REF_SLICE_TMP1 

The slice with pointers to columns of 1st group-order-distinct tmp table.

REF_SLICE_TMP2 

The slice with pointers to columns of 2nd group-order-distinct tmp table.

REF_SLICE_ORDERED_GROUP_BY 

Stores the unfinished aggregated row when doing GROUP BY on an ordered table.

For certain queries with GROUP BY (e.g., when using an index), rows arrive already sorted in the right order for grouping. In that case, we do not need nor use a temporary table, but can just group values as we go. However, we do not necessarily know when a group ends – a group implicitly ends when we see that the group index values have changed, and by that time, it's too late to output them in the aggregated row (the Fields already point to the new row, so the data is lost).

Thus, we need to store the values for the current group somewhere. We use a set of Items, which together represent a one-row pseudo-tmp-table holding the current group. These items are created by setup_copy_fields().

When we have finished reading a row from the last pre-grouping table, we process it either with end_send_group() or end_send():

end_send_group(): Compare the new row with the current group.
If it belongs to the current group, we update the aggregation functions
and move on. If not, we output the aggregated row and overwrite the
contents of this slice with the new group.

end_send(): Used when we know there's exactly one row for each group
(e.g., during a loose index scan). In this case, we can skip the
comparison and just output the group directly; however, we still need
the temporary table to avoid evaluating Items more than once (see the
next paragraph).

Both functions build the group by copying values of items from the previous stages into a pseudo-table, e.g.

SELECT a, RAND() AS r FROM t GROUP BY a HAVING r=1;

copies "a" from "t" and stores it into the pseudo-table (this slice), evaluates rand() and stores it, then finally evaluates "r=1" based on the stored value (so that "r" in the SELECT list and "r" in "r=1" match).

Groups from this slice are always directly sent to the query's result, and never buffered to any further temporary table.

REF_SLICE_SAVED_BASE 

The slice with pointers to columns of table(s), ie., the actual Items.

Only used for queries involving temporary tables or the likes; for simple queries, they always live in REF_SLICE_ACTIVE, so we don't need a copy here. See REF_SLICE_ACTIVE for more discussion.

REF_SLICE_WIN_1 

The slice with pointers to columns of 1st tmp table of windowing.

◆ join_type

enum join_type
Enumerator
JT_UNKNOWN 
JT_SYSTEM 
JT_CONST 
JT_EQ_REF 
JT_REF 
JT_ALL 
JT_RANGE 
JT_INDEX_SCAN 
JT_FT 
JT_REF_OR_NULL 
JT_INDEX_MERGE