MySQL 9.5.0
Source Code Documentation
relational_expression.h
Go to the documentation of this file.
1/* Copyright (c) 2020, 2025, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef SQL_JOIN_OPTIMIZER_RELATIONAL_EXPRESSION_H
25#define SQL_JOIN_OPTIMIZER_RELATIONAL_EXPRESSION_H
26
27#include <sys/types.h>
28#include <algorithm>
29#include <array>
30#include <cassert>
31#include <string>
32#include <type_traits>
33#include <utility>
34
35#include "my_table_map.h"
36#include "sql/field.h"
37#include "sql/item.h"
42#include "sql/join_type.h"
43#include "sql/mem_root_array.h"
44#include "sql/nested_join.h"
45#include "sql/sql_class.h"
46#include "sql/sql_const.h"
47#include "sql/table.h"
48
49class Item_eq_base;
50class Item_func_eq;
51
52// Some information about each predicate that the join optimizer would like to
53// have available in order to avoid computing it anew for each use of that
54// predicate.
57 double selectivity{};
58
59 // For equijoins only: A bitmap of which sargable predicates
60 // are part of the same multi-equality as this one (except the
61 // condition itself, which is excluded), and thus are redundant
62 // against it. This is used in AlreadyAppliedThroughSargable()
63 // to quickly find out if we already have applied any of them
64 // as a join condition.
66};
67
68// Describes a rule disallowing specific joins; if any tables from
69// needed_to_activate_rule is part of the join, then _all_ tables from
70// required_nodes must also be present.
71//
72// See FindHyperedgeAndJoinConflicts() for details.
76};
77
78/**
79 RelationalExpression objects in the same companion set are those
80 that are inner-joined against each other; we use this to see in
81 what parts of the graph we allow cycles. (Within companion sets, we
82 are also allowed to add Cartesian products if we deem that an
83 advantage, but we don't do it currently.) Tables may be alone in
84 their companion sets. Companion sets are also used when calculating
85 selectivity for equijoin predicates using multi-field indexes,
86 @see EstimateEqualPredicateSelectivity()).
87*/
88class CompanionSet final {
89 public:
90 CompanionSet() = default;
91
92 explicit CompanionSet(THD *thd) : m_equal_terms(thd->mem_root) {}
93
94 /// No copying.
95 CompanionSet(const CompanionSet &) = delete;
97
98 /// Add the set of equal fields specified by 'eq'.
99 void AddEquijoinCondition(THD *thd, const Item_eq_base &eq);
100
101 /**
102 If 'field' is part of an equijoin predicate in this CompanionSet, return a
103 table_map of the tables involved in that predicate. Otherwise, return 0.
104 */
105 table_map GetEqualityMap(const Field &field) const;
106
107 /// For tracing and debugging.
108 /// @returns A string representation like "{{t1.f1, t2.f2}, {t2.f3, t3.f4}}".
109 std::string ToString() const;
110
111 private:
113
114 /**
115 This represents equality between a set of fields, i.e.
116 "t1.f1=t2.f2...=tN.fN".
117 */
118 struct EqualTerm {
119 /// The fields that are equal to each other.
121
122 /// A map of all tables in 'fields'.
124 };
125
126 /**
127 The set of sets of fields in equijoin predicates in this companion set.
128 (@see EstimateEqualPredicateSelectivity() to see how this is utilized.)
129 For example, if we have:
130
131 SELECT ... FROM t1, t2, t3 WHERE t1.x=t2.x AND t2.x=t3.x AND t2.y=t3.y
132
133 m_equal_terms will contain:
134
135 {{t1.x, t2.x, t3.x}, {t2.y, t3.y}}
136 */
138};
139
140/**
141 Represents an expression tree in the relational algebra of joins.
142 Expressions are either tables, or joins of two expressions.
143 (Joins can have join conditions, but more general filters are
144 not represented in this structure.)
145
146 These are used as an abstract precursor to the join hypergraph;
147 they represent the joins in the query block more or less directly,
148 without any reordering. (The parser should largely have output a
149 structure like this instead of Table_ref, but we are not there yet.)
150 The only real manipulation we do on them is pushing down conditions,
151 identifying equijoin conditions from other join conditions,
152 and identifying join conditions that touch given tables (also a form
153 of pushdown).
154 */
156 enum Type {
157 INNER_JOIN = static_cast<int>(JoinType::INNER),
158 LEFT_JOIN = static_cast<int>(JoinType::OUTER),
159
160 /// Left semijoin.
161 SEMIJOIN = static_cast<int>(JoinType::SEMI),
162
163 /// Left antijoin.
164 ANTIJOIN = static_cast<int>(JoinType::ANTI),
165
166 // STRAIGHT_JOIN is an inner join that the user has specified
167 // is noncommutative (as a hint, but one we are not allowed to
168 // disregard).
170
171 // Generally supported by the conflict detector only, not the parser
172 // or any iterators. We include this because we will be needing it
173 // when we actually implement full outer join, and because it helps
174 // verifying semijoin correctness in the unit tests (see the CountPlans*
175 // tests).
177
178 // An inner join between two _or more_ tables, with no join conditions.
179 // This is a special form used only during pushdown, for increased
180 // flexibility in reordering. MULTI_INNER_JOIN nodes do not use
181 // left and right, but rather store all its children in multi_children
182 // (which is empty for all other types).
184
185 TABLE = 100
187
189 : multi_children(thd->mem_root),
195
197
198 // Exactly the same as tables_in_subtree, just with node indexes instead of
199 // table indexes. This is stored alongside tables_in_subtree to save the cost
200 // and convenience of doing repeated translation between the two.
202
203 // If type == TABLE.
205
206 // The CompanionSet that this object is part of.
208
209 // If type != TABLE. Note that equijoin_conditions will be split off
210 // from join_conditions fairly late (at CreateHashJoinConditions()),
211 // so often, you will see equijoin conditions in join_condition..
214 multi_children; // See MULTI_INNER_JOIN.
217
218 // For each element in join_conditions and equijoin_conditions (respectively),
219 // contains some cached properties that the join optimizer would like to have
220 // available for frequent reuse.
221 //
222 // It is a bit awkward to have these separate instead of in the same arrays,
223 // but the latter would complicate MakeJoinHypergraph() a fair amount,
224 // as this information is private to the join optimizer (ie., it is not
225 // generated along with the hypergraph; it is added after MakeJoinHypergraph()
226 // is completed).
230
231 // If true, at least one condition under “join_conditions” is a false (0)
232 // constant. (Such conditions can never be under “equijoin_conditions”.)
235 // If the join conditions were also added as predicates due to cycles
236 // in the graph (see comment in AddCycleEdges()), contains a range of
237 // which indexes they got in the predicate list. This is so that we know that
238 // they are redundant and don't have to apply them if we actually apply this
239 // join (as opposed to getting the edge implicitly by means of joining the
240 // tables along some other way in the cycle).
242
243 // Conflict rules that must be checked before making a subgraph
244 // out of this join; this is in addition to the regular connectivity
245 // check. See FindHyperedgeAndJoinConflicts() for more details.
248
251 }
252
255 }
256
257 /// Add a condition that can be pushed down to the access path for 'table'.
258 void AddPushable(Item *cond, const RelationalExpression *from) {
259 assert(type == TABLE);
260 assert(from->type != TABLE);
261 assert(table->map() && cond->used_tables() != 0);
262 // Don't add duplicates.
263 if (std::ranges::none_of(m_pushable_conditions,
264 [&](const PushableJoinCondition &other) {
265 return ItemsAreEqual(cond, other.cond);
266 })) {
267 m_pushable_conditions.push_back({.cond = cond, .from = from});
268 }
269 }
270
271 private:
272 /// Conditions that can be pushed down to the access path for 'table'
274};
275
276// Check conflict rules; usually, they will be empty, but the hyperedges are
277// not able to encode every single combination of disallowed joins.
278inline bool PassesConflictRules(hypergraph::NodeMap joined_tables,
279 const RelationalExpression *expr) {
280 for (const ConflictRule &rule : expr->conflict_rules) {
281 if (Overlaps(joined_tables, rule.needed_to_activate_rule) &&
282 !IsSubset(rule.required_nodes, joined_tables)) {
283 return false;
284 }
285 }
286 return true;
287}
288
289// Whether (a <expr> b) === (b <expr> a). See also OperatorsAreAssociative() and
290// OperatorsAre{Left,Right}Asscom() in make_join_hypergraph.cc.
292 return expr.type == RelationalExpression::INNER_JOIN ||
294}
295
296// Call the given functor on each non-table operator in the tree below expr,
297// including expr itself, in post-traversal order.
298template <class Operator, class Func>
299 requires std::is_same_v<RelationalExpression,
300 std::remove_const_t<Operator>> &&
301 std::is_invocable_v<Func, Operator *>
302void ForEachJoinOperator(Operator *expr, Func &&func) {
303 if (expr->type == RelationalExpression::TABLE) {
304 return;
305 }
306 ForEachJoinOperator(expr->left, std::forward<Func &&>(func));
307 ForEachJoinOperator(expr->right, std::forward<Func &&>(func));
308 func(expr);
309}
310
311template <class Func>
312void ForEachOperator(RelationalExpression *expr, Func &&func) {
313 if (expr->type != RelationalExpression::TABLE) {
314 ForEachOperator(expr->left, std::forward<Func &&>(func));
315 ForEachOperator(expr->right, std::forward<Func &&>(func));
316 }
317 func(expr);
318}
319
320/// The collection of CompanionSet objects for a given JoinHypergraph.
322 public:
324 Compute(thd, root, nullptr);
325 }
326
327 /// No copying.
330
331 CompanionSet *Find(table_map tables) { return FindInternal(tables); }
332
333 const CompanionSet *Find(table_map tables) const {
334 return FindInternal(tables);
335 }
336
337 /// For trace and debugging.
338 std::string ToString() const;
339
340 private:
341 /// A mapping from table number to CompanionSet.
342 std::array<CompanionSet *, MAX_TABLES> m_table_num_to_companion_set{nullptr};
343
344 /**
345 Compute the CompanionSet of 'expr' and all of its descendants.
346 @param thd The current thread.
347 @param expr Compute CompanionSet of this and all of its descendants.
348 @param current_set The CompanionSet to which 'expr' will belong, or
349 nullptr if 'expr' is the root of a new set.
350 */
351 void Compute(THD *thd, RelationalExpression *expr, CompanionSet *current_set);
352
353 /**
354 For a given set of tables, find the CompanionSet they are part of
355 Returns nullptr if the tables are in different (i.e., incompatible)
356 CompanionSet instances. If so, a condition using this set of
357 tables can _not_ induce a new (cycle) edge in the hypergraph, as
358 there are non-inner joins in the way.
359 */
360 CompanionSet *FindInternal(table_map tables) const;
361};
362
363#endif // SQL_JOIN_OPTIMIZER_RELATIONAL_EXPRESSION_H
bool IsSubset(uint64_t x, uint64_t y)
Definition: bit_utils.h:221
bool Overlaps(uint64_t x, uint64_t y)
Definition: bit_utils.h:229
The collection of CompanionSet objects for a given JoinHypergraph.
Definition: relational_expression.h:321
CompanionSet * Find(table_map tables)
Definition: relational_expression.h:331
CompanionSet * FindInternal(table_map tables) const
For a given set of tables, find the CompanionSet they are part of Returns nullptr if the tables are i...
Definition: relational_expression.cc:204
CompanionSetCollection(const CompanionSetCollection &)=delete
No copying.
void Compute(THD *thd, RelationalExpression *expr, CompanionSet *current_set)
Compute the CompanionSet of 'expr' and all of its descendants.
Definition: relational_expression.cc:154
std::array< CompanionSet *, MAX_TABLES > m_table_num_to_companion_set
A mapping from table number to CompanionSet.
Definition: relational_expression.h:342
CompanionSetCollection & operator=(const CompanionSetCollection &)=delete
CompanionSetCollection(THD *thd, struct RelationalExpression *root)
Definition: relational_expression.h:323
std::string ToString() const
For trace and debugging.
Definition: relational_expression.cc:186
const CompanionSet * Find(table_map tables) const
Definition: relational_expression.h:333
RelationalExpression objects in the same companion set are those that are inner-joined against each o...
Definition: relational_expression.h:88
CompanionSet & operator=(const CompanionSet &)=delete
CompanionSet()=default
Mem_root_array< EqualTerm > m_equal_terms
The set of sets of fields in equijoin predicates in this companion set.
Definition: relational_expression.h:137
table_map GetEqualityMap(const Field &field) const
If 'field' is part of an equijoin predicate in this CompanionSet, return a table_map of the tables in...
Definition: relational_expression.cc:126
CompanionSet(const CompanionSet &)=delete
No copying.
CompanionSet(THD *thd)
Definition: relational_expression.h:92
std::string ToString() const
For tracing and debugging.
Definition: relational_expression.cc:137
void AddEquijoinCondition(THD *thd, const Item_eq_base &eq)
Add the set of equal fields specified by 'eq'.
Definition: relational_expression.cc:71
Definition: field.h:570
Base class for the equality comparison operators = and <=>.
Definition: item_cmpfunc.h:1045
Implements the comparison operator equals (=)
Definition: item_cmpfunc.h:1110
Base class that is used to represent any kind of expression in a relational query.
Definition: item.h:928
virtual table_map used_tables() const
Definition: item.h:2379
A typesafe replacement for DYNAMIC_ARRAY.
Definition: mem_root_array.h:432
Definition: overflow_bitset.h:81
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:36
Definition: table.h:2933
table_map map() const
Return table map derived from table number.
Definition: table.h:4122
NESTED_JOIN * nested_join
Is non-NULL if this table reference is a nested join, ie it represents the inner tables of an outer j...
Definition: table.h:3994
static MEM_ROOT mem_root
Definition: client_plugin.cc:114
bool ItemsAreEqual(const Item *a, const Item *b)
Returns true iff the two items are equal, as in a->eq(b), after unwrapping refs and Item_cache object...
Definition: item.cc:11568
@ OUTER
Left outer join.
@ ANTI
Left antijoin, i.e.
@ SEMI
Left semijoin, i.e.
uint64_t table_map
Definition: my_table_map.h:30
uint64_t NodeMap
Since our graphs can never have more than 61 tables, node sets and edge lists are implemented using 6...
Definition: node_map.h:40
OverflowBitset is a fixed-size (once allocated) bitmap that is optimized for the common case of few e...
void ForEachOperator(RelationalExpression *expr, Func &&func)
Definition: relational_expression.h:312
bool PassesConflictRules(hypergraph::NodeMap joined_tables, const RelationalExpression *expr)
Definition: relational_expression.h:278
void ForEachJoinOperator(Operator *expr, Func &&func)
Definition: relational_expression.h:302
bool OperatorIsCommutative(const RelationalExpression &expr)
Definition: relational_expression.h:291
File containing constants that can be used throughout the server.
Definition: relational_expression.h:55
double selectivity
Definition: relational_expression.h:57
Mem_root_array< ContainedSubquery > contained_subqueries
Definition: relational_expression.h:56
OverflowBitset redundant_against_sargable_predicates
Definition: relational_expression.h:65
This represents equality between a set of fields, i.e.
Definition: relational_expression.h:118
FieldArray * fields
The fields that are equal to each other.
Definition: relational_expression.h:120
table_map tables
A map of all tables in 'fields'.
Definition: relational_expression.h:123
Definition: relational_expression.h:73
hypergraph::NodeMap required_nodes
Definition: relational_expression.h:75
hypergraph::NodeMap needed_to_activate_rule
Definition: relational_expression.h:74
uint sj_enabled_strategies
Bitmap of which strategies are enabled for this semi-join nest.
Definition: nested_join.h:136
Information about a join condition that can potentially be pushed down as a sargable predicate for a ...
Definition: make_join_hypergraph.h:81
Item * cond
The condition that may be pushed as a sargable predicate.
Definition: make_join_hypergraph.h:83
Represents an expression tree in the relational algebra of joins.
Definition: relational_expression.h:155
int join_predicate_last
Definition: relational_expression.h:241
Mem_root_array< CachedPropertiesForPredicate > properties_for_equijoin_conditions
Definition: relational_expression.h:229
Mem_root_array< PushableJoinCondition > m_pushable_conditions
Conditions that can be pushed down to the access path for 'table'.
Definition: relational_expression.h:273
Mem_root_array< Item_eq_base * > equijoin_conditions
Definition: relational_expression.h:216
int join_predicate_first
Definition: relational_expression.h:241
Mem_root_array< ConflictRule > conflict_rules
Definition: relational_expression.h:246
void enable_semijoin_strategies(const Table_ref *tl)
Definition: relational_expression.h:249
enum RelationalExpression::Type type
void AddPushable(Item *cond, const RelationalExpression *from)
Add a condition that can be pushed down to the access path for 'table'.
Definition: relational_expression.h:258
CompanionSet * companion_set
Definition: relational_expression.h:207
RelationalExpression(THD *thd)
Definition: relational_expression.h:188
table_map tables_in_subtree
Definition: relational_expression.h:196
const Table_ref * table
Definition: relational_expression.h:204
hypergraph::NodeMap nodes_in_subtree
Definition: relational_expression.h:201
Mem_root_array< RelationalExpression * > multi_children
Definition: relational_expression.h:214
uint sj_enabled_strategies
Definition: relational_expression.h:247
table_map conditions_used_tables
Definition: relational_expression.h:234
Mem_root_array< Item * > join_conditions
Definition: relational_expression.h:215
Type
Definition: relational_expression.h:156
@ SEMIJOIN
Left semijoin.
Definition: relational_expression.h:161
@ MULTI_INNER_JOIN
Definition: relational_expression.h:183
@ STRAIGHT_INNER_JOIN
Definition: relational_expression.h:169
@ ANTIJOIN
Left antijoin.
Definition: relational_expression.h:164
@ INNER_JOIN
Definition: relational_expression.h:157
@ FULL_OUTER_JOIN
Definition: relational_expression.h:176
@ TABLE
Definition: relational_expression.h:185
@ LEFT_JOIN
Definition: relational_expression.h:158
bool join_conditions_reject_all_rows
Definition: relational_expression.h:233
Mem_root_array< CachedPropertiesForPredicate > properties_for_join_conditions
Definition: relational_expression.h:227
RelationalExpression * left
Definition: relational_expression.h:212
const Mem_root_array< PushableJoinCondition > & pushable_conditions() const
Definition: relational_expression.h:253
RelationalExpression * right
Definition: relational_expression.h:212
Definition: table.h:1435