My Project
ha_ndbcluster_cond.h
00001 /*
00002    Copyright (C) 2000-2007 MySQL AB
00003     All rights reserved. Use is subject to license terms.
00004 
00005    This program is free software; you can redistribute it and/or modify
00006    it under the terms of the GNU General Public License as published by
00007    the Free Software Foundation; version 2 of the License.
00008 
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012    GNU General Public License for more details.
00013 
00014    You should have received a copy of the GNU General Public License
00015    along with this program; if not, write to the Free Software
00016    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
00017 */
00018 
00019 /*
00020   This file defines the data structures used by engine condition pushdown in
00021   the NDB Cluster handler
00022 */
00023 
00024 typedef enum ndb_item_type {
00025   NDB_VALUE = 0,   // Qualified more with Item::Type
00026   NDB_FIELD = 1,   // Qualified from table definition
00027   NDB_FUNCTION = 2,// Qualified from Item_func::Functype
00028   NDB_END_COND = 3 // End marker for condition group
00029 } NDB_ITEM_TYPE;
00030 
00031 typedef enum ndb_func_type {
00032   NDB_EQ_FUNC = 0,
00033   NDB_NE_FUNC = 1,
00034   NDB_LT_FUNC = 2,
00035   NDB_LE_FUNC = 3,
00036   NDB_GT_FUNC = 4,
00037   NDB_GE_FUNC = 5,
00038   NDB_ISNULL_FUNC = 6,
00039   NDB_ISNOTNULL_FUNC = 7,
00040   NDB_LIKE_FUNC = 8,
00041   NDB_NOTLIKE_FUNC = 9,
00042   NDB_NOT_FUNC = 10,
00043   NDB_UNKNOWN_FUNC = 11,
00044   NDB_COND_AND_FUNC = 12,
00045   NDB_COND_OR_FUNC = 13,
00046   NDB_UNSUPPORTED_FUNC = 14
00047 } NDB_FUNC_TYPE;
00048 
00049 typedef union ndb_item_qualification {
00050   Item::Type value_type; 
00051   enum_field_types field_type; // Instead of Item::FIELD_ITEM
00052   NDB_FUNC_TYPE function_type; // Instead of Item::FUNC_ITEM
00053 } NDB_ITEM_QUALIFICATION;
00054 
00055 typedef struct ndb_item_field_value {
00056   Field* field;
00057   int column_no;
00058 } NDB_ITEM_FIELD_VALUE;
00059 
00060 typedef union ndb_item_value {
00061   const Item *item;
00062   NDB_ITEM_FIELD_VALUE *field_value;
00063   uint arg_count;
00064 } NDB_ITEM_VALUE;
00065 
00066 struct negated_function_mapping
00067 {
00068   NDB_FUNC_TYPE pos_fun;
00069   NDB_FUNC_TYPE neg_fun;
00070 };
00071 
00072 /*
00073   Define what functions can be negated in condition pushdown.
00074   Note, these HAVE to be in the same order as in definition enum
00075 */
00076 static const negated_function_mapping neg_map[]= 
00077 {
00078   {NDB_EQ_FUNC, NDB_NE_FUNC},
00079   {NDB_NE_FUNC, NDB_EQ_FUNC},
00080   {NDB_LT_FUNC, NDB_GE_FUNC},
00081   {NDB_LE_FUNC, NDB_GT_FUNC},
00082   {NDB_GT_FUNC, NDB_LE_FUNC},
00083   {NDB_GE_FUNC, NDB_LT_FUNC},
00084   {NDB_ISNULL_FUNC, NDB_ISNOTNULL_FUNC},
00085   {NDB_ISNOTNULL_FUNC, NDB_ISNULL_FUNC},
00086   {NDB_LIKE_FUNC, NDB_NOTLIKE_FUNC},
00087   {NDB_NOTLIKE_FUNC, NDB_LIKE_FUNC},
00088   {NDB_NOT_FUNC, NDB_UNSUPPORTED_FUNC},
00089   {NDB_UNKNOWN_FUNC, NDB_UNSUPPORTED_FUNC},
00090   {NDB_COND_AND_FUNC, NDB_UNSUPPORTED_FUNC},
00091   {NDB_COND_OR_FUNC, NDB_UNSUPPORTED_FUNC},
00092   {NDB_UNSUPPORTED_FUNC, NDB_UNSUPPORTED_FUNC}
00093 };
00094   
00095 /*
00096   This class is the construction element for serialization of Item tree 
00097   in condition pushdown.
00098   An instance of Ndb_Item represents a constant, table field reference,
00099   unary or binary comparison predicate, and start/end of AND/OR.
00100   Instances of Ndb_Item are stored in a linked list implemented by Ndb_cond
00101   class.
00102   The order of elements produced by Ndb_cond::next corresponds to
00103   breadth-first traversal of the Item (i.e. expression) tree in prefix order.
00104   AND and OR have arbitrary arity, so the end of AND/OR group is marked with  
00105   Ndb_item with type == NDB_END_COND.
00106   NOT items represent negated conditions and generate NAND/NOR groups.
00107 */
00108 class Ndb_item : public Sql_alloc
00109 {
00110 public:
00111   Ndb_item(NDB_ITEM_TYPE item_type) : type(item_type) {};
00112   Ndb_item(NDB_ITEM_TYPE item_type, 
00113            NDB_ITEM_QUALIFICATION item_qualification,
00114            const Item *item_value)
00115     : type(item_type), qualification(item_qualification)
00116   { 
00117     switch(item_type) {
00118     case(NDB_VALUE):
00119       value.item= item_value;
00120       break;
00121     case(NDB_FIELD): {
00122       NDB_ITEM_FIELD_VALUE *field_value= new NDB_ITEM_FIELD_VALUE();
00123       Item_field *field_item= (Item_field *) item_value;
00124       field_value->field= field_item->field;
00125       field_value->column_no= -1; // Will be fetched at scan filter generation
00126       value.field_value= field_value;
00127       break;
00128     }
00129     case(NDB_FUNCTION):
00130       value.item= item_value;
00131       value.arg_count= ((Item_func *) item_value)->argument_count();
00132       break;
00133     case(NDB_END_COND):
00134       break;
00135     }
00136   };
00137   Ndb_item(Field *field, int column_no) : type(NDB_FIELD)
00138   {
00139     NDB_ITEM_FIELD_VALUE *field_value= new NDB_ITEM_FIELD_VALUE();
00140     qualification.field_type= field->real_type();
00141     field_value->field= field;
00142     field_value->column_no= column_no;
00143     value.field_value= field_value;
00144   };
00145   Ndb_item(Item_func::Functype func_type, const Item *item_value) 
00146     : type(NDB_FUNCTION)
00147   {
00148     qualification.function_type= item_func_to_ndb_func(func_type);
00149     value.item= item_value;
00150     value.arg_count= ((Item_func *) item_value)->argument_count();
00151   };
00152   Ndb_item(Item_func::Functype func_type, uint no_args) 
00153     : type(NDB_FUNCTION)
00154   {
00155     qualification.function_type= item_func_to_ndb_func(func_type);
00156     value.arg_count= no_args;
00157   };
00158   ~Ndb_item()
00159   { 
00160     if (type == NDB_FIELD)
00161       {
00162         delete value.field_value;
00163         value.field_value= NULL;
00164       }
00165   };
00166 
00167   uint32 pack_length() 
00168   { 
00169     switch(type) {
00170     case(NDB_VALUE):
00171       if(qualification.value_type == Item::STRING_ITEM)
00172         return value.item->str_value.length();
00173       break;
00174     case(NDB_FIELD):
00175       return value.field_value->field->pack_length(); 
00176     default:
00177       break;
00178     }
00179     
00180     return 0;
00181   };
00182 
00183   Field * get_field() { return value.field_value->field; };
00184 
00185   int get_field_no() { return value.field_value->column_no; };
00186 
00187   int argument_count() 
00188   { 
00189     return value.arg_count;
00190   };
00191 
00192   const char* get_val() 
00193   {  
00194     switch(type) {
00195     case(NDB_VALUE):
00196       if(qualification.value_type == Item::STRING_ITEM)
00197         return value.item->str_value.ptr();
00198       break;
00199     case(NDB_FIELD):
00200       return (char*) value.field_value->field->ptr; 
00201     default:
00202       break;
00203     }
00204     
00205     return NULL;
00206   };
00207 
00208   void save_in_field(Ndb_item *field_item)
00209   {
00210     DBUG_ENTER("save_in_field");
00211     Field *field = field_item->value.field_value->field;
00212     const Item *item= value.item;
00213     if (item && field)
00214     {
00215       DBUG_PRINT("info", ("item length %u, field length %u",
00216                           item->max_length, field->field_length));
00217       if (item->max_length > field->field_length)
00218       {
00219         DBUG_PRINT("info", ("Comparing field with longer value"));
00220         DBUG_PRINT("info", ("Field can store %u", field->field_length));
00221       }
00222       my_bitmap_map *old_map=
00223         dbug_tmp_use_all_columns(field->table, field->table->write_set);
00224       ((Item *)item)->save_in_field(field, FALSE);
00225       dbug_tmp_restore_column_map(field->table->write_set, old_map);
00226     }
00227     DBUG_VOID_RETURN;
00228   };
00229 
00230   static NDB_FUNC_TYPE item_func_to_ndb_func(Item_func::Functype fun)
00231   {
00232     switch (fun) {
00233     case (Item_func::EQ_FUNC): { return NDB_EQ_FUNC; }
00234     case (Item_func::NE_FUNC): { return NDB_NE_FUNC; }
00235     case (Item_func::LT_FUNC): { return NDB_LT_FUNC; }
00236     case (Item_func::LE_FUNC): { return NDB_LE_FUNC; }
00237     case (Item_func::GT_FUNC): { return NDB_GT_FUNC; }
00238     case (Item_func::GE_FUNC): { return NDB_GE_FUNC; }
00239     case (Item_func::ISNULL_FUNC): { return NDB_ISNULL_FUNC; }
00240     case (Item_func::ISNOTNULL_FUNC): { return NDB_ISNOTNULL_FUNC; }
00241     case (Item_func::LIKE_FUNC): { return NDB_LIKE_FUNC; }
00242     case (Item_func::NOT_FUNC): { return NDB_NOT_FUNC; }
00243     case (Item_func::NEG_FUNC): { return NDB_UNKNOWN_FUNC; }
00244     case (Item_func::UNKNOWN_FUNC): { return NDB_UNKNOWN_FUNC; }
00245     case (Item_func::COND_AND_FUNC): { return NDB_COND_AND_FUNC; }
00246     case (Item_func::COND_OR_FUNC): { return NDB_COND_OR_FUNC; }
00247     default: { return NDB_UNSUPPORTED_FUNC; }
00248     }
00249   };
00250 
00251   static NDB_FUNC_TYPE negate(NDB_FUNC_TYPE fun)
00252   {
00253     uint i= (uint) fun;
00254     DBUG_ASSERT(fun == neg_map[i].pos_fun);
00255     return  neg_map[i].neg_fun;
00256   };
00257 
00258   NDB_ITEM_TYPE type;
00259   NDB_ITEM_QUALIFICATION qualification;
00260  private:
00261   NDB_ITEM_VALUE value;
00262 };
00263 
00264 /*
00265   This class implements a linked list used for storing a
00266   serialization of the Item tree for condition pushdown.
00267  */
00268 class Ndb_cond : public Sql_alloc
00269 {
00270  public:
00271   Ndb_cond() : ndb_item(NULL), next(NULL), prev(NULL) {};
00272   ~Ndb_cond() 
00273   { 
00274     if (ndb_item) delete ndb_item; 
00275     ndb_item= NULL;
00276     /*
00277       First item in the linked list deletes all in a loop
00278       Note - doing it recursively causes stack issues for
00279       big IN clauses
00280     */
00281     Ndb_cond *n= next;
00282     while (n)
00283     {
00284       Ndb_cond *tmp= n;
00285       n= n->next;
00286       tmp->next= NULL;
00287       delete tmp;
00288     }
00289     next= prev= NULL; 
00290   };
00291   Ndb_item *ndb_item;
00292   Ndb_cond *next;
00293   Ndb_cond *prev;
00294 };
00295 
00296 /*
00297   This class implements a stack for storing several conditions
00298   for pushdown (represented as serialized Item trees using Ndb_cond).
00299   The current implementation only pushes one condition, but is
00300   prepared for handling several (C1 AND C2 ...) if the logic for 
00301   pushing conditions is extended in sql_select.
00302 */
00303 class Ndb_cond_stack : public Sql_alloc
00304 {
00305  public:
00306   Ndb_cond_stack() : ndb_cond(NULL), next(NULL) {};
00307   ~Ndb_cond_stack() 
00308   { 
00309     if (ndb_cond) delete ndb_cond; 
00310     ndb_cond= NULL; 
00311     if (next) delete next;
00312     next= NULL; 
00313   };
00314   Ndb_cond *ndb_cond;
00315   Ndb_cond_stack *next;
00316 };
00317 
00318 /*
00319   This class implements look-ahead during the parsing
00320   of the item tree. It contains bit masks for expected
00321   items, field types and field results. It also contains
00322   expected collation. The parse context (Ndb_cond_traverse_context)
00323   always contains one expect_stack instance (top of the stack).
00324   More expects (deeper look-ahead) can be pushed to the expect_stack
00325   to check specific order (currently used for detecting support for
00326   <field> LIKE <string>|<func>, but not <string>|<func> LIKE <field>).
00327  */
00328 class Ndb_expect_stack : public Sql_alloc
00329 {
00330   static const uint MAX_EXPECT_ITEMS = Item::VIEW_FIXER_ITEM + 1;
00331   static const uint MAX_EXPECT_FIELD_TYPES = MYSQL_TYPE_GEOMETRY + 1;
00332   static const uint MAX_EXPECT_FIELD_RESULTS = DECIMAL_RESULT + 1;
00333  public:
00334 Ndb_expect_stack(): collation(NULL), length(0), max_length(0), next(NULL) 
00335   {
00336     // Allocate type checking bitmaps using fixed size buffers
00337     // since max size is known at compile time
00338     bitmap_init(&expect_mask, m_expect_buf,
00339                 MAX_EXPECT_ITEMS, FALSE);
00340     bitmap_init(&expect_field_type_mask, m_expect_field_type_buf,
00341                 MAX_EXPECT_FIELD_TYPES, FALSE);
00342     bitmap_init(&expect_field_result_mask, m_expect_field_result_buf,
00343                 MAX_EXPECT_FIELD_RESULTS, FALSE);
00344   };
00345   ~Ndb_expect_stack()
00346   {
00347     if (next)
00348       delete next;
00349     next= NULL;
00350   }
00351   void push(Ndb_expect_stack* expect_next)
00352   {
00353     next= expect_next;
00354   }
00355   void pop()
00356   {
00357     if (next)
00358     {
00359       Ndb_expect_stack* expect_next= next;
00360       bitmap_clear_all(&expect_mask);
00361       bitmap_union(&expect_mask, &next->expect_mask);
00362       bitmap_clear_all(&expect_field_type_mask);
00363       bitmap_union(&expect_field_type_mask, &next->expect_field_type_mask);
00364       bitmap_clear_all(&expect_field_result_mask);
00365       bitmap_union(&expect_field_result_mask, &next->expect_field_result_mask);
00366       collation= next->collation;
00367       next= next->next;
00368       delete expect_next;
00369     }
00370   }
00371   void expect(Item::Type type)
00372   {
00373     bitmap_set_bit(&expect_mask, (uint) type);
00374     if (type == Item::FIELD_ITEM)
00375       expect_all_field_types();
00376   }
00377   void dont_expect(Item::Type type)
00378   {
00379     bitmap_clear_bit(&expect_mask, (uint) type);
00380   }
00381   bool expecting(Item::Type type)
00382   {
00383     if (unlikely((uint)type > MAX_EXPECT_ITEMS))
00384     {
00385       // Unknown type, can't be expected
00386       return false;
00387     }
00388     return bitmap_is_set(&expect_mask, (uint) type);
00389   }
00390   void expect_nothing()
00391   {
00392     bitmap_clear_all(&expect_mask);
00393   }
00394   bool expecting_nothing()
00395   {
00396     return bitmap_is_clear_all(&expect_mask);
00397   }
00398   void expect_only(Item::Type type)
00399   {
00400     expect_nothing();
00401     expect(type);
00402   }
00403 
00404   void expect_field_type(enum_field_types type)
00405   {
00406     bitmap_set_bit(&expect_field_type_mask, (uint) type);
00407   }
00408   void expect_all_field_types()
00409   {
00410     bitmap_set_all(&expect_field_type_mask);
00411   }
00412   bool expecting_field_type(enum_field_types type)
00413   {
00414     if (unlikely((uint)type > MAX_EXPECT_FIELD_TYPES))
00415     {
00416       // Unknown type, can't be expected
00417       return false;
00418     }
00419     return bitmap_is_set(&expect_field_type_mask, (uint) type);
00420   }
00421   void expect_no_field_type()
00422   {
00423     bitmap_clear_all(&expect_field_type_mask);
00424   }
00425   bool expecting_no_field_type()
00426   {
00427     return bitmap_is_clear_all(&expect_field_type_mask);
00428   }
00429   void expect_only_field_type(enum_field_types result)
00430   {
00431     expect_no_field_type();
00432     expect_field_type(result);
00433   }
00434 
00435   void expect_field_result(Item_result result)
00436   {
00437     bitmap_set_bit(&expect_field_result_mask, (uint) result);
00438   }
00439   bool expecting_field_result(Item_result result)
00440   {
00441     if (unlikely((uint)result > MAX_EXPECT_FIELD_RESULTS))
00442     {
00443       // Unknown result, can't be expected
00444       return false;
00445     }
00446     return bitmap_is_set(&expect_field_result_mask,
00447                          (uint) result);
00448   }
00449   void expect_no_field_result()
00450   {
00451     bitmap_clear_all(&expect_field_result_mask);
00452   }
00453   bool expecting_no_field_result()
00454   {
00455     return bitmap_is_clear_all(&expect_field_result_mask);
00456   }
00457   void expect_only_field_result(Item_result result)
00458   {
00459     expect_no_field_result();
00460     expect_field_result(result);
00461   }
00462   void expect_collation(const CHARSET_INFO* col)
00463   {
00464     collation= col;
00465   }
00466   bool expecting_collation(const CHARSET_INFO* col)
00467   {
00468     bool matching= (!collation)
00469       ? true
00470       : (collation == col);
00471     collation= NULL;
00472 
00473     return matching;
00474   }
00475   void expect_length(Uint32 len)
00476   {
00477     length= len;
00478   }
00479   void expect_max_length(Uint32 max)
00480   {
00481     max_length= max;
00482   }
00483   bool expecting_length(Uint32 len)
00484   {
00485     return max_length == 0 || len <= max_length;
00486   }
00487   bool expecting_max_length(Uint32 max)
00488   {
00489     return max >= length;
00490   }
00491   void expect_no_length()
00492   {
00493     length= max_length= 0;
00494   }
00495 
00496 private:
00497   my_bitmap_map
00498     m_expect_buf[bitmap_buffer_size(MAX_EXPECT_ITEMS)];
00499   my_bitmap_map
00500     m_expect_field_type_buf[bitmap_buffer_size(MAX_EXPECT_FIELD_TYPES)];
00501   my_bitmap_map
00502     m_expect_field_result_buf[bitmap_buffer_size(MAX_EXPECT_FIELD_RESULTS)];
00503   MY_BITMAP expect_mask;
00504   MY_BITMAP expect_field_type_mask;
00505   MY_BITMAP expect_field_result_mask;
00506   const CHARSET_INFO* collation;
00507   Uint32 length;
00508   Uint32 max_length;
00509   Ndb_expect_stack* next;
00510 };
00511 
00512 class Ndb_rewrite_context : public Sql_alloc
00513 {
00514 public:
00515   Ndb_rewrite_context(Item_func *func) 
00516     : func_item(func), left_hand_item(NULL), count(0) {};
00517   ~Ndb_rewrite_context()
00518   {
00519     if (next) delete next;
00520   }
00521   const Item_func *func_item;
00522   const Item *left_hand_item;
00523   uint count;
00524   Ndb_rewrite_context *next;
00525 };
00526 
00527 /*
00528   This class is used for storing the context when traversing
00529   the Item tree. It stores a reference to the table the condition
00530   is defined on, the serialized representation being generated, 
00531   if the condition found is supported, and information what is
00532   expected next in the tree inorder for the condition to be supported.
00533 */
00534 class Ndb_cond_traverse_context : public Sql_alloc
00535 {
00536  public:
00537    Ndb_cond_traverse_context(TABLE *tab, const NdbDictionary::Table *ndb_tab,
00538                              Ndb_cond_stack* stack)
00539     : table(tab), ndb_table(ndb_tab), 
00540     supported(TRUE), cond_stack(stack), cond_ptr(NULL),
00541     skip(0), rewrite_stack(NULL)
00542   { 
00543    if (stack)
00544       cond_ptr= stack->ndb_cond;
00545   }
00546   ~Ndb_cond_traverse_context()
00547   {
00548     if (rewrite_stack) delete rewrite_stack;
00549   }
00550   inline void expect(Item::Type type)
00551   {
00552     expect_stack.expect(type);
00553   }
00554   inline void dont_expect(Item::Type type)
00555   {
00556     expect_stack.dont_expect(type);
00557   }
00558   inline bool expecting(Item::Type type)
00559   {
00560     return expect_stack.expecting(type);
00561   }
00562   inline void expect_nothing()
00563   {
00564     expect_stack.expect_nothing();
00565   }
00566   inline bool expecting_nothing()
00567   {
00568     return expect_stack.expecting_nothing();
00569   }
00570   inline void expect_only(Item::Type type)
00571   {
00572     expect_stack.expect_only(type);
00573   }
00574 
00575   inline void expect_field_type(enum_field_types type)
00576   {
00577     expect_stack.expect_field_type(type);
00578   }
00579   inline void expect_all_field_types()
00580   {
00581     expect_stack.expect_all_field_types();
00582   }
00583   inline bool expecting_field_type(enum_field_types type)
00584   {
00585     return expect_stack.expecting_field_type(type);
00586   }
00587   inline void expect_no_field_type()
00588   {
00589     expect_stack.expect_no_field_type();
00590   }
00591   inline bool expecting_no_field_type()
00592   {
00593     return expect_stack.expecting_no_field_type();
00594   }
00595   inline void expect_only_field_type(enum_field_types result)
00596   {
00597     expect_stack.expect_only_field_type(result);
00598   }
00599 
00600   inline void expect_field_result(Item_result result)
00601   {
00602     expect_stack.expect_field_result(result);
00603   }
00604   inline bool expecting_field_result(Item_result result)
00605   {
00606     return expect_stack.expecting_field_result(result);
00607   }
00608   inline void expect_no_field_result()
00609   {
00610     expect_stack.expect_no_field_result();
00611   }
00612   inline bool expecting_no_field_result()
00613   {
00614     return expect_stack.expecting_no_field_result();
00615   }
00616   inline void expect_only_field_result(Item_result result)
00617   {
00618     expect_stack.expect_only_field_result(result);
00619   }
00620   inline void expect_collation(const CHARSET_INFO* col)
00621   {
00622     expect_stack.expect_collation(col);
00623   }
00624   inline bool expecting_collation(const CHARSET_INFO* col)
00625   {
00626     return expect_stack.expecting_collation(col);
00627   }
00628   inline void expect_length(Uint32 length)
00629   {
00630     expect_stack.expect_length(length);
00631   }
00632   inline void expect_max_length(Uint32 max)
00633   {
00634     expect_stack.expect_max_length(max);
00635   }
00636   inline bool expecting_length(Uint32 length)
00637   {
00638     return expect_stack.expecting_length(length);
00639   }
00640   inline bool expecting_max_length(Uint32 max)
00641   {
00642     return expect_stack.expecting_max_length(max);
00643   }
00644   inline void expect_no_length()
00645   {
00646     expect_stack.expect_no_length();
00647   }
00648   
00649 
00650   TABLE* table;
00651   const NdbDictionary::Table *ndb_table;
00652   bool supported;
00653   Ndb_cond_stack* cond_stack;
00654   Ndb_cond* cond_ptr;
00655   Ndb_expect_stack expect_stack;
00656   uint skip;
00657   Ndb_rewrite_context *rewrite_stack;
00658 };
00659 
00660 class ha_ndbcluster;
00661 
00662 class ha_ndbcluster_cond
00663 {
00664 public:
00665   ha_ndbcluster_cond() 
00666   : m_cond_stack(NULL)
00667   {}
00668   ~ha_ndbcluster_cond() 
00669   { if (m_cond_stack) delete m_cond_stack; }
00670   const Item *cond_push(const Item *cond, 
00671                         TABLE *table, const NdbDictionary::Table *ndb_table);
00672   void cond_pop();
00673   void cond_clear();
00674   int generate_scan_filter(NdbInterpretedCode* code, 
00675                            NdbScanOperation::ScanOptions* options);
00676   int generate_scan_filter_from_cond(NdbScanFilter& filter);
00677   int generate_scan_filter_from_key(NdbInterpretedCode* code,
00678                                     NdbScanOperation::ScanOptions* options,
00679                                     const KEY* key_info, 
00680                                     const key_range *start_key,
00681                                     const key_range *end_key,
00682                                     uchar *buf);
00683 private:
00684   bool serialize_cond(const Item *cond, Ndb_cond_stack *ndb_cond,
00685                       TABLE *table, const NdbDictionary::Table *ndb_table);
00686   int build_scan_filter_predicate(Ndb_cond* &cond, 
00687                                   NdbScanFilter* filter,
00688                                   bool negated= false);
00689   int build_scan_filter_group(Ndb_cond* &cond, 
00690                               NdbScanFilter* filter);
00691   int build_scan_filter(Ndb_cond* &cond, NdbScanFilter* filter);
00692 
00693   Ndb_cond_stack *m_cond_stack;
00694 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines