MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ha_ndbcluster_cond.cc
1 /*
2  Copyright (C) 2000-2003 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 NDB Cluster handler engine_condition_pushdown
21 */
22 
23 #include "ha_ndbcluster_glue.h"
24 
25 #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
26 #include <ndbapi/NdbApi.hpp>
27 #include "ha_ndbcluster_cond.h"
28 
29 // Typedefs for long names
32 
33 /*
34  Serialize the item tree into a linked list represented by Ndb_cond
35  for fast generation of NbdScanFilter. Adds information such as
36  position of fields that is not directly available in the Item tree.
37  Also checks if condition is supported.
38 */
39 static void
40 ndb_serialize_cond(const Item *item, void *arg)
41 {
43  DBUG_ENTER("ndb_serialize_cond");
44 
45  // Check if we are skipping arguments to a function to be evaluated
46  if (context->skip)
47  {
48  if (!item)
49  {
50  DBUG_PRINT("info", ("Unexpected mismatch of found and expected number of function arguments %u", context->skip));
51  sql_print_error("ndb_serialize_cond: Unexpected mismatch of found and "
52  "expected number of function arguments %u", context->skip);
53  context->skip= 0;
54  DBUG_VOID_RETURN;
55  }
56  DBUG_PRINT("info", ("Skiping argument %d", context->skip));
57  context->skip--;
58  switch (item->type()) {
59  case Item::FUNC_ITEM:
60  {
61  Item_func *func_item= (Item_func *) item;
62  context->skip+= func_item->argument_count();
63  break;
64  }
65  case Item::INT_ITEM:
66  case Item::REAL_ITEM:
67  case Item::STRING_ITEM:
68  case Item::VARBIN_ITEM:
69  case Item::DECIMAL_ITEM:
70  break;
71  default:
72  context->supported= FALSE;
73  break;
74  }
75 
76  DBUG_VOID_RETURN;
77  }
78 
79  if (context->supported)
80  {
81  Ndb_rewrite_context *rewrite_context2= context->rewrite_stack;
82  const Item_func *rewrite_func_item;
83  // Check if we are rewriting some unsupported function call
84  if (rewrite_context2 &&
85  (rewrite_func_item= rewrite_context2->func_item) &&
86  rewrite_context2->count++ == 0)
87  {
88  switch (rewrite_func_item->functype()) {
89  case Item_func::BETWEEN:
90  /*
91  Rewrite
92  <field>|<const> BETWEEN <const1>|<field1> AND <const2>|<field2>
93  to <field>|<const> > <const1>|<field1> AND
94  <field>|<const> < <const2>|<field2>
95  or actually in prefix format
96  BEGIN(AND) GT(<field>|<const>, <const1>|<field1>),
97  LT(<field>|<const>, <const2>|<field2>), END()
98  */
99  case Item_func::IN_FUNC:
100  {
101  /*
102  Rewrite <field>|<const> IN(<const1>|<field1>, <const2>|<field2>,..)
103  to <field>|<const> = <const1>|<field1> OR
104  <field> = <const2>|<field2> ...
105  or actually in prefix format
106  BEGIN(OR) EQ(<field>|<const>, <const1><field1>),
107  EQ(<field>|<const>, <const2>|<field2>), ... END()
108  Each part of the disjunction is added for each call
109  to ndb_serialize_cond and end of rewrite statement
110  is wrapped in end of ndb_serialize_cond
111  */
112  if (context->expecting(item->type()))
113  {
114  // This is the <field>|<const> item, save it in the rewrite context
115  rewrite_context2->left_hand_item= item;
116  if (item->type() == Item::FUNC_ITEM)
117  {
118  Item_func *func_item= (Item_func *) item;
119  if ((func_item->functype() == Item_func::UNKNOWN_FUNC ||
120  func_item->functype() == Item_func::NEG_FUNC) &&
121  func_item->const_item())
122  {
123  // Skip any arguments since we will evaluate function instead
124  DBUG_PRINT("info", ("Skip until end of arguments marker"));
125  context->skip= func_item->argument_count();
126  }
127  else
128  {
129  DBUG_PRINT("info", ("Found unsupported functional expression in BETWEEN|IN"));
130  context->supported= FALSE;
131  DBUG_VOID_RETURN;
132 
133  }
134  }
135  }
136  else
137  {
138  // Non-supported BETWEEN|IN expression
139  DBUG_PRINT("info", ("Found unexpected item of type %u in BETWEEN|IN",
140  item->type()));
141  context->supported= FALSE;
142  DBUG_VOID_RETURN;
143  }
144  break;
145  }
146  default:
147  context->supported= FALSE;
148  break;
149  }
150  DBUG_VOID_RETURN;
151  }
152  else
153  {
154  Ndb_cond_stack *ndb_stack= context->cond_stack;
155  Ndb_cond *prev_cond= context->cond_ptr;
156  Ndb_cond *curr_cond= context->cond_ptr= new Ndb_cond();
157  if (!ndb_stack->ndb_cond)
158  ndb_stack->ndb_cond= curr_cond;
159  curr_cond->prev= prev_cond;
160  if (prev_cond) prev_cond->next= curr_cond;
161  // Check if we are rewriting some unsupported function call
162  if (context->rewrite_stack)
163  {
164  Ndb_rewrite_context *rewrite_context= context->rewrite_stack;
165  const Item_func *func_item= rewrite_context->func_item;
166  switch (func_item->functype()) {
167  case Item_func::BETWEEN:
168  {
169  /*
170  Rewrite
171  <field>|<const> BETWEEN <const1>|<field1> AND <const2>|<field2>
172  to <field>|<const> > <const1>|<field1> AND
173  <field>|<const> < <const2>|<field2>
174  or actually in prefix format
175  BEGIN(AND) GT(<field>|<const>, <const1>|<field1>),
176  LT(<field>|<const>, <const2>|<field2>), END()
177  */
178  if (rewrite_context->count == 2)
179  {
180  // Lower limit of BETWEEN
181  DBUG_PRINT("info", ("GE_FUNC"));
182  curr_cond->ndb_item= new Ndb_item(Item_func::GE_FUNC, 2);
183  }
184  else if (rewrite_context->count == 3)
185  {
186  // Upper limit of BETWEEN
187  DBUG_PRINT("info", ("LE_FUNC"));
188  curr_cond->ndb_item= new Ndb_item(Item_func::LE_FUNC, 2);
189  }
190  else
191  {
192  // Illegal BETWEEN expression
193  DBUG_PRINT("info", ("Illegal BETWEEN expression"));
194  context->supported= FALSE;
195  DBUG_VOID_RETURN;
196  }
197  break;
198  }
199  case Item_func::IN_FUNC:
200  {
201  /*
202  Rewrite <field>|<const> IN(<const1>|<field1>, <const2>|<field2>,..)
203  to <field>|<const> = <const1>|<field1> OR
204  <field> = <const2>|<field2> ...
205  or actually in prefix format
206  BEGIN(OR) EQ(<field>|<const>, <const1><field1>),
207  EQ(<field>|<const>, <const2>|<field2>), ... END()
208  Each part of the disjunction is added for each call
209  to ndb_serialize_cond and end of rewrite statement
210  is wrapped in end of ndb_serialize_cond
211  */
212  DBUG_PRINT("info", ("EQ_FUNC"));
213  curr_cond->ndb_item= new Ndb_item(Item_func::EQ_FUNC, 2);
214  break;
215  }
216  default:
217  context->supported= FALSE;
218  }
219  // Handle left hand <field>|<const>
220  context->rewrite_stack= NULL; // Disable rewrite mode
221  context->expect_only(Item::FIELD_ITEM);
222  context->expect_field_result(STRING_RESULT);
223  context->expect_field_result(REAL_RESULT);
224  context->expect_field_result(INT_RESULT);
225  context->expect_field_result(DECIMAL_RESULT);
226  context->expect(Item::INT_ITEM);
227  context->expect(Item::STRING_ITEM);
228  context->expect(Item::VARBIN_ITEM);
229  context->expect(Item::FUNC_ITEM);
230  context->expect(Item::CACHE_ITEM);
231  ndb_serialize_cond(rewrite_context->left_hand_item, arg);
232  context->skip= 0; // Any FUNC_ITEM expression has already been parsed
233  context->rewrite_stack= rewrite_context; // Enable rewrite mode
234  if (!context->supported)
235  DBUG_VOID_RETURN;
236 
237  prev_cond= context->cond_ptr;
238  curr_cond= context->cond_ptr= new Ndb_cond();
239  prev_cond->next= curr_cond;
240  }
241 
242  // Check for end of AND/OR expression
243  if (!item)
244  {
245  // End marker for condition group
246  DBUG_PRINT("info", ("End of condition group"));
247  context->expect_no_length();
248  curr_cond->ndb_item= new Ndb_item(NDB_END_COND);
249  }
250  else
251  {
252  bool pop= TRUE;
253 
254  switch (item->type()) {
255  case Item::FIELD_ITEM:
256  {
257  Item_field *field_item= (Item_field *) item;
258  Field *field= field_item->field;
259  const enum_field_types type= field->real_type();
260  /*
261  Check that the field is part of the table of the handler
262  instance and that we expect a field with of this result type.
263  */
264  if (context->table->s == field->table->s)
265  {
266  const NDBTAB *tab= context->ndb_table;
267  DBUG_PRINT("info", ("FIELD_ITEM"));
268  DBUG_PRINT("info", ("table %s", tab->getName()));
269  DBUG_PRINT("info", ("column %s", field->field_name));
270  DBUG_PRINT("info", ("column length %u", field->field_length));
271  DBUG_PRINT("info", ("type %d", type));
272  DBUG_PRINT("info", ("result type %d", field->result_type()));
273 
274  // Check that we are expecting a field and with the correct
275  // result type and of length that can store the item value
276  if (context->expecting(Item::FIELD_ITEM) &&
277  context->expecting_field_type(type) &&
278  context->expecting_max_length(field->field_length) &&
279  (context->expecting_field_result(field->result_type()) ||
280  // Date and year can be written as string or int
281  ((type == MYSQL_TYPE_TIME ||
282  type == MYSQL_TYPE_DATE ||
283  type == MYSQL_TYPE_NEWDATE ||
284  type == MYSQL_TYPE_YEAR ||
285  type == MYSQL_TYPE_DATETIME)
286  ? (context->expecting_field_result(STRING_RESULT) ||
287  context->expecting_field_result(INT_RESULT))
288  : TRUE)) &&
289  // Bit fields no yet supported in scan filter
290  type != MYSQL_TYPE_BIT &&
291  // No BLOB support in scan filter
292  type != MYSQL_TYPE_TINY_BLOB &&
293  type != MYSQL_TYPE_MEDIUM_BLOB &&
294  type != MYSQL_TYPE_LONG_BLOB &&
295  type != MYSQL_TYPE_BLOB)
296  {
297  const NDBCOL *col= tab->getColumn(field->field_name);
298  DBUG_ASSERT(col);
299  curr_cond->ndb_item= new Ndb_item(field, col->getColumnNo());
300  context->dont_expect(Item::FIELD_ITEM);
301  context->expect_no_field_result();
302  if (! context->expecting_nothing())
303  {
304  // We have not seen second argument yet
305  if (type == MYSQL_TYPE_TIME ||
306  type == MYSQL_TYPE_DATE ||
307  type == MYSQL_TYPE_NEWDATE ||
308  type == MYSQL_TYPE_YEAR ||
309  type == MYSQL_TYPE_DATETIME)
310  {
311  context->expect_only(Item::STRING_ITEM);
312  context->expect(Item::INT_ITEM);
313  }
314  else
315  switch (field->result_type()) {
316  case STRING_RESULT:
317  // Expect char string or binary string
318  context->expect_only(Item::STRING_ITEM);
319  context->expect(Item::VARBIN_ITEM);
320  context->expect_collation(field_item->collation.collation);
321  context->expect_max_length(field->field_length);
322  break;
323  case REAL_RESULT:
324  context->expect_only(Item::REAL_ITEM);
325  context->expect(Item::DECIMAL_ITEM);
326  context->expect(Item::INT_ITEM);
327  break;
328  case INT_RESULT:
329  context->expect_only(Item::INT_ITEM);
330  context->expect(Item::VARBIN_ITEM);
331  break;
332  case DECIMAL_RESULT:
333  context->expect_only(Item::DECIMAL_ITEM);
334  context->expect(Item::REAL_ITEM);
335  context->expect(Item::INT_ITEM);
336  break;
337  default:
338  break;
339  }
340  }
341  else
342  {
343  // Expect another logical expression
344  context->expect_only(Item::FUNC_ITEM);
345  context->expect(Item::COND_ITEM);
346  // Check that field and string constant collations are the same
347  if ((field->result_type() == STRING_RESULT) &&
348  !context->expecting_collation(item->collation.collation)
349  && type != MYSQL_TYPE_TIME
350  && type != MYSQL_TYPE_DATE
351  && type != MYSQL_TYPE_NEWDATE
352  && type != MYSQL_TYPE_YEAR
353  && type != MYSQL_TYPE_DATETIME)
354  {
355  DBUG_PRINT("info", ("Found non-matching collation %s",
356  item->collation.collation->name));
357  context->supported= FALSE;
358  }
359  }
360  break;
361  }
362  else
363  {
364  DBUG_PRINT("info", ("Was not expecting field of type %u(%u)",
365  field->result_type(), type));
366  context->supported= FALSE;
367  }
368  }
369  else
370  {
371  DBUG_PRINT("info", ("Was not expecting field from table %s (%s)",
372  context->table->s->table_name.str,
373  field->table->s->table_name.str));
374  context->supported= FALSE;
375  }
376  break;
377  }
378  case Item::FUNC_ITEM:
379  {
380  Item_func *func_item= (Item_func *) item;
381  // Check that we expect a function or functional expression here
382  if (context->expecting(Item::FUNC_ITEM) ||
383  func_item->functype() == Item_func::UNKNOWN_FUNC ||
384  func_item->functype() == Item_func::NEG_FUNC)
385  context->expect_nothing();
386  else
387  {
388  // Did not expect function here
389  context->supported= FALSE;
390  break;
391  }
392  context->expect_no_length();
393  switch (func_item->functype()) {
394  case Item_func::EQ_FUNC:
395  {
396  DBUG_PRINT("info", ("EQ_FUNC"));
397  curr_cond->ndb_item= new Ndb_item(func_item->functype(),
398  func_item);
399  context->expect(Item::STRING_ITEM);
400  context->expect(Item::INT_ITEM);
401  context->expect(Item::REAL_ITEM);
402  context->expect(Item::DECIMAL_ITEM);
403  context->expect(Item::VARBIN_ITEM);
404  context->expect(Item::FIELD_ITEM);
405  context->expect_field_result(STRING_RESULT);
406  context->expect_field_result(REAL_RESULT);
407  context->expect_field_result(INT_RESULT);
408  context->expect_field_result(DECIMAL_RESULT);
409  break;
410  }
411  case Item_func::NE_FUNC:
412  {
413  DBUG_PRINT("info", ("NE_FUNC"));
414  curr_cond->ndb_item= new Ndb_item(func_item->functype(),
415  func_item);
416  context->expect(Item::STRING_ITEM);
417  context->expect(Item::INT_ITEM);
418  context->expect(Item::REAL_ITEM);
419  context->expect(Item::DECIMAL_ITEM);
420  context->expect(Item::VARBIN_ITEM);
421  context->expect(Item::FIELD_ITEM);
422  context->expect_field_result(STRING_RESULT);
423  context->expect_field_result(REAL_RESULT);
424  context->expect_field_result(INT_RESULT);
425  context->expect_field_result(DECIMAL_RESULT);
426  break;
427  }
428  case Item_func::LT_FUNC:
429  {
430  DBUG_PRINT("info", ("LT_FUNC"));
431  curr_cond->ndb_item= new Ndb_item(func_item->functype(),
432  func_item);
433  context->expect(Item::STRING_ITEM);
434  context->expect(Item::INT_ITEM);
435  context->expect(Item::REAL_ITEM);
436  context->expect(Item::DECIMAL_ITEM);
437  context->expect(Item::VARBIN_ITEM);
438  context->expect(Item::FIELD_ITEM);
439  context->expect_field_result(STRING_RESULT);
440  context->expect_field_result(REAL_RESULT);
441  context->expect_field_result(INT_RESULT);
442  context->expect_field_result(DECIMAL_RESULT);
443  break;
444  }
445  case Item_func::LE_FUNC:
446  {
447  DBUG_PRINT("info", ("LE_FUNC"));
448  curr_cond->ndb_item= new Ndb_item(func_item->functype(),
449  func_item);
450  context->expect(Item::STRING_ITEM);
451  context->expect(Item::INT_ITEM);
452  context->expect(Item::REAL_ITEM);
453  context->expect(Item::DECIMAL_ITEM);
454  context->expect(Item::VARBIN_ITEM);
455  context->expect(Item::FIELD_ITEM);
456  context->expect_field_result(STRING_RESULT);
457  context->expect_field_result(REAL_RESULT);
458  context->expect_field_result(INT_RESULT);
459  context->expect_field_result(DECIMAL_RESULT);
460  break;
461  }
462  case Item_func::GE_FUNC:
463  {
464  DBUG_PRINT("info", ("GE_FUNC"));
465  curr_cond->ndb_item= new Ndb_item(func_item->functype(),
466  func_item);
467  context->expect(Item::STRING_ITEM);
468  context->expect(Item::INT_ITEM);
469  context->expect(Item::REAL_ITEM);
470  context->expect(Item::DECIMAL_ITEM);
471  context->expect(Item::VARBIN_ITEM);
472  context->expect(Item::FIELD_ITEM);
473  context->expect_field_result(STRING_RESULT);
474  context->expect_field_result(REAL_RESULT);
475  context->expect_field_result(INT_RESULT);
476  context->expect_field_result(DECIMAL_RESULT);
477  break;
478  }
479  case Item_func::GT_FUNC:
480  {
481  DBUG_PRINT("info", ("GT_FUNC"));
482  curr_cond->ndb_item= new Ndb_item(func_item->functype(),
483  func_item);
484  context->expect(Item::STRING_ITEM);
485  context->expect(Item::REAL_ITEM);
486  context->expect(Item::DECIMAL_ITEM);
487  context->expect(Item::INT_ITEM);
488  context->expect(Item::VARBIN_ITEM);
489  context->expect(Item::FIELD_ITEM);
490  context->expect_field_result(STRING_RESULT);
491  context->expect_field_result(REAL_RESULT);
492  context->expect_field_result(INT_RESULT);
493  context->expect_field_result(DECIMAL_RESULT);
494  break;
495  }
496  case Item_func::LIKE_FUNC:
497  {
498  Ndb_expect_stack* expect_next= new Ndb_expect_stack();
499  DBUG_PRINT("info", ("LIKE_FUNC"));
500 
501  if (((const Item_func_like *)func_item)->escape_was_used_in_parsing())
502  {
503  DBUG_PRINT("info", ("LIKE expressions with ESCAPE not supported"));
504  context->supported= FALSE;
505  }
506 
507  curr_cond->ndb_item= new Ndb_item(func_item->functype(),
508  func_item);
509 
510  /*
511  Ndb currently only supports pushing
512  <field> LIKE <string> | <func>
513  we thus push <string> | <func>
514  on the expect stack to catch that we
515  don't support <string> LIKE <field>.
516  */
517  context->expect(Item::FIELD_ITEM);
518  context->expect_only_field_type(MYSQL_TYPE_STRING);
519  context->expect_field_type(MYSQL_TYPE_VAR_STRING);
520  context->expect_field_type(MYSQL_TYPE_VARCHAR);
521  context->expect_field_result(STRING_RESULT);
522  expect_next->expect(Item::STRING_ITEM);
523  expect_next->expect(Item::FUNC_ITEM);
524  context->expect_stack.push(expect_next);
525  pop= FALSE;
526  break;
527  }
528  case Item_func::ISNULL_FUNC:
529  {
530  DBUG_PRINT("info", ("ISNULL_FUNC"));
531  curr_cond->ndb_item= new Ndb_item(func_item->functype(),
532  func_item);
533  context->expect(Item::FIELD_ITEM);
534  context->expect_field_result(STRING_RESULT);
535  context->expect_field_result(REAL_RESULT);
536  context->expect_field_result(INT_RESULT);
537  context->expect_field_result(DECIMAL_RESULT);
538  break;
539  }
540  case Item_func::ISNOTNULL_FUNC:
541  {
542  DBUG_PRINT("info", ("ISNOTNULL_FUNC"));
543  curr_cond->ndb_item= new Ndb_item(func_item->functype(),
544  func_item);
545  context->expect(Item::FIELD_ITEM);
546  context->expect_field_result(STRING_RESULT);
547  context->expect_field_result(REAL_RESULT);
548  context->expect_field_result(INT_RESULT);
549  context->expect_field_result(DECIMAL_RESULT);
550  break;
551  }
552  case Item_func::NOT_FUNC:
553  {
554  DBUG_PRINT("info", ("NOT_FUNC"));
555  curr_cond->ndb_item= new Ndb_item(func_item->functype(),
556  func_item);
557  context->expect(Item::FUNC_ITEM);
558  context->expect(Item::COND_ITEM);
559  break;
560  }
561  case Item_func::BETWEEN:
562  {
563  DBUG_PRINT("info", ("BETWEEN, rewriting using AND"));
564  Item_func_between *between_func= (Item_func_between *) func_item;
565  Ndb_rewrite_context *rewrite_context=
566  new Ndb_rewrite_context(func_item);
567  rewrite_context->next= context->rewrite_stack;
568  context->rewrite_stack= rewrite_context;
569  if (between_func->negated)
570  {
571  DBUG_PRINT("info", ("NOT_FUNC"));
572  curr_cond->ndb_item= new Ndb_item(Item_func::NOT_FUNC, 1);
573  prev_cond= curr_cond;
574  curr_cond= context->cond_ptr= new Ndb_cond();
575  curr_cond->prev= prev_cond;
576  prev_cond->next= curr_cond;
577  }
578  DBUG_PRINT("info", ("COND_AND_FUNC"));
579  curr_cond->ndb_item=
580  new Ndb_item(Item_func::COND_AND_FUNC,
581  func_item->argument_count() - 1);
582  context->expect_only(Item::FIELD_ITEM);
583  context->expect(Item::INT_ITEM);
584  context->expect(Item::STRING_ITEM);
585  context->expect(Item::VARBIN_ITEM);
586  context->expect(Item::FUNC_ITEM);
587  context->expect(Item::CACHE_ITEM);
588  break;
589  }
590  case Item_func::IN_FUNC:
591  {
592  DBUG_PRINT("info", ("IN_FUNC, rewriting using OR"));
593  Item_func_in *in_func= (Item_func_in *) func_item;
594  Ndb_rewrite_context *rewrite_context=
595  new Ndb_rewrite_context(func_item);
596  rewrite_context->next= context->rewrite_stack;
597  context->rewrite_stack= rewrite_context;
598  if (in_func->negated)
599  {
600  DBUG_PRINT("info", ("NOT_FUNC"));
601  curr_cond->ndb_item= new Ndb_item(Item_func::NOT_FUNC, 1);
602  prev_cond= curr_cond;
603  curr_cond= context->cond_ptr= new Ndb_cond();
604  curr_cond->prev= prev_cond;
605  prev_cond->next= curr_cond;
606  }
607  DBUG_PRINT("info", ("COND_OR_FUNC"));
608  curr_cond->ndb_item= new Ndb_item(Item_func::COND_OR_FUNC,
609  func_item->argument_count() - 1);
610  context->expect_only(Item::FIELD_ITEM);
611  context->expect(Item::INT_ITEM);
612  context->expect(Item::STRING_ITEM);
613  context->expect(Item::VARBIN_ITEM);
614  context->expect(Item::FUNC_ITEM);
615  context->expect(Item::CACHE_ITEM);
616  break;
617  }
618  case Item_func::NEG_FUNC:
619  case Item_func::UNKNOWN_FUNC:
620  {
621  /*
622  Constant expressions of the type
623  -17, 1+2, concat(0xBB, '%') will
624  be evaluated before pushed.
625  */
626  DBUG_PRINT("info", ("Function %s",
627  func_item->const_item()?"const":""));
628  DBUG_PRINT("info", ("result type %d", func_item->result_type()));
629  /*
630  Check if we are rewriting queries of the type
631  <const> BETWEEN|IN <func> ...
632  as this is currently not supported.
633  */
634  if (context->rewrite_stack &&
635  context->rewrite_stack->left_hand_item &&
636  context->rewrite_stack->left_hand_item->type()
637  != Item::FIELD_ITEM)
638  {
639  DBUG_PRINT("info", ("Function during rewrite not supported"));
640  context->supported= FALSE;
641  }
642  if (func_item->const_item())
643  {
644  switch (func_item->result_type()) {
645  case STRING_RESULT:
646  {
648  q.value_type= Item::STRING_ITEM;
649  curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
650  if (! context->expecting_no_field_result())
651  {
652  // We have not seen the field argument yet
653  context->expect_only(Item::FIELD_ITEM);
654  context->expect_only_field_result(STRING_RESULT);
655  context->expect_collation(func_item->collation.collation);
656  }
657  else
658  {
659  // Expect another logical expression
660  context->expect_only(Item::FUNC_ITEM);
661  context->expect(Item::COND_ITEM);
662  // Check that string result have correct collation
663  if (!context->expecting_collation(item->collation.collation))
664  {
665  DBUG_PRINT("info", ("Found non-matching collation %s",
666  item->collation.collation->name));
667  context->supported= FALSE;
668  }
669  }
670  // Skip any arguments since we will evaluate function instead
671  DBUG_PRINT("info", ("Skip until end of arguments marker"));
672  context->skip= func_item->argument_count();
673  break;
674  }
675  case REAL_RESULT:
676  {
678  q.value_type= Item::REAL_ITEM;
679  curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
680  if (! context->expecting_no_field_result())
681  {
682  // We have not seen the field argument yet
683  context->expect_only(Item::FIELD_ITEM);
684  context->expect_only_field_result(REAL_RESULT);
685  }
686  else
687  {
688  // Expect another logical expression
689  context->expect_only(Item::FUNC_ITEM);
690  context->expect(Item::COND_ITEM);
691  }
692 
693  // Skip any arguments since we will evaluate function instead
694  DBUG_PRINT("info", ("Skip until end of arguments marker"));
695  context->skip= func_item->argument_count();
696  break;
697  }
698  case INT_RESULT:
699  {
701  q.value_type= Item::INT_ITEM;
702  curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
703  if (! context->expecting_no_field_result())
704  {
705  // We have not seen the field argument yet
706  context->expect_only(Item::FIELD_ITEM);
707  context->expect_only_field_result(INT_RESULT);
708  }
709  else
710  {
711  // Expect another logical expression
712  context->expect_only(Item::FUNC_ITEM);
713  context->expect(Item::COND_ITEM);
714  }
715 
716  // Skip any arguments since we will evaluate function instead
717  DBUG_PRINT("info", ("Skip until end of arguments marker"));
718  context->skip= func_item->argument_count();
719  break;
720  }
721  case DECIMAL_RESULT:
722  {
724  q.value_type= Item::DECIMAL_ITEM;
725  curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
726  if (! context->expecting_no_field_result())
727  {
728  // We have not seen the field argument yet
729  context->expect_only(Item::FIELD_ITEM);
730  context->expect_only_field_result(DECIMAL_RESULT);
731  }
732  else
733  {
734  // Expect another logical expression
735  context->expect_only(Item::FUNC_ITEM);
736  context->expect(Item::COND_ITEM);
737  }
738  // Skip any arguments since we will evaluate function instead
739  DBUG_PRINT("info", ("Skip until end of arguments marker"));
740  context->skip= func_item->argument_count();
741  break;
742  }
743  default:
744  break;
745  }
746  }
747  else
748  // Function does not return constant expression
749  context->supported= FALSE;
750  break;
751  }
752  default:
753  {
754  DBUG_PRINT("info", ("Found func_item of type %d",
755  func_item->functype()));
756  context->supported= FALSE;
757  }
758  }
759  break;
760  }
761  case Item::STRING_ITEM:
762  DBUG_PRINT("info", ("STRING_ITEM"));
763  // Check that we do support pushing the item value length
764  if (context->expecting(Item::STRING_ITEM) &&
765  context->expecting_length(item->max_length))
766  {
767 #ifndef DBUG_OFF
768  char buff[256];
769  String str(buff,0, system_charset_info);
770  //str.length(0);// Magnus
771  Item_string *string_item= (Item_string *) item;
772  DBUG_PRINT("info", ("value \"%s\"",
773  string_item->val_str(&str)->ptr()));
774 #endif
776  q.value_type= Item::STRING_ITEM;
777  curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
778  if (! context->expecting_no_field_result())
779  {
780  // We have not seen the field argument yet
781  context->expect_only(Item::FIELD_ITEM);
782  context->expect_only_field_result(STRING_RESULT);
783  context->expect_collation(item->collation.collation);
784  context->expect_length(item->max_length);
785  }
786  else
787  {
788  // Expect another logical expression
789  context->expect_only(Item::FUNC_ITEM);
790  context->expect(Item::COND_ITEM);
791  context->expect_no_length();
792  // Check that we are comparing with a field with same collation
793  if (!context->expecting_collation(item->collation.collation))
794  {
795  DBUG_PRINT("info", ("Found non-matching collation %s",
796  item->collation.collation->name));
797  context->supported= FALSE;
798  }
799  }
800  }
801  else
802  context->supported= FALSE;
803  break;
804  case Item::INT_ITEM:
805  DBUG_PRINT("info", ("INT_ITEM"));
806  if (context->expecting(Item::INT_ITEM))
807  {
808  DBUG_PRINT("info", ("value %ld",
809  (long) ((Item_int*) item)->value));
811  q.value_type= Item::INT_ITEM;
812  curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
813  if (! context->expecting_no_field_result())
814  {
815  // We have not seen the field argument yet
816  context->expect_only(Item::FIELD_ITEM);
817  context->expect_only_field_result(INT_RESULT);
818  context->expect_field_result(REAL_RESULT);
819  context->expect_field_result(DECIMAL_RESULT);
820  }
821  else
822  {
823  // Expect another logical expression
824  context->expect_only(Item::FUNC_ITEM);
825  context->expect(Item::COND_ITEM);
826  }
827  }
828  else
829  context->supported= FALSE;
830  break;
831  case Item::REAL_ITEM:
832  DBUG_PRINT("info", ("REAL_ITEM"));
833  if (context->expecting(Item::REAL_ITEM))
834  {
835  DBUG_PRINT("info", ("value %f", ((Item_float*) item)->value));
837  q.value_type= Item::REAL_ITEM;
838  curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
839  if (! context->expecting_no_field_result())
840  {
841  // We have not seen the field argument yet
842  context->expect_only(Item::FIELD_ITEM);
843  context->expect_only_field_result(REAL_RESULT);
844  }
845  else
846  {
847  // Expect another logical expression
848  context->expect_only(Item::FUNC_ITEM);
849  context->expect(Item::COND_ITEM);
850  }
851  }
852  else
853  context->supported= FALSE;
854  break;
855  case Item::VARBIN_ITEM:
856  DBUG_PRINT("info", ("VARBIN_ITEM"));
857  if (context->expecting(Item::VARBIN_ITEM))
858  {
860  q.value_type= Item::VARBIN_ITEM;
861  curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
862  if (! context->expecting_no_field_result())
863  {
864  // We have not seen the field argument yet
865  context->expect_only(Item::FIELD_ITEM);
866  context->expect_only_field_result(STRING_RESULT);
867  }
868  else
869  {
870  // Expect another logical expression
871  context->expect_only(Item::FUNC_ITEM);
872  context->expect(Item::COND_ITEM);
873  }
874  }
875  else
876  context->supported= FALSE;
877  break;
878  case Item::DECIMAL_ITEM:
879  DBUG_PRINT("info", ("DECIMAL_ITEM"));
880  if (context->expecting(Item::DECIMAL_ITEM))
881  {
882  DBUG_PRINT("info", ("value %f",
883  ((Item_decimal*) item)->val_real()));
885  q.value_type= Item::DECIMAL_ITEM;
886  curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
887  if (! context->expecting_no_field_result())
888  {
889  // We have not seen the field argument yet
890  context->expect_only(Item::FIELD_ITEM);
891  context->expect_only_field_result(REAL_RESULT);
892  context->expect_field_result(DECIMAL_RESULT);
893  }
894  else
895  {
896  // Expect another logical expression
897  context->expect_only(Item::FUNC_ITEM);
898  context->expect(Item::COND_ITEM);
899  }
900  }
901  else
902  context->supported= FALSE;
903  break;
904  case Item::COND_ITEM:
905  {
906  Item_cond *cond_item= (Item_cond *) item;
907 
908  if (context->expecting(Item::COND_ITEM))
909  {
910  switch (cond_item->functype()) {
911  case Item_func::COND_AND_FUNC:
912  DBUG_PRINT("info", ("COND_AND_FUNC"));
913  curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
914  cond_item);
915  break;
916  case Item_func::COND_OR_FUNC:
917  DBUG_PRINT("info", ("COND_OR_FUNC"));
918  curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
919  cond_item);
920  break;
921  default:
922  DBUG_PRINT("info", ("COND_ITEM %d", cond_item->functype()));
923  context->supported= FALSE;
924  break;
925  }
926  }
927  else
928  {
929  /* Did not expect condition */
930  context->supported= FALSE;
931  }
932  break;
933  }
934  case Item::CACHE_ITEM:
935  {
936  DBUG_PRINT("info", ("CACHE_ITEM"));
937  Item_cache* cache_item = (Item_cache*)item;
938  DBUG_PRINT("info", ("result type %d", cache_item->result_type()));
939 
940  // Item_cache has cached "something", use its value
941  // based on the result_type of the item
942  switch(cache_item->result_type())
943  {
944  case INT_RESULT:
945  DBUG_PRINT("info", ("INT_RESULT"));
946  if (context->expecting(Item::INT_ITEM))
947  {
948  DBUG_PRINT("info", ("value %ld",
949  (long) ((Item_int*) item)->value));
951  q.value_type= Item::INT_ITEM;
952  curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
953  if (! context->expecting_no_field_result())
954  {
955  // We have not seen the field argument yet
956  context->expect_only(Item::FIELD_ITEM);
957  context->expect_only_field_result(INT_RESULT);
958  context->expect_field_result(REAL_RESULT);
959  context->expect_field_result(DECIMAL_RESULT);
960  }
961  else
962  {
963  // Expect another logical expression
964  context->expect_only(Item::FUNC_ITEM);
965  context->expect(Item::COND_ITEM);
966  }
967  }
968  else
969  context->supported= FALSE;
970  break;
971 
972  case REAL_RESULT:
973  DBUG_PRINT("info", ("REAL_RESULT"));
974  if (context->expecting(Item::REAL_ITEM))
975  {
976  DBUG_PRINT("info", ("value %f", ((Item_float*) item)->value));
978  q.value_type= Item::REAL_ITEM;
979  curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
980  if (! context->expecting_no_field_result())
981  {
982  // We have not seen the field argument yet
983  context->expect_only(Item::FIELD_ITEM);
984  context->expect_only_field_result(REAL_RESULT);
985  }
986  else
987  {
988  // Expect another logical expression
989  context->expect_only(Item::FUNC_ITEM);
990  context->expect(Item::COND_ITEM);
991  }
992  }
993  else
994  context->supported= FALSE;
995  break;
996 
997  case DECIMAL_RESULT:
998  DBUG_PRINT("info", ("DECIMAL_RESULT"));
999  if (context->expecting(Item::DECIMAL_ITEM))
1000  {
1001  DBUG_PRINT("info", ("value %f",
1002  ((Item_decimal*) item)->val_real()));
1004  q.value_type= Item::DECIMAL_ITEM;
1005  curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
1006  if (! context->expecting_no_field_result())
1007  {
1008  // We have not seen the field argument yet
1009  context->expect_only(Item::FIELD_ITEM);
1010  context->expect_only_field_result(REAL_RESULT);
1011  context->expect_field_result(DECIMAL_RESULT);
1012  }
1013  else
1014  {
1015  // Expect another logical expression
1016  context->expect_only(Item::FUNC_ITEM);
1017  context->expect(Item::COND_ITEM);
1018  }
1019  }
1020  else
1021  context->supported= FALSE;
1022  break;
1023 
1024  case STRING_RESULT:
1025  DBUG_PRINT("info", ("STRING_RESULT"));
1026  // Check that we do support pushing the item value length
1027  if (context->expecting(Item::STRING_ITEM) &&
1028  context->expecting_length(item->max_length))
1029  {
1030  #ifndef DBUG_OFF
1031  char buff[256];
1032  String str(buff,0, system_charset_info);
1033  //str.length(0);// Magnus
1034  Item_string *string_item= (Item_string *) item;
1035  DBUG_PRINT("info", ("value \"%s\"",
1036  string_item->val_str(&str)->ptr()));
1037  #endif
1039  q.value_type= Item::STRING_ITEM;
1040  curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
1041  if (! context->expecting_no_field_result())
1042  {
1043  // We have not seen the field argument yet
1044  context->expect_only(Item::FIELD_ITEM);
1045  context->expect_only_field_result(STRING_RESULT);
1046  context->expect_collation(item->collation.collation);
1047  context->expect_length(item->max_length);
1048  }
1049  else
1050  {
1051  // Expect another logical expression
1052  context->expect_only(Item::FUNC_ITEM);
1053  context->expect(Item::COND_ITEM);
1054  context->expect_no_length();
1055  // Check that we are comparing with a field with same collation
1056  if (!context->expecting_collation(item->collation.collation))
1057  {
1058  DBUG_PRINT("info", ("Found non-matching collation %s",
1059  item->collation.collation->name));
1060  context->supported= FALSE;
1061  }
1062  }
1063  }
1064  else
1065  context->supported= FALSE;
1066  break;
1067 
1068  default:
1069  context->supported= FALSE;
1070  break;
1071  }
1072  break;
1073  }
1074 
1075  default:
1076  {
1077  DBUG_PRINT("info", ("Found unsupported item of type %d",
1078  item->type()));
1079  context->supported= FALSE;
1080  }
1081  }
1082  if (pop)
1083  context->expect_stack.pop();
1084  }
1085  if (context->supported && context->rewrite_stack)
1086  {
1087  Ndb_rewrite_context *rewrite_context= context->rewrite_stack;
1088  if (rewrite_context->count ==
1089  rewrite_context->func_item->argument_count())
1090  {
1091  // Rewrite is done, wrap an END() at the en
1092  DBUG_PRINT("info", ("End of condition group"));
1093  prev_cond= curr_cond;
1094  curr_cond= context->cond_ptr= new Ndb_cond();
1095  curr_cond->prev= prev_cond;
1096  prev_cond->next= curr_cond;
1097  context->expect_no_length();
1098  curr_cond->ndb_item= new Ndb_item(NDB_END_COND);
1099  // Pop rewrite stack
1100  context->rewrite_stack= rewrite_context->next;
1101  rewrite_context->next= NULL;
1102  delete(rewrite_context);
1103  }
1104  }
1105  }
1106  }
1107 
1108  DBUG_VOID_RETURN;
1109 }
1110 
1111 /*
1112  Push a condition
1113  */
1114 const
1115 Item*
1116 ha_ndbcluster_cond::cond_push(const Item *cond,
1117  TABLE *table, const NDBTAB *ndb_table)
1118 {
1119  DBUG_ENTER("ha_ndbcluster_cond::cond_push");
1120  Ndb_cond_stack *ndb_cond = new Ndb_cond_stack();
1121  if (ndb_cond == NULL)
1122  {
1123  my_errno= HA_ERR_OUT_OF_MEM;
1124  DBUG_RETURN(cond);
1125  }
1126  if (m_cond_stack)
1127  ndb_cond->next= m_cond_stack;
1128  else
1129  ndb_cond->next= NULL;
1130  m_cond_stack= ndb_cond;
1131 
1132  if (serialize_cond(cond, ndb_cond, table, ndb_table))
1133  {
1134  DBUG_RETURN(NULL);
1135  }
1136  else
1137  {
1138  cond_pop();
1139  }
1140  DBUG_RETURN(cond);
1141 }
1142 
1143 /*
1144  Pop the top condition from the condition stack
1145 */
1146 void
1147 ha_ndbcluster_cond::cond_pop()
1148 {
1149  Ndb_cond_stack *ndb_cond_stack= m_cond_stack;
1150  if (ndb_cond_stack)
1151  {
1152  m_cond_stack= ndb_cond_stack->next;
1153  ndb_cond_stack->next= NULL;
1154  delete ndb_cond_stack;
1155  }
1156 }
1157 
1158 /*
1159  Clear the condition stack
1160 */
1161 void
1162 ha_ndbcluster_cond::cond_clear()
1163 {
1164  DBUG_ENTER("cond_clear");
1165  while (m_cond_stack)
1166  cond_pop();
1167 
1168  DBUG_VOID_RETURN;
1169 }
1170 
1171 bool
1172 ha_ndbcluster_cond::serialize_cond(const Item *cond, Ndb_cond_stack *ndb_cond,
1173  TABLE *table, const NDBTAB *ndb_table)
1174 {
1175  DBUG_ENTER("serialize_cond");
1176  Item *item= (Item *) cond;
1177  Ndb_cond_traverse_context context(table, ndb_table, ndb_cond);
1178  // Expect a logical expression
1179  context.expect(Item::FUNC_ITEM);
1180  context.expect(Item::COND_ITEM);
1181  item->traverse_cond(&ndb_serialize_cond, (void *) &context, Item::PREFIX);
1182  DBUG_PRINT("info", ("The pushed condition is %ssupported", (context.supported)?"":"not "));
1183 
1184  DBUG_RETURN(context.supported);
1185 }
1186 
1187 int
1188 ha_ndbcluster_cond::build_scan_filter_predicate(Ndb_cond * &cond,
1189  NdbScanFilter *filter,
1190  bool negated)
1191 {
1192  DBUG_ENTER("build_scan_filter_predicate");
1193  switch (cond->ndb_item->type) {
1194  case NDB_FUNCTION:
1195  {
1196  if (!cond->next)
1197  break;
1198  Ndb_item *a= cond->next->ndb_item;
1199  Ndb_item *b, *field, *value= NULL;
1200 
1201  switch (cond->ndb_item->argument_count()) {
1202  case 1:
1203  field= (a->type == NDB_FIELD)? a : NULL;
1204  break;
1205  case 2:
1206  if (!cond->next->next)
1207  {
1208  field= NULL;
1209  break;
1210  }
1211  b= cond->next->next->ndb_item;
1212  value= ((a->type == NDB_VALUE) ? a :
1213  (b->type == NDB_VALUE) ? b :
1214  NULL);
1215  field= ((a->type == NDB_FIELD) ? a :
1216  (b->type == NDB_FIELD) ? b :
1217  NULL);
1218  break;
1219  default:
1220  field= NULL; //Keep compiler happy
1221  DBUG_ASSERT(0);
1222  break;
1223  }
1224  switch ((negated) ?
1225  Ndb_item::negate(cond->ndb_item->qualification.function_type)
1226  : cond->ndb_item->qualification.function_type) {
1227  case NDB_EQ_FUNC:
1228  {
1229  if (!value || !field) break;
1230  // Save value in right format for the field type
1231  value->save_in_field(field);
1232  DBUG_PRINT("info", ("Generating EQ filter"));
1233  if (filter->cmp(NdbScanFilter::COND_EQ,
1234  field->get_field_no(),
1235  field->get_val(),
1236  field->pack_length()) == -1)
1237  DBUG_RETURN(1);
1238  cond= cond->next->next->next;
1239  DBUG_RETURN(0);
1240  }
1241  case NDB_NE_FUNC:
1242  {
1243  if (!value || !field) break;
1244  // Save value in right format for the field type
1245  value->save_in_field(field);
1246  DBUG_PRINT("info", ("Generating NE filter"));
1247  if (filter->cmp(NdbScanFilter::COND_NE,
1248  field->get_field_no(),
1249  field->get_val(),
1250  field->pack_length()) == -1)
1251  DBUG_RETURN(1);
1252  cond= cond->next->next->next;
1253  DBUG_RETURN(0);
1254  }
1255  case NDB_LT_FUNC:
1256  {
1257  if (!value || !field) break;
1258  // Save value in right format for the field type
1259  value->save_in_field(field);
1260  if (a == field)
1261  {
1262  DBUG_PRINT("info", ("Generating LT filter"));
1263  if (filter->cmp(NdbScanFilter::COND_LT,
1264  field->get_field_no(),
1265  field->get_val(),
1266  field->pack_length()) == -1)
1267  DBUG_RETURN(1);
1268  }
1269  else
1270  {
1271  DBUG_PRINT("info", ("Generating GT filter"));
1272  if (filter->cmp(NdbScanFilter::COND_GT,
1273  field->get_field_no(),
1274  field->get_val(),
1275  field->pack_length()) == -1)
1276  DBUG_RETURN(1);
1277  }
1278  cond= cond->next->next->next;
1279  DBUG_RETURN(0);
1280  }
1281  case NDB_LE_FUNC:
1282  {
1283  if (!value || !field) break;
1284  // Save value in right format for the field type
1285  value->save_in_field(field);
1286  if (a == field)
1287  {
1288  DBUG_PRINT("info", ("Generating LE filter"));
1289  if (filter->cmp(NdbScanFilter::COND_LE,
1290  field->get_field_no(),
1291  field->get_val(),
1292  field->pack_length()) == -1)
1293  DBUG_RETURN(1);
1294  }
1295  else
1296  {
1297  DBUG_PRINT("info", ("Generating GE filter"));
1298  if (filter->cmp(NdbScanFilter::COND_GE,
1299  field->get_field_no(),
1300  field->get_val(),
1301  field->pack_length()) == -1)
1302  DBUG_RETURN(1);
1303  }
1304  cond= cond->next->next->next;
1305  DBUG_RETURN(0);
1306  }
1307  case NDB_GE_FUNC:
1308  {
1309  if (!value || !field) break;
1310  // Save value in right format for the field type
1311  value->save_in_field(field);
1312  if (a == field)
1313  {
1314  DBUG_PRINT("info", ("Generating GE filter"));
1315  if (filter->cmp(NdbScanFilter::COND_GE,
1316  field->get_field_no(),
1317  field->get_val(),
1318  field->pack_length()) == -1)
1319  DBUG_RETURN(1);
1320  }
1321  else
1322  {
1323  DBUG_PRINT("info", ("Generating LE filter"));
1324  if (filter->cmp(NdbScanFilter::COND_LE,
1325  field->get_field_no(),
1326  field->get_val(),
1327  field->pack_length()) == -1)
1328  DBUG_RETURN(1);
1329  }
1330  cond= cond->next->next->next;
1331  DBUG_RETURN(0);
1332  }
1333  case NDB_GT_FUNC:
1334  {
1335  if (!value || !field) break;
1336  // Save value in right format for the field type
1337  value->save_in_field(field);
1338  if (a == field)
1339  {
1340  DBUG_PRINT("info", ("Generating GT filter"));
1341  if (filter->cmp(NdbScanFilter::COND_GT,
1342  field->get_field_no(),
1343  field->get_val(),
1344  field->pack_length()) == -1)
1345  DBUG_RETURN(1);
1346  }
1347  else
1348  {
1349  DBUG_PRINT("info", ("Generating LT filter"));
1350  if (filter->cmp(NdbScanFilter::COND_LT,
1351  field->get_field_no(),
1352  field->get_val(),
1353  field->pack_length()) == -1)
1354  DBUG_RETURN(1);
1355  }
1356  cond= cond->next->next->next;
1357  DBUG_RETURN(0);
1358  }
1359  case NDB_LIKE_FUNC:
1360  {
1361  if (!value || !field) break;
1362  if ((value->qualification.value_type != Item::STRING_ITEM) &&
1363  (value->qualification.value_type != Item::VARBIN_ITEM))
1364  break;
1365  // Save value in right format for the field type
1366  value->save_in_field(field);
1367  DBUG_PRINT("info", ("Generating LIKE filter: like(%d,%s,%d)",
1368  field->get_field_no(), value->get_val(),
1369  value->pack_length()));
1370  if (filter->cmp(NdbScanFilter::COND_LIKE,
1371  field->get_field_no(),
1372  value->get_val(),
1373  value->pack_length()) == -1)
1374  DBUG_RETURN(1);
1375  cond= cond->next->next->next;
1376  DBUG_RETURN(0);
1377  }
1378  case NDB_NOTLIKE_FUNC:
1379  {
1380  if (!value || !field) break;
1381  if ((value->qualification.value_type != Item::STRING_ITEM) &&
1382  (value->qualification.value_type != Item::VARBIN_ITEM))
1383  break;
1384  // Save value in right format for the field type
1385  value->save_in_field(field);
1386  DBUG_PRINT("info", ("Generating NOTLIKE filter: notlike(%d,%s,%d)",
1387  field->get_field_no(), value->get_val(),
1388  value->pack_length()));
1389  if (filter->cmp(NdbScanFilter::COND_NOT_LIKE,
1390  field->get_field_no(),
1391  value->get_val(),
1392  value->pack_length()) == -1)
1393  DBUG_RETURN(1);
1394  cond= cond->next->next->next;
1395  DBUG_RETURN(0);
1396  }
1397  case NDB_ISNULL_FUNC:
1398  if (!field)
1399  break;
1400  DBUG_PRINT("info", ("Generating ISNULL filter"));
1401  if (filter->isnull(field->get_field_no()) == -1)
1402  DBUG_RETURN(1);
1403  cond= cond->next->next;
1404  DBUG_RETURN(0);
1405  case NDB_ISNOTNULL_FUNC:
1406  {
1407  if (!field)
1408  break;
1409  DBUG_PRINT("info", ("Generating ISNOTNULL filter"));
1410  if (filter->isnotnull(field->get_field_no()) == -1)
1411  DBUG_RETURN(1);
1412  cond= cond->next->next;
1413  DBUG_RETURN(0);
1414  }
1415  default:
1416  break;
1417  }
1418  break;
1419  }
1420  default:
1421  break;
1422  }
1423  DBUG_PRINT("info", ("Found illegal condition"));
1424  DBUG_RETURN(1);
1425 }
1426 
1427 
1428 int
1429 ha_ndbcluster_cond::build_scan_filter_group(Ndb_cond* &cond,
1430  NdbScanFilter *filter)
1431 {
1432  uint level=0;
1433  bool negated= FALSE;
1434  DBUG_ENTER("build_scan_filter_group");
1435 
1436  do
1437  {
1438  if (!cond)
1439  DBUG_RETURN(1);
1440  switch (cond->ndb_item->type) {
1441  case NDB_FUNCTION:
1442  {
1443  switch (cond->ndb_item->qualification.function_type) {
1444  case NDB_COND_AND_FUNC:
1445  {
1446  level++;
1447  DBUG_PRINT("info", ("Generating %s group %u", (negated)?"NAND":"AND",
1448  level));
1449  if ((negated) ? filter->begin(NdbScanFilter::NAND)
1450  : filter->begin(NdbScanFilter::AND) == -1)
1451  DBUG_RETURN(1);
1452  negated= FALSE;
1453  cond= cond->next;
1454  break;
1455  }
1456  case NDB_COND_OR_FUNC:
1457  {
1458  level++;
1459  DBUG_PRINT("info", ("Generating %s group %u", (negated)?"NOR":"OR",
1460  level));
1461  if ((negated) ? filter->begin(NdbScanFilter::NOR)
1462  : filter->begin(NdbScanFilter::OR) == -1)
1463  DBUG_RETURN(1);
1464  negated= FALSE;
1465  cond= cond->next;
1466  break;
1467  }
1468  case NDB_NOT_FUNC:
1469  {
1470  DBUG_PRINT("info", ("Generating negated query"));
1471  cond= cond->next;
1472  negated= TRUE;
1473  break;
1474  }
1475  default:
1476  if (build_scan_filter_predicate(cond, filter, negated))
1477  DBUG_RETURN(1);
1478  negated= FALSE;
1479  break;
1480  }
1481  break;
1482  }
1483  case NDB_END_COND:
1484  DBUG_PRINT("info", ("End of group %u", level));
1485  level--;
1486  if (cond) cond= cond->next;
1487  if (filter->end() == -1)
1488  DBUG_RETURN(1);
1489  if (!negated)
1490  break;
1491  // else fall through (NOT END is an illegal condition)
1492  default:
1493  {
1494  DBUG_PRINT("info", ("Illegal scan filter"));
1495  }
1496  }
1497  } while (level > 0 || negated);
1498 
1499  DBUG_RETURN(0);
1500 }
1501 
1502 
1503 int
1504 ha_ndbcluster_cond::build_scan_filter(Ndb_cond * &cond, NdbScanFilter *filter)
1505 {
1506  bool simple_cond= TRUE;
1507  DBUG_ENTER("build_scan_filter");
1508 
1509  switch (cond->ndb_item->type) {
1510  case NDB_FUNCTION:
1511  switch (cond->ndb_item->qualification.function_type) {
1512  case NDB_COND_AND_FUNC:
1513  case NDB_COND_OR_FUNC:
1514  simple_cond= FALSE;
1515  break;
1516  default:
1517  break;
1518  }
1519  break;
1520  default:
1521  break;
1522  }
1523  if (simple_cond && filter->begin() == -1)
1524  DBUG_RETURN(1);
1525  if (build_scan_filter_group(cond, filter))
1526  DBUG_RETURN(1);
1527  if (simple_cond && filter->end() == -1)
1528  DBUG_RETURN(1);
1529 
1530  DBUG_RETURN(0);
1531 }
1532 
1533 int
1534 ha_ndbcluster_cond::generate_scan_filter(NdbInterpretedCode* code,
1536 {
1537  DBUG_ENTER("generate_scan_filter");
1538 
1539  if (m_cond_stack)
1540  {
1541  NdbScanFilter filter(code);
1542 
1543  int ret= generate_scan_filter_from_cond(filter);
1544  if (ret != 0)
1545  {
1546  const NdbError& err= filter.getNdbError();
1547  if (err.code == NdbScanFilter::FilterTooLarge)
1548  {
1549  // err.message has static storage
1550  DBUG_PRINT("info", ("%s", err.message));
1551  push_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
1552  err.code, err.message);
1553  }
1554  else
1555  DBUG_RETURN(ret);
1556  }
1557  else if (options!=NULL)
1558  {
1559  options->interpretedCode= code;
1560  options->optionsPresent|= NdbScanOperation::ScanOptions::SO_INTERPRETED;
1561  }
1562  }
1563  else
1564  {
1565  DBUG_PRINT("info", ("Empty stack"));
1566  }
1567 
1568  DBUG_RETURN(0);
1569 }
1570 
1571 
1572 int
1573 ha_ndbcluster_cond::generate_scan_filter_from_cond(NdbScanFilter& filter)
1574 {
1575  bool multiple_cond= FALSE;
1576  DBUG_ENTER("generate_scan_filter_from_cond");
1577 
1578  // Wrap an AND group around multiple conditions
1579  if (m_cond_stack->next)
1580  {
1581  multiple_cond= TRUE;
1582  if (filter.begin() == -1)
1583  DBUG_RETURN(1);
1584  }
1585  for (Ndb_cond_stack *stack= m_cond_stack;
1586  (stack);
1587  stack= stack->next)
1588  {
1589  Ndb_cond *cond= stack->ndb_cond;
1590 
1591  if (build_scan_filter(cond, &filter))
1592  {
1593  DBUG_PRINT("info", ("build_scan_filter failed"));
1594  DBUG_RETURN(1);
1595  }
1596  }
1597  if (multiple_cond && filter.end() == -1)
1598  DBUG_RETURN(1);
1599 
1600  DBUG_RETURN(0);
1601 }
1602 
1603 
1604 /*
1605  Optimizer sometimes does hash index lookup of a key where some
1606  key parts are null. The set of cases where this happens makes
1607  no sense but cannot be ignored since optimizer may expect the result
1608  to be filtered accordingly. The scan is actually on the table and
1609  the index bounds are pushed down.
1610 */
1611 int ha_ndbcluster_cond::generate_scan_filter_from_key(NdbInterpretedCode* code,
1613  const KEY* key_info,
1614  const key_range *start_key,
1615  const key_range *end_key,
1616  uchar *buf)
1617 {
1618  DBUG_ENTER("generate_scan_filter_from_key");
1619 
1620 #ifndef DBUG_OFF
1621  {
1622  DBUG_PRINT("info", ("key parts:%u length:%u",
1623  key_info->user_defined_key_parts, key_info->key_length));
1624  const key_range* keylist[2]={ start_key, end_key };
1625  for (uint j=0; j <= 1; j++)
1626  {
1627  char buf[8192];
1628  const key_range* key=keylist[j];
1629  if (key == 0)
1630  {
1631  sprintf(buf, "key range %u: none", j);
1632  }
1633  else
1634  {
1635  sprintf(buf, "key range %u: flag:%u part", j, key->flag);
1636  const KEY_PART_INFO* key_part=key_info->key_part;
1637  const uchar* ptr=key->key;
1638  for (uint i=0; i < key_info->user_defined_key_parts; i++)
1639  {
1640  sprintf(buf+strlen(buf), " %u:", i);
1641  for (uint k=0; k < key_part->store_length; k++)
1642  {
1643  sprintf(buf+strlen(buf), " %02x", ptr[k]);
1644  }
1645  ptr+=key_part->store_length;
1646  if (ptr - key->key >= (ptrdiff_t)key->length)
1647  {
1648  /*
1649  key_range has no count of parts so must test byte length.
1650  But this is not the place for following assert.
1651  */
1652  // DBUG_ASSERT(ptr - key->key == key->length);
1653  break;
1654  }
1655  key_part++;
1656  }
1657  }
1658  DBUG_PRINT("info", ("%s", buf));
1659  }
1660  }
1661 #endif
1662 
1663  NdbScanFilter filter(code);
1664  int res;
1665  filter.begin(NdbScanFilter::AND);
1666  do
1667  {
1668  /*
1669  Case "x is not null".
1670  Seen with index(x) where it becomes range "null < x".
1671  Not seen with index(x,y) for any combination of bounds
1672  which include "is not null".
1673  */
1674  if (start_key != 0 &&
1675  start_key->flag == HA_READ_AFTER_KEY &&
1676  end_key == 0 &&
1677  key_info->user_defined_key_parts == 1)
1678  {
1679  const KEY_PART_INFO* key_part=key_info->key_part;
1680  if (key_part->null_bit != 0) // nullable (must be)
1681  {
1682  const uchar* ptr= start_key->key;
1683  if (ptr[0] != 0) // null (in "null < x")
1684  {
1685  DBUG_PRINT("info", ("Generating ISNOTNULL filter for nullable %s",
1686  key_part->field->field_name));
1687  if (filter.isnotnull(key_part->fieldnr-1) == -1)
1688  DBUG_RETURN(1);
1689  break;
1690  }
1691  }
1692  }
1693 
1694  /*
1695  Case "x is null" in an EQ range.
1696  Seen with index(x) for "x is null".
1697  Seen with index(x,y) for "x is null and y = 1".
1698  Not seen with index(x,y) for "x is null and y is null".
1699  Seen only when all key parts are present (but there is
1700  no reason to limit the code to this case).
1701  */
1702  if (start_key != 0 &&
1703  start_key->flag == HA_READ_KEY_EXACT &&
1704  end_key != 0 &&
1705  end_key->flag == HA_READ_AFTER_KEY &&
1706  start_key->length == end_key->length &&
1707  memcmp(start_key->key, end_key->key, start_key->length) == 0)
1708  {
1709  const KEY_PART_INFO* key_part=key_info->key_part;
1710  const uchar* ptr=start_key->key;
1711  for (uint i=0; i < key_info->user_defined_key_parts; i++)
1712  {
1713  const Field* field=key_part->field;
1714  if (key_part->null_bit) // nullable
1715  {
1716  if (ptr[0] != 0) // null
1717  {
1718  DBUG_PRINT("info", ("Generating ISNULL filter for nullable %s",
1719  field->field_name));
1720  if (filter.isnull(key_part->fieldnr-1) == -1)
1721  DBUG_RETURN(1);
1722  }
1723  else
1724  {
1725  DBUG_PRINT("info", ("Generating EQ filter for nullable %s",
1726  field->field_name));
1727  if (filter.cmp(NdbScanFilter::COND_EQ,
1728  key_part->fieldnr-1,
1729  ptr + 1, // skip null-indicator byte
1730  field->pack_length()) == -1)
1731  DBUG_RETURN(1);
1732  }
1733  }
1734  else
1735  {
1736  DBUG_PRINT("info", ("Generating EQ filter for non-nullable %s",
1737  field->field_name));
1738  if (filter.cmp(NdbScanFilter::COND_EQ,
1739  key_part->fieldnr-1,
1740  ptr,
1741  field->pack_length()) == -1)
1742  DBUG_RETURN(1);
1743  }
1744  ptr+=key_part->store_length;
1745  if (ptr - start_key->key >= (ptrdiff_t)start_key->length)
1746  {
1747  break;
1748  }
1749  key_part++;
1750  }
1751  break;
1752  }
1753 
1754  DBUG_PRINT("info", ("Unknown hash index scan"));
1755  // enable to catch new cases when optimizer changes
1756  // DBUG_ASSERT(false);
1757  }
1758  while (0);
1759 
1760  // Add any pushed condition
1761  if (m_cond_stack &&
1762  (res= generate_scan_filter_from_cond(filter)))
1763  DBUG_RETURN(res);
1764 
1765  if (filter.end() == -1)
1766  DBUG_RETURN(1);
1767 
1768  if (options!=NULL)
1769  {
1770  options->interpretedCode= code;
1771  options->optionsPresent|= NdbScanOperation::ScanOptions::SO_INTERPRETED;
1772  }
1773 
1774  DBUG_RETURN(0);
1775 }
1776 
1777 #endif