1 /* 2 Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License, version 2.0, 6 as published by the Free Software Foundation. 7 8 This program is also distributed with certain software (including 9 but not limited to OpenSSL) that is licensed under separate terms, 10 as designated in a particular file or component or in included license 11 documentation. The authors of MySQL hereby grant you an additional 12 permission to link the program and your derivative works with the 13 separately licensed software that they have included with MySQL. 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 25 #ifndef ABSTRACT_QUERY_PLAN_H_INCLUDED 26 #define ABSTRACT_QUERY_PLAN_H_INCLUDED 27 28 #include <sys/types.h> 29 30 #include "my_dbug.h" 31 #include "sql/item_cmpfunc.h" // Item_equal_iterator 32 33 class Item; 34 class Item_field; 35 class JOIN; 36 class KEY_PART_INFO; 37 class QEP_TAB; 38 struct TABLE; 39 40 /** 41 Abstract query plan (AQP) is an interface for examining certain aspects of 42 query plans without accessing mysqld internal classes (JOIN_TAB, QEP_TAB, 43 etc.) directly. 44 45 AQP maps join execution plans, as represented by mysqld internals, to a set 46 of facade classes. Non-join operations such as sorting and aggregation is 47 currently *not* modelled in the AQP. 48 49 The AQP models an n-way join as a sequence of the n table access operations 50 that the MySQL server would execute as part of its nested loop join 51 execution. (Each such table access operation is a scan of a table or index, 52 or an index lookup.) For each lookup operation, it is possible to examine 53 the expression that represents each field in the key. 54 55 A storage enging will typically use the AQP for finding sections of a join 56 execution plan that may be executed in the engine rather than in mysqld. By 57 using the AQP rather than the mysqld internals directly, the coupling between 58 the engine and mysqld is reduced. 59 60 The AQP also provides functions which allows the storage engine 61 to change the query execution plan for the part of the join which 62 it will handle. Thus be aware that although the QEP_TAB*'s are const 63 they may be modified. 64 */ 65 namespace AQP 66 { 67 class Table_access; 68 69 /** 70 This class represents a query plan for an n-way join, in the form a 71 sequence of n table access operations that will execute as a nested loop 72 join. 73 */ 74 class Join_plan 75 { 76 friend class Equal_set_iterator; 77 friend class Table_access; 78 public: 79 80 explicit Join_plan(const JOIN* join); 81 82 ~Join_plan(); 83 84 Table_access* get_table_access(uint access_no) const; 85 86 uint get_access_count() const; 87 88 private: 89 /** 90 Array of the QEP_TABs that are the internal representation of table 91 access operations. 92 */ 93 const QEP_TAB* const m_qep_tabs; 94 95 /** Number of table access operations. */ 96 uint m_access_count; 97 Table_access* m_table_accesses; 98 99 const QEP_TAB* get_qep_tab(uint qep_tab_no) const; 100 101 // No copying. 102 Join_plan(const Join_plan&); 103 Join_plan& operator=(const Join_plan&); 104 }; 105 // class Join_plan 106 107 108 /** 109 This class is an iterator for iterating over sets of fields (columns) that 110 should have the same value. For example, if the query is 111 SELECT * FROM T1, T2, T3 WHERE T1.b = T2.a AND T2.a = T3.a 112 then there would be such a set of {T1.b, T2.a, T3.a}. 113 */ 114 class Equal_set_iterator 115 { 116 public: Equal_set_iterator(Item_equal & item_equal)117 explicit Equal_set_iterator(Item_equal& item_equal) 118 : m_iterator(item_equal) {} 119 next()120 const Item_field* next() 121 { return m_iterator++; } 122 123 private: 124 /** 125 This class is implemented in terms of this mysqld internal class. 126 */ 127 Item_equal_iterator m_iterator; 128 129 // No copying. 130 Equal_set_iterator(const Equal_set_iterator&); 131 Equal_set_iterator& operator=(const Equal_set_iterator&); 132 }; 133 // class Equal_set_iterator 134 135 /** The type of a table access operation. */ 136 enum enum_access_type 137 { 138 /** For default initialization.*/ 139 AT_VOID, 140 /** Value has already been fetched / determined by optimizer.*/ 141 AT_FIXED, 142 /** Do a lookup of a single primary key.*/ 143 AT_PRIMARY_KEY, 144 /** Do a lookup of a single unique index key.*/ 145 AT_UNIQUE_KEY, 146 /** Scan an ordered index with a single upper and lower bound pair.*/ 147 AT_ORDERED_INDEX_SCAN, 148 /** Do a multi range read for a set of primary keys.*/ 149 AT_MULTI_PRIMARY_KEY, 150 /** Do a multi range read for a set of unique index keys.*/ 151 AT_MULTI_UNIQUE_KEY, 152 /** 153 Do a multi range read for a mix of ranges (for which there is an 154 ordered index), and either primary keys or unique index keys. 155 */ 156 AT_MULTI_MIXED, 157 /** Scan a table. (No index is assumed to be used.) */ 158 AT_TABLE_SCAN, 159 /** Access method will not be chosen before the execution phase.*/ 160 AT_UNDECIDED, 161 /** 162 The access method has properties that prevents it from being pushed to a 163 storage engine. 164 */ 165 AT_OTHER 166 }; 167 168 /** 169 This class represents an access operation on a table, such as a table 170 scan, or a scan or lookup via an index. A Table_access object is always 171 owned by a Join_plan object, such that the life time of the Table_access 172 object ends when the life time of the owning Join_plan object ends. 173 */ 174 class Table_access 175 { 176 friend class Join_plan; 177 friend inline bool equal(const Table_access*, const Table_access*); 178 public: 179 180 const Join_plan* get_join_plan() const; 181 182 enum_access_type get_access_type() const; 183 184 const char* get_other_access_reason() const; 185 186 uint get_no_of_key_fields() const; 187 188 const Item* get_key_field(uint field_no) const; 189 190 const KEY_PART_INFO* get_key_part_info(uint field_no) const; 191 192 uint get_access_no() const; 193 194 int get_index_no() const; 195 196 TABLE* get_table() const; 197 198 Item_equal* get_item_equal(const Item_field* field_item) const; 199 200 void dbug_print() const; 201 202 bool uses_join_cache() const; 203 204 bool filesort_before_join() const; 205 206 Item* get_condition() const; 207 void set_condition(Item* cond); 208 209 uint get_first_inner() const; 210 uint get_last_inner() const; 211 int get_first_upper() const; 212 213 int get_first_sj_inner() const; 214 int get_last_sj_inner() const; 215 216 // Is member of a firstMatch sj_nest? 217 bool is_sj_firstmatch() const; 218 // Get the upper-table we skip out to upon a firstMatch 219 int get_firstmatch_return() const; 220 221 bool is_antijoin() const; 222 223 /** 224 Getter and setters for an opaque object for each table. 225 Used by the handler's to persist 'pushability-flags' to avoid 226 overhead by recalculating it for each ::engine_push() 227 */ 228 uint get_table_properties() const; 229 void set_table_properties(uint); 230 231 private: 232 233 /** Backref. to the Join_plan which this Table_access is part of */ 234 const Join_plan* m_join_plan; 235 236 /** This operation corresponds to m_root_tab[m_tab_no].*/ 237 uint m_tab_no; 238 239 /** The type of this operation.*/ 240 mutable enum_access_type m_access_type; 241 242 /** 243 The reason for getting m_access_type==AT_OTHER. Used for explain extended. 244 */ 245 mutable const char* m_other_access_reason; 246 247 /** The index to use for this operation (if applicable )*/ 248 mutable int m_index_no; 249 250 /** May store an opaque property / flag */ 251 uint m_properties; 252 253 explicit Table_access(); 254 255 const QEP_TAB* get_qep_tab() const; 256 257 void compute_type_and_index() const; 258 259 /** No copying*/ 260 Table_access(const Table_access&); 261 Table_access& operator=(const Table_access&); 262 }; 263 // class Table_access 264 265 /** 266 Get the n'th table access operation. 267 @param access_no The index of the table access operation to fetch. 268 @return The access_no'th table access operation. 269 */ get_table_access(uint access_no)270 inline Table_access* Join_plan::get_table_access(uint access_no) const 271 { 272 DBUG_ASSERT(access_no < m_access_count); 273 return m_table_accesses + access_no; 274 } 275 276 /** 277 @return The number of table access operations in the nested loop join. 278 */ get_access_count()279 inline uint Join_plan::get_access_count() const 280 { 281 return m_access_count; 282 } 283 284 /** Get the Join_plan that this Table_access belongs to.*/ get_join_plan()285 inline const Join_plan* Table_access::get_join_plan() const 286 { 287 return m_join_plan; 288 } 289 290 /** Get the type of this operation.*/ get_access_type()291 inline enum_access_type Table_access::get_access_type() const 292 { 293 if (m_access_type == AT_VOID) 294 compute_type_and_index(); 295 return m_access_type; 296 } 297 298 /** 299 Get a description of the reason for getting access_type==AT_OTHER. To be 300 used for informational messages. 301 @return A string that should be assumed to have the same life time as the 302 Table_access object. 303 */ get_other_access_reason()304 inline const char* Table_access::get_other_access_reason() const 305 { 306 if (m_access_type == AT_VOID) 307 compute_type_and_index(); 308 return m_other_access_reason; 309 } 310 311 /** 312 @return The number of the index to use for this access operation ( 313 or -1 for non-index operations). 314 */ get_index_no()315 inline int Table_access::get_index_no() const 316 { 317 if (m_access_type == AT_VOID) 318 compute_type_and_index(); 319 320 return m_index_no; 321 } 322 323 /** 324 Get the number of this Table_access within the enclosing Join_plan. 325 (This number will be in the range 0 to Join_plan::get_access_count() - 1.) 326 */ get_access_no()327 inline uint Table_access::get_access_no() const 328 { 329 return m_tab_no; 330 } 331 get_table_properties()332 inline uint Table_access::get_table_properties() const 333 { 334 return m_properties; 335 } 336 set_table_properties(uint val)337 inline void Table_access::set_table_properties(uint val) 338 { 339 m_properties = val; 340 } 341 342 } 343 // namespace AQP 344 345 #endif 346