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