~ubuntu-branches/ubuntu/trusty/mysql-5.6/trusty

« back to all changes in this revision

Viewing changes to sql/ha_ndbcluster_cond.h

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-02-12 11:54:27 UTC
  • Revision ID: package-import@ubuntu.com-20140212115427-oq6tfsqxl1wuwehi
Tags: upstream-5.6.15
ImportĀ upstreamĀ versionĀ 5.6.15

Show diffs side-by-side

added added

removed removed

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