1 /*
2    Copyright (c) 2000, 2021, Oracle and/or its affiliates.
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 /*
26   This file defines the data structures used by engine condition pushdown in
27   the NDB Cluster handler
28 */
29 
30 typedef enum ndb_item_type {
31   NDB_VALUE = 0,   // Qualified more with Item::Type
32   NDB_FIELD = 1,   // Qualified from table definition
33   NDB_FUNCTION = 2,// Qualified from Item_func::Functype
34   NDB_END_COND = 3 // End marker for condition group
35 } NDB_ITEM_TYPE;
36 
37 typedef enum ndb_func_type {
38   NDB_EQ_FUNC = 0,
39   NDB_NE_FUNC = 1,
40   NDB_LT_FUNC = 2,
41   NDB_LE_FUNC = 3,
42   NDB_GT_FUNC = 4,
43   NDB_GE_FUNC = 5,
44   NDB_ISNULL_FUNC = 6,
45   NDB_ISNOTNULL_FUNC = 7,
46   NDB_LIKE_FUNC = 8,
47   NDB_NOTLIKE_FUNC = 9,
48   NDB_NOT_FUNC = 10,
49   NDB_UNKNOWN_FUNC = 11,
50   NDB_COND_AND_FUNC = 12,
51   NDB_COND_OR_FUNC = 13,
52   NDB_UNSUPPORTED_FUNC = 14
53 } NDB_FUNC_TYPE;
54 
55 typedef union ndb_item_qualification {
56   Item::Type value_type;
57   enum_field_types field_type; // Instead of Item::FIELD_ITEM
58   NDB_FUNC_TYPE function_type; // Instead of Item::FUNC_ITEM
59 } NDB_ITEM_QUALIFICATION;
60 
61 typedef struct ndb_item_field_value {
62   Field* field;
63   int column_no;
64 } NDB_ITEM_FIELD_VALUE;
65 
66 typedef union ndb_item_value {
67   const Item *item;
68   NDB_ITEM_FIELD_VALUE *field_value;
69   uint arg_count;
70 } NDB_ITEM_VALUE;
71 
72 struct negated_function_mapping
73 {
74   NDB_FUNC_TYPE pos_fun;
75   NDB_FUNC_TYPE neg_fun;
76 };
77 
78 /*
79   Define what functions can be negated in condition pushdown.
80   Note, these HAVE to be in the same order as in definition enum
81 */
82 static const negated_function_mapping neg_map[]=
83 {
84   {NDB_EQ_FUNC, NDB_NE_FUNC},
85   {NDB_NE_FUNC, NDB_EQ_FUNC},
86   {NDB_LT_FUNC, NDB_GE_FUNC},
87   {NDB_LE_FUNC, NDB_GT_FUNC},
88   {NDB_GT_FUNC, NDB_LE_FUNC},
89   {NDB_GE_FUNC, NDB_LT_FUNC},
90   {NDB_ISNULL_FUNC, NDB_ISNOTNULL_FUNC},
91   {NDB_ISNOTNULL_FUNC, NDB_ISNULL_FUNC},
92   {NDB_LIKE_FUNC, NDB_NOTLIKE_FUNC},
93   {NDB_NOTLIKE_FUNC, NDB_LIKE_FUNC},
94   {NDB_NOT_FUNC, NDB_UNSUPPORTED_FUNC},
95   {NDB_UNKNOWN_FUNC, NDB_UNSUPPORTED_FUNC},
96   {NDB_COND_AND_FUNC, NDB_UNSUPPORTED_FUNC},
97   {NDB_COND_OR_FUNC, NDB_UNSUPPORTED_FUNC},
98   {NDB_UNSUPPORTED_FUNC, NDB_UNSUPPORTED_FUNC}
99 };
100 
101 /*
102   This class is the construction element for serialization of Item tree
103   in condition pushdown.
104   An instance of Ndb_Item represents a constant, table field reference,
105   unary or binary comparison predicate, and start/end of AND/OR.
106   Instances of Ndb_Item are stored in a linked list implemented by Ndb_cond
107   class.
108   The order of elements produced by Ndb_cond::next corresponds to
109   breadth-first traversal of the Item (i.e. expression) tree in prefix order.
110   AND and OR have arbitrary arity, so the end of AND/OR group is marked with
111   Ndb_item with type == NDB_END_COND.
112   NOT items represent negated conditions and generate NAND/NOR groups.
113 */
114 class Ndb_item : public Sql_alloc
115 {
116 public:
Ndb_item(NDB_ITEM_TYPE item_type)117   Ndb_item(NDB_ITEM_TYPE item_type) : type(item_type) {}
Ndb_item(NDB_ITEM_TYPE item_type,NDB_ITEM_QUALIFICATION item_qualification,const Item * item_value)118   Ndb_item(NDB_ITEM_TYPE item_type,
119            NDB_ITEM_QUALIFICATION item_qualification,
120            const Item *item_value)
121     : type(item_type), qualification(item_qualification)
122   {
123     switch(item_type) {
124     case(NDB_VALUE):
125       value.item= item_value;
126       break;
127     case(NDB_FIELD): {
128       NDB_ITEM_FIELD_VALUE *field_value= new NDB_ITEM_FIELD_VALUE();
129       Item_field *field_item= (Item_field *) item_value;
130       field_value->field= field_item->field;
131       field_value->column_no= -1; // Will be fetched at scan filter generation
132       value.field_value= field_value;
133       break;
134     }
135     case(NDB_FUNCTION):
136       value.item= item_value;
137       value.arg_count= ((Item_func *) item_value)->argument_count();
138       break;
139     case(NDB_END_COND):
140       break;
141     }
142   }
Ndb_item(Field * field,int column_no)143   Ndb_item(Field *field, int column_no) : type(NDB_FIELD)
144   {
145     NDB_ITEM_FIELD_VALUE *field_value= new NDB_ITEM_FIELD_VALUE();
146     qualification.field_type= field->real_type();
147     field_value->field= field;
148     field_value->column_no= column_no;
149     value.field_value= field_value;
150   }
Ndb_item(Item_func::Functype func_type,const Item * item_value)151   Ndb_item(Item_func::Functype func_type, const Item *item_value)
152     : type(NDB_FUNCTION)
153   {
154     qualification.function_type= item_func_to_ndb_func(func_type);
155     value.item= item_value;
156     value.arg_count= ((Item_func *) item_value)->argument_count();
157   }
Ndb_item(Item_func::Functype func_type,uint no_args)158   Ndb_item(Item_func::Functype func_type, uint no_args)
159     : type(NDB_FUNCTION)
160   {
161     qualification.function_type= item_func_to_ndb_func(func_type);
162     value.arg_count= no_args;
163   }
~Ndb_item()164   ~Ndb_item()
165   {
166     if (type == NDB_FIELD)
167       {
168         delete value.field_value;
169         value.field_value= NULL;
170       }
171   }
172 
pack_length()173   uint32 pack_length()
174   {
175     switch(type) {
176     case(NDB_VALUE):
177       if(qualification.value_type == Item::STRING_ITEM)
178         return value.item->str_value.length();
179       break;
180     case(NDB_FIELD):
181       return value.field_value->field->pack_length();
182     default:
183       break;
184     }
185 
186     return 0;
187   }
188 
get_field()189   Field * get_field() { return value.field_value->field; }
190 
get_field_no()191   int get_field_no() { return value.field_value->column_no; }
192 
argument_count()193   int argument_count()
194   {
195     return value.arg_count;
196   }
197 
get_val()198   const char* get_val()
199   {
200     switch(type) {
201     case(NDB_VALUE):
202       if(qualification.value_type == Item::STRING_ITEM)
203         return value.item->str_value.ptr();
204       break;
205     case(NDB_FIELD):
206       return (char*) value.field_value->field->ptr;
207     case(NDB_FUNCTION):
208       if(qualification.value_type == Item::STRING_ITEM)
209         return value.item->str_value.ptr();
210     default:
211       break;
212     }
213 
214     return NULL;
215   }
216 
get_field_charset()217   const CHARSET_INFO *get_field_charset()
218   {
219     Field *field= get_field();
220     if (field)
221       return field->charset();
222 
223     return NULL;
224   }
225 
get_field_val_str(String * str)226   String *get_field_val_str(String *str)
227   {
228     Field *field= get_field();
229     if (field)
230       return field->val_str(str);
231 
232     return NULL;
233   }
234 
is_const_func()235   bool is_const_func()
236   {
237     const Item *item= value.item;
238 
239     if (item->type() == Item::FUNC_ITEM)
240     {
241       Item_func *func_item= (Item_func *) item;
242       if (func_item->const_item())
243         return true;
244     }
245     return false;
246   }
247 
is_cached()248   bool is_cached()
249   {
250     const Item *item= value.item;
251 
252     return (item->type() == Item::CACHE_ITEM);
253   }
254 
255 
save_in_field(Ndb_item * field_item)256   uint32 save_in_field(Ndb_item *field_item)
257   {
258     uint32 length= 0;
259     DBUG_ENTER("save_in_field");
260     Field *field = field_item->value.field_value->field;
261     const Item *item= value.item;
262     if (item && field)
263     {
264       length= item->max_length;
265       my_bitmap_map *old_map=
266         dbug_tmp_use_all_columns(field->table, field->table->write_set);
267       ((Item *)item)->save_in_field(field, false);
268       dbug_tmp_restore_column_map(field->table->write_set, old_map);
269     }
270     DBUG_RETURN(length);
271   }
272 
item_func_to_ndb_func(Item_func::Functype fun)273   static NDB_FUNC_TYPE item_func_to_ndb_func(Item_func::Functype fun)
274   {
275     switch (fun) {
276     case (Item_func::EQ_FUNC): { return NDB_EQ_FUNC; }
277     case (Item_func::NE_FUNC): { return NDB_NE_FUNC; }
278     case (Item_func::LT_FUNC): { return NDB_LT_FUNC; }
279     case (Item_func::LE_FUNC): { return NDB_LE_FUNC; }
280     case (Item_func::GT_FUNC): { return NDB_GT_FUNC; }
281     case (Item_func::GE_FUNC): { return NDB_GE_FUNC; }
282     case (Item_func::ISNULL_FUNC): { return NDB_ISNULL_FUNC; }
283     case (Item_func::ISNOTNULL_FUNC): { return NDB_ISNOTNULL_FUNC; }
284     case (Item_func::LIKE_FUNC): { return NDB_LIKE_FUNC; }
285     case (Item_func::NOT_FUNC): { return NDB_NOT_FUNC; }
286     case (Item_func::NEG_FUNC): { return NDB_UNKNOWN_FUNC; }
287     case (Item_func::UNKNOWN_FUNC): { return NDB_UNKNOWN_FUNC; }
288     case (Item_func::COND_AND_FUNC): { return NDB_COND_AND_FUNC; }
289     case (Item_func::COND_OR_FUNC): { return NDB_COND_OR_FUNC; }
290     default: { return NDB_UNSUPPORTED_FUNC; }
291     }
292   }
293 
negate(NDB_FUNC_TYPE fun)294   static NDB_FUNC_TYPE negate(NDB_FUNC_TYPE fun)
295   {
296     uint i= (uint) fun;
297     assert(fun == neg_map[i].pos_fun);
298     return  neg_map[i].neg_fun;
299   }
300 
301   NDB_ITEM_TYPE type;
302   NDB_ITEM_QUALIFICATION qualification;
303  private:
304   NDB_ITEM_VALUE value;
305 };
306 
307 /*
308   This class implements a linked list used for storing a
309   serialization of the Item tree for condition pushdown.
310  */
311 class Ndb_cond : public Sql_alloc
312 {
313  public:
Ndb_cond()314   Ndb_cond() : ndb_item(NULL), next(NULL), prev(NULL) {}
~Ndb_cond()315   ~Ndb_cond()
316   {
317     if (ndb_item) delete ndb_item;
318     ndb_item= NULL;
319     /*
320       First item in the linked list deletes all in a loop
321       Note - doing it recursively causes stack issues for
322       big IN clauses
323     */
324     Ndb_cond *n= next;
325     while (n)
326     {
327       Ndb_cond *tmp= n;
328       n= n->next;
329       tmp->next= NULL;
330       delete tmp;
331     }
332     next= prev= NULL;
333   }
334   Ndb_item *ndb_item;
335   Ndb_cond *next;
336   Ndb_cond *prev;
337 };
338 
339 /*
340   This class implements a stack for storing several conditions
341   for pushdown (represented as serialized Item trees using Ndb_cond).
342   The current implementation only pushes one condition, but is
343   prepared for handling several (C1 AND C2 ...) if the logic for
344   pushing conditions is extended in sql_select.
345 */
346 class Ndb_cond_stack : public Sql_alloc
347 {
348  public:
Ndb_cond_stack()349   Ndb_cond_stack() : ndb_cond(NULL), next(NULL) {}
~Ndb_cond_stack()350   ~Ndb_cond_stack()
351   {
352     if (ndb_cond) delete ndb_cond;
353     ndb_cond= NULL;
354     if (next) delete next;
355     next= NULL;
356   }
357   Ndb_cond *ndb_cond;
358   Ndb_cond_stack *next;
359 };
360 
361 /*
362   This class implements look-ahead during the parsing
363   of the item tree. It contains bit masks for expected
364   items, field types and field results. It also contains
365   expected collation. The parse context (Ndb_cond_traverse_context)
366   always contains one expect_stack instance (top of the stack).
367   More expects (deeper look-ahead) can be pushed to the expect_stack
368   to check specific order (currently used for detecting support for
369   <field> LIKE <string>|<func>, but not <string>|<func> LIKE <field>).
370  */
371 class Ndb_expect_stack : public Sql_alloc
372 {
373   static const uint MAX_EXPECT_ITEMS = Item::VIEW_FIXER_ITEM + 1;
374   static const uint MAX_EXPECT_FIELD_TYPES = MYSQL_TYPE_GEOMETRY + 1;
375   static const uint MAX_EXPECT_FIELD_RESULTS = DECIMAL_RESULT + 1;
376  public:
Ndb_expect_stack()377 Ndb_expect_stack(): collation(NULL), length(0), max_length(0), next(NULL)
378   {
379     // Allocate type checking bitmaps using fixed size buffers
380     // since max size is known at compile time
381     bitmap_init(&expect_mask, m_expect_buf,
382                 MAX_EXPECT_ITEMS, FALSE);
383     bitmap_init(&expect_field_type_mask, m_expect_field_type_buf,
384                 MAX_EXPECT_FIELD_TYPES, FALSE);
385     bitmap_init(&expect_field_result_mask, m_expect_field_result_buf,
386                 MAX_EXPECT_FIELD_RESULTS, FALSE);
387   }
~Ndb_expect_stack()388   ~Ndb_expect_stack()
389   {
390     if (next)
391       delete next;
392     next= NULL;
393   }
push(Ndb_expect_stack * expect_next)394   void push(Ndb_expect_stack* expect_next)
395   {
396     next= expect_next;
397   }
pop()398   void pop()
399   {
400     if (next)
401     {
402       Ndb_expect_stack* expect_next= next;
403       bitmap_clear_all(&expect_mask);
404       bitmap_union(&expect_mask, &next->expect_mask);
405       bitmap_clear_all(&expect_field_type_mask);
406       bitmap_union(&expect_field_type_mask, &next->expect_field_type_mask);
407       bitmap_clear_all(&expect_field_result_mask);
408       bitmap_union(&expect_field_result_mask, &next->expect_field_result_mask);
409       collation= next->collation;
410       next= next->next;
411       delete expect_next;
412     }
413   }
expect(Item::Type type)414   void expect(Item::Type type)
415   {
416     bitmap_set_bit(&expect_mask, (uint) type);
417     if (type == Item::FIELD_ITEM)
418       expect_all_field_types();
419   }
dont_expect(Item::Type type)420   void dont_expect(Item::Type type)
421   {
422     bitmap_clear_bit(&expect_mask, (uint) type);
423   }
expecting(Item::Type type)424   bool expecting(Item::Type type)
425   {
426     if (unlikely((uint)type > MAX_EXPECT_ITEMS))
427     {
428       // Unknown type, can't be expected
429       return false;
430     }
431     return bitmap_is_set(&expect_mask, (uint) type);
432   }
expect_nothing()433   void expect_nothing()
434   {
435     bitmap_clear_all(&expect_mask);
436   }
expecting_nothing()437   bool expecting_nothing()
438   {
439     return bitmap_is_clear_all(&expect_mask);
440   }
expect_only(Item::Type type)441   void expect_only(Item::Type type)
442   {
443     expect_nothing();
444     expect(type);
445   }
446 
expect_field_type(enum_field_types type)447   void expect_field_type(enum_field_types type)
448   {
449     bitmap_set_bit(&expect_field_type_mask, (uint) type);
450   }
expect_all_field_types()451   void expect_all_field_types()
452   {
453     bitmap_set_all(&expect_field_type_mask);
454   }
expecting_field_type(enum_field_types type)455   bool expecting_field_type(enum_field_types type)
456   {
457     if (unlikely((uint)type > MAX_EXPECT_FIELD_TYPES))
458     {
459       // Unknown type, can't be expected
460       return false;
461     }
462     return bitmap_is_set(&expect_field_type_mask, (uint) type);
463   }
expect_no_field_type()464   void expect_no_field_type()
465   {
466     bitmap_clear_all(&expect_field_type_mask);
467   }
expecting_no_field_type()468   bool expecting_no_field_type()
469   {
470     return bitmap_is_clear_all(&expect_field_type_mask);
471   }
expect_only_field_type(enum_field_types result)472   void expect_only_field_type(enum_field_types result)
473   {
474     expect_no_field_type();
475     expect_field_type(result);
476   }
477 
expect_field_result(Item_result result)478   void expect_field_result(Item_result result)
479   {
480     bitmap_set_bit(&expect_field_result_mask, (uint) result);
481   }
expecting_field_result(Item_result result)482   bool expecting_field_result(Item_result result)
483   {
484     if (unlikely((uint)result > MAX_EXPECT_FIELD_RESULTS))
485     {
486       // Unknown result, can't be expected
487       return false;
488     }
489     return bitmap_is_set(&expect_field_result_mask,
490                          (uint) result);
491   }
expect_no_field_result()492   void expect_no_field_result()
493   {
494     bitmap_clear_all(&expect_field_result_mask);
495   }
expecting_no_field_result()496   bool expecting_no_field_result()
497   {
498     return bitmap_is_clear_all(&expect_field_result_mask);
499   }
expect_only_field_result(Item_result result)500   void expect_only_field_result(Item_result result)
501   {
502     expect_no_field_result();
503     expect_field_result(result);
504   }
expect_collation(const CHARSET_INFO * col)505   void expect_collation(const CHARSET_INFO* col)
506   {
507     collation= col;
508   }
expecting_collation(const CHARSET_INFO * col)509   bool expecting_collation(const CHARSET_INFO* col)
510   {
511     bool matching= (!collation)
512       ? true
513       : (collation == col);
514     collation= NULL;
515 
516     return matching;
517   }
expect_length(Uint32 len)518   void expect_length(Uint32 len)
519   {
520     length= len;
521   }
expect_max_length(Uint32 max)522   void expect_max_length(Uint32 max)
523   {
524     max_length= max;
525   }
expecting_length(Uint32 len)526   bool expecting_length(Uint32 len)
527   {
528     return max_length == 0 || len <= max_length;
529   }
expecting_max_length(Uint32 max)530   bool expecting_max_length(Uint32 max)
531   {
532     return max >= length;
533   }
expect_no_length()534   void expect_no_length()
535   {
536     length= max_length= 0;
537   }
538 
539 private:
540   my_bitmap_map
541     m_expect_buf[bitmap_buffer_size(MAX_EXPECT_ITEMS)];
542   my_bitmap_map
543     m_expect_field_type_buf[bitmap_buffer_size(MAX_EXPECT_FIELD_TYPES)];
544   my_bitmap_map
545     m_expect_field_result_buf[bitmap_buffer_size(MAX_EXPECT_FIELD_RESULTS)];
546   MY_BITMAP expect_mask;
547   MY_BITMAP expect_field_type_mask;
548   MY_BITMAP expect_field_result_mask;
549   const CHARSET_INFO* collation;
550   Uint32 length;
551   Uint32 max_length;
552   Ndb_expect_stack* next;
553 };
554 
555 class Ndb_rewrite_context : public Sql_alloc
556 {
557 public:
Ndb_rewrite_context(Item_func * func)558   Ndb_rewrite_context(Item_func *func)
559     : func_item(func), left_hand_item(NULL), count(0) {}
~Ndb_rewrite_context()560   ~Ndb_rewrite_context()
561   {
562     if (next) delete next;
563   }
564   const Item_func *func_item;
565   const Item *left_hand_item;
566   uint count;
567   Ndb_rewrite_context *next;
568 };
569 
570 /*
571   This class is used for storing the context when traversing
572   the Item tree. It stores a reference to the table the condition
573   is defined on, the serialized representation being generated,
574   if the condition found is supported, and information what is
575   expected next in the tree inorder for the condition to be supported.
576 */
577 class Ndb_cond_traverse_context : public Sql_alloc
578 {
579  public:
Ndb_cond_traverse_context(TABLE * tab,const NdbDictionary::Table * ndb_tab,Ndb_cond_stack * stack)580    Ndb_cond_traverse_context(TABLE *tab, const NdbDictionary::Table *ndb_tab,
581 			     Ndb_cond_stack* stack)
582     : table(tab), ndb_table(ndb_tab),
583     supported(TRUE), cond_stack(stack), cond_ptr(NULL),
584     skip(0), rewrite_stack(NULL)
585   {
586    if (stack)
587       cond_ptr= stack->ndb_cond;
588   }
~Ndb_cond_traverse_context()589   ~Ndb_cond_traverse_context()
590   {
591     if (rewrite_stack) delete rewrite_stack;
592   }
expect(Item::Type type)593   inline void expect(Item::Type type)
594   {
595     expect_stack.expect(type);
596   }
dont_expect(Item::Type type)597   inline void dont_expect(Item::Type type)
598   {
599     expect_stack.dont_expect(type);
600   }
expecting(Item::Type type)601   inline bool expecting(Item::Type type)
602   {
603     return expect_stack.expecting(type);
604   }
expect_nothing()605   inline void expect_nothing()
606   {
607     expect_stack.expect_nothing();
608   }
expecting_nothing()609   inline bool expecting_nothing()
610   {
611     return expect_stack.expecting_nothing();
612   }
expect_only(Item::Type type)613   inline void expect_only(Item::Type type)
614   {
615     expect_stack.expect_only(type);
616   }
617 
expect_field_type(enum_field_types type)618   inline void expect_field_type(enum_field_types type)
619   {
620     expect_stack.expect_field_type(type);
621   }
expect_all_field_types()622   inline void expect_all_field_types()
623   {
624     expect_stack.expect_all_field_types();
625   }
expecting_field_type(enum_field_types type)626   inline bool expecting_field_type(enum_field_types type)
627   {
628     return expect_stack.expecting_field_type(type);
629   }
expect_no_field_type()630   inline void expect_no_field_type()
631   {
632     expect_stack.expect_no_field_type();
633   }
expecting_no_field_type()634   inline bool expecting_no_field_type()
635   {
636     return expect_stack.expecting_no_field_type();
637   }
expect_only_field_type(enum_field_types result)638   inline void expect_only_field_type(enum_field_types result)
639   {
640     expect_stack.expect_only_field_type(result);
641   }
642 
expect_field_result(Item_result result)643   inline void expect_field_result(Item_result result)
644   {
645     expect_stack.expect_field_result(result);
646   }
expecting_field_result(Item_result result)647   inline bool expecting_field_result(Item_result result)
648   {
649     return expect_stack.expecting_field_result(result);
650   }
expect_no_field_result()651   inline void expect_no_field_result()
652   {
653     expect_stack.expect_no_field_result();
654   }
expecting_no_field_result()655   inline bool expecting_no_field_result()
656   {
657     return expect_stack.expecting_no_field_result();
658   }
expect_only_field_result(Item_result result)659   inline void expect_only_field_result(Item_result result)
660   {
661     expect_stack.expect_only_field_result(result);
662   }
expect_collation(const CHARSET_INFO * col)663   inline void expect_collation(const CHARSET_INFO* col)
664   {
665     expect_stack.expect_collation(col);
666   }
expecting_collation(const CHARSET_INFO * col)667   inline bool expecting_collation(const CHARSET_INFO* col)
668   {
669     return expect_stack.expecting_collation(col);
670   }
expect_length(Uint32 length)671   inline void expect_length(Uint32 length)
672   {
673     expect_stack.expect_length(length);
674   }
expect_max_length(Uint32 max)675   inline void expect_max_length(Uint32 max)
676   {
677     expect_stack.expect_max_length(max);
678   }
expecting_length(Uint32 length)679   inline bool expecting_length(Uint32 length)
680   {
681     return expect_stack.expecting_length(length);
682   }
expecting_max_length(Uint32 max)683   inline bool expecting_max_length(Uint32 max)
684   {
685     return expect_stack.expecting_max_length(max);
686   }
expect_no_length()687   inline void expect_no_length()
688   {
689     expect_stack.expect_no_length();
690   }
691 
692 
693   TABLE* table;
694   const NdbDictionary::Table *ndb_table;
695   bool supported;
696   Ndb_cond_stack* cond_stack;
697   Ndb_cond* cond_ptr;
698   Ndb_expect_stack expect_stack;
699   uint skip;
700   Ndb_rewrite_context *rewrite_stack;
701 };
702 
703 class ha_ndbcluster;
704 
705 class ha_ndbcluster_cond
706 {
707 public:
ha_ndbcluster_cond()708   ha_ndbcluster_cond()
709   : m_cond_stack(NULL)
710   {}
~ha_ndbcluster_cond()711   ~ha_ndbcluster_cond()
712   { if (m_cond_stack) delete m_cond_stack; }
713   const Item *cond_push(const Item *cond,
714                         TABLE *table, const NdbDictionary::Table *ndb_table);
715   void cond_pop();
716   void cond_clear();
717   int generate_scan_filter(NdbInterpretedCode* code,
718                            NdbScanOperation::ScanOptions* options) const;
719   int generate_scan_filter_from_cond(NdbScanFilter& filter) const;
720   int generate_scan_filter_from_key(NdbInterpretedCode* code,
721                                     NdbScanOperation::ScanOptions* options,
722                                     const KEY* key_info,
723                                     const key_range *start_key,
724                                     const key_range *end_key) const;
725 private:
726   bool serialize_cond(const Item *cond, Ndb_cond_stack *ndb_cond,
727                       TABLE *table,
728                       const NdbDictionary::Table *ndb_table) const;
729   int build_scan_filter_predicate(Ndb_cond* &cond,
730                                   NdbScanFilter* filter,
731                                   bool negated= false) const;
732   int build_scan_filter_group(Ndb_cond* &cond,
733                               NdbScanFilter* filter) const;
734   int build_scan_filter(Ndb_cond* &cond, NdbScanFilter* filter) const;
735 
736   Ndb_cond_stack *m_cond_stack;
737 };
738