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