My Project
|
00001 /* 00002 Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU General Public License as published by 00006 the Free Software Foundation; version 2 of the License. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00016 */ 00017 00018 #include "sql_bitmap.h" 00019 00020 class NdbTransaction; 00021 class NdbQueryBuilder; 00022 class NdbQueryOperand; 00023 class NdbQueryOperationDef; 00024 class ndb_pushed_builder_ctx; 00025 struct NdbError; 00026 00027 namespace AQP{ 00028 class Join_plan; 00029 class Table_access; 00030 }; 00031 00032 void ndbcluster_build_key_map(const NdbDictionary::Table* table, 00033 const NDB_INDEX_DATA& index, 00034 const KEY *key_def, 00035 uint ix_map[]); 00036 00037 00044 typedef Bitmap<(MAX_TABLES > 64 ? MAX_TABLES : 64)> table_bitmap; 00045 00046 class ndb_table_access_map : public table_bitmap 00047 { 00048 public: 00049 explicit ndb_table_access_map() 00050 : table_bitmap(0) 00051 {} 00052 explicit ndb_table_access_map(uint table_no) 00053 : table_bitmap(0) 00054 { set_bit(table_no); 00055 } 00056 00057 void add(const ndb_table_access_map& table_map) 00058 { // Require const_cast as signature of class Bitmap::merge is not const correct 00059 merge(const_cast<ndb_table_access_map&>(table_map)); 00060 } 00061 void add(uint table_no) 00062 { 00063 set_bit(table_no); 00064 } 00065 00066 bool contain(const ndb_table_access_map& table_map) const 00067 { 00068 return table_map.is_subset(*this); 00069 } 00070 bool contain(uint table_no) const 00071 { 00072 return is_set(table_no); 00073 } 00074 00075 uint first_table(uint start= 0) const; 00076 uint last_table(uint start= MAX_TABLES) const; 00077 00078 }; // class ndb_table_access_map 00079 00080 00088 class ndb_pushed_join 00089 { 00090 public: 00091 explicit ndb_pushed_join(const ndb_pushed_builder_ctx& builder_ctx, 00092 const NdbQueryDef* query_def); 00093 00094 ~ndb_pushed_join(); 00095 00100 bool match_definition(int type, //NdbQueryOperationDef::Type, 00101 const NDB_INDEX_DATA* idx, 00102 bool needSorted) const; 00103 00105 NdbQuery* make_query_instance( 00106 NdbTransaction* trans, 00107 const NdbQueryParamValue* keyFieldParams, 00108 uint paramCnt) const; 00109 00111 uint get_operation_count() const 00112 { return m_operation_count; } 00113 00119 uint get_field_referrences_count() const 00120 { return m_field_count; } 00121 00122 const NdbQueryDef& get_query_def() const 00123 { return *m_query_def; } 00124 00126 TABLE* get_table(uint i) const 00127 { 00128 DBUG_ASSERT(i < m_operation_count); 00129 return m_tables[i]; 00130 } 00131 00136 static const uint MAX_KEY_PART= MAX_KEY; 00143 static const uint MAX_REFERRED_FIELDS= 16; 00148 static const uint MAX_LINKED_KEYS= MAX_KEY; 00153 static const uint MAX_PUSHED_OPERATIONS= MAX_TABLES; 00154 00155 private: 00156 const NdbQueryDef* const m_query_def; // Definition of pushed join query 00157 00159 uint m_operation_count; 00160 00162 TABLE* m_tables[MAX_PUSHED_OPERATIONS]; 00163 00168 const uint m_field_count; 00169 00174 Field* m_referred_fields[MAX_REFERRED_FIELDS]; 00175 }; // class ndb_pushed_join 00176 00177 00178 00187 class ndb_pushed_builder_ctx 00188 { 00189 friend ndb_pushed_join::ndb_pushed_join( 00190 const ndb_pushed_builder_ctx& builder_ctx, 00191 const NdbQueryDef* query_def); 00192 00193 public: 00194 ndb_pushed_builder_ctx(const AQP::Join_plan& plan); 00195 ~ndb_pushed_builder_ctx(); 00196 00204 int make_pushed_join(const AQP::Table_access* join_root, 00205 const ndb_pushed_join* &pushed_join); 00206 00207 const NdbError& getNdbError() const; 00208 00209 private: 00214 bool is_pushable_with_root( 00215 const AQP::Table_access* root); 00216 00217 bool is_pushable_as_child( 00218 const AQP::Table_access* table); 00219 00220 bool is_const_item_pushable( 00221 const Item* key_item, 00222 const KEY_PART_INFO* key_part); 00223 00224 bool is_field_item_pushable( 00225 const AQP::Table_access* table, 00226 const Item* key_item, 00227 const KEY_PART_INFO* key_part, 00228 ndb_table_access_map& parents); 00229 00230 int optimize_query_plan(); 00231 00232 int build_query(); 00233 00234 void collect_key_refs( 00235 const AQP::Table_access* table, 00236 const Item* key_refs[]) const; 00237 00238 int build_key(const AQP::Table_access* table, 00239 const NdbQueryOperand* op_key[]); 00240 00241 uint get_table_no(const Item* key_item) const; 00242 00243 private: 00244 const AQP::Join_plan& m_plan; 00245 const AQP::Table_access* m_join_root; 00246 00247 // Scope of tables covered by this pushed join 00248 ndb_table_access_map m_join_scope; 00249 00250 // Scope of tables evaluated prior to 'm_join_root' 00251 // These are effectively const or params wrt. the pushed join 00252 ndb_table_access_map m_const_scope; 00253 00254 // Set of tables required to have strict sequential dependency 00255 ndb_table_access_map m_forced_sequence; 00256 00257 uint m_fld_refs; 00258 Field* m_referred_fields[ndb_pushed_join::MAX_REFERRED_FIELDS]; 00259 00260 // Handle to the NdbQuery factory. 00261 // Possibly reused if multiple NdbQuery's are pushed. 00262 NdbQueryBuilder* m_builder; 00263 00264 enum pushability 00265 { 00266 PUSHABLE_AS_PARENT= 0x01, 00267 PUSHABLE_AS_CHILD= 0x02 00268 } enum_pushability; 00269 00270 struct pushed_tables 00271 { 00272 pushed_tables() : 00273 m_maybe_pushable(0), 00274 m_common_parents(), 00275 m_extend_parents(), 00276 m_depend_parents(), 00277 m_parent(MAX_TABLES), 00278 m_ancestors(), 00279 m_op(NULL) 00280 {} 00281 00282 int m_maybe_pushable; // OR'ed bits from 'enum_pushability' 00283 00293 ndb_table_access_map m_common_parents; 00294 ndb_table_access_map m_extend_parents; 00295 00300 ndb_table_access_map m_depend_parents; 00301 00306 uint m_parent; 00307 00311 ndb_table_access_map m_ancestors; 00312 00313 const NdbQueryOperationDef* m_op; 00314 } m_tables[MAX_TABLES]; 00315 00319 struct table_remap 00320 { 00321 Uint16 to_external; // m_remap[] is indexed with internal table_no 00322 Uint16 to_internal; // m_remap[] is indexed with external tablenr 00323 } m_remap[MAX_TABLES]; 00324 00325 }; // class ndb_pushed_builder_ctx 00326 00327