My Project
ha_ndbcluster_push.h
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines