MySQL 8.4.3
Source Code Documentation
|
A struct containing a join hypergraph of a single query block, encapsulating the constraints given by the relational expressions (e.g. More...
#include <make_join_hypergraph.h>
Classes | |
class | Node |
Public Member Functions | |
JoinHypergraph (MEM_ROOT *mem_root, const Query_block *query_block) | |
const Query_block * | query_block () const |
Returns a pointer to the query block that is being planned. More... | |
const JOIN * | join () const |
Returns a pointer to the JOIN object of the query block being planned. More... | |
int | FindSargableJoinPredicate (const Item *predicate) const |
void | AddSargableJoinPredicate (const Item *predicate, int position) |
Public Attributes | |
hypergraph::Hypergraph | graph |
SecondaryEngineCostingFlags | secondary_engine_costing_flags {} |
Flags set when AccessPaths are proposed to secondary engines for costing. More... | |
std::array< int, MAX_TABLES > | table_num_to_node_num |
Mem_root_array< Node > | nodes |
Mem_root_array< JoinPredicate > | edges |
Mem_root_array< Predicate > | predicates |
unsigned | num_where_predicates = 0 |
OverflowBitset | materializable_predicates {0} |
bool | has_reordered_left_joins = false |
Whether, at any point, we could rewrite (t1 LEFT JOIN t2) LEFT JOIN t3 to t1 LEFT JOIN (t2 LEFT JOIN t3) or vice versa. More... | |
table_map | tables_inner_to_outer_or_anti = 0 |
The set of tables that are on the inner side of some outer join or antijoin. More... | |
Private Attributes | |
mem_root_unordered_map< const Item *, int > | m_sargable_join_predicates |
const Query_block * | m_query_block |
A pointer to the query block being planned. More... | |
A struct containing a join hypergraph of a single query block, encapsulating the constraints given by the relational expressions (e.g.
inner joins are more freely reorderable than outer joins).
Since the Hypergraph class does not carry any payloads for nodes and edges, and we need to associate e.g. TABLE pointers with each node, we store our extra data in “nodes” and “edges”, indexed the same way the hypergraph is indexed.
|
inline |
|
inline |
|
inline |
const JOIN * JoinHypergraph::join | ( | ) | const |
Returns a pointer to the JOIN object of the query block being planned.
|
inline |
Returns a pointer to the query block that is being planned.
Mem_root_array<JoinPredicate> JoinHypergraph::edges |
hypergraph::Hypergraph JoinHypergraph::graph |
bool JoinHypergraph::has_reordered_left_joins = false |
Whether, at any point, we could rewrite (t1 LEFT JOIN t2) LEFT JOIN t3 to t1 LEFT JOIN (t2 LEFT JOIN t3) or vice versa.
We record this purely to note that we have a known bug/inconsistency in row count estimation in this case. Bug #33550360 has a test case, but to sum up: Assume t1 and t3 has 25 rows, but t2 has zero rows, and selectivities are 0.1. As long as we clamp the row count in FindOutputRowsForJoin(), and do not modify these selectivities somehow, the former would give 62.5 rows, and the second would give 25 rows. This should be fixed eventually, but for now, at least we register it, so that we do not assert-fail on inconsistent row counts if this (known) issue could be the root cause.
|
private |
A pointer to the query block being planned.
|
private |
OverflowBitset JoinHypergraph::materializable_predicates {0} |
Mem_root_array<Node> JoinHypergraph::nodes |
unsigned JoinHypergraph::num_where_predicates = 0 |
Mem_root_array<Predicate> JoinHypergraph::predicates |
SecondaryEngineCostingFlags JoinHypergraph::secondary_engine_costing_flags {} |
Flags set when AccessPaths are proposed to secondary engines for costing.
The intention of these flags is to avoid traversing the AccessPath tree to check for certain criteria. TODO (tikoldit) Move to JOIN or Secondary_engine_execution_context, so that JoinHypergraph can be immutable during planning
std::array<int, MAX_TABLES> JoinHypergraph::table_num_to_node_num |
table_map JoinHypergraph::tables_inner_to_outer_or_anti = 0 |
The set of tables that are on the inner side of some outer join or antijoin.
If a table is not part of this set, and it is found to be empty, we can assume that the result of the top-level join will also be empty.