~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2003 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
17
/* compare and test functions */
18
19
#ifdef USE_PRAGMA_INTERFACE
20
#pragma interface			/* gcc class implementation */
21
#endif
22
23
extern Item_result item_cmp_type(Item_result a,Item_result b);
24
class Item_bool_func2;
25
class Arg_comparator;
26
27
typedef int (Arg_comparator::*arg_cmp_func)();
28
29
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg); 
30
31
class Arg_comparator: public Sql_alloc
32
{
33
  Item **a, **b;
34
  arg_cmp_func func;
35
  Item_bool_func2 *owner;
36
  Arg_comparator *comparators;   // used only for compare_row()
37
  double precision;
38
  /* Fields used in DATE/DATETIME comparison. */
39
  THD *thd;
40
  enum_field_types a_type, b_type; // Types of a and b items
41
  Item *a_cache, *b_cache;         // Cached values of a and b items
42
  bool is_nulls_eq;                // TRUE <=> compare for the EQUAL_FUNC
43
  enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
44
                            CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
45
  ulonglong (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg,
46
                              Item *warn_item, bool *is_null);
47
public:
48
  DTCollation cmp_collation;
49
50
  Arg_comparator(): thd(0), a_cache(0), b_cache(0) {};
51
  Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), thd(0),
52
    a_cache(0), b_cache(0) {};
53
54
  int set_compare_func(Item_bool_func2 *owner, Item_result type);
55
  inline int set_compare_func(Item_bool_func2 *owner_arg)
56
  {
57
    return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(),
58
                                                     (*b)->result_type()));
59
  }
60
  int set_cmp_func(Item_bool_func2 *owner_arg,
61
			  Item **a1, Item **a2,
62
			  Item_result type);
63
64
  inline int set_cmp_func(Item_bool_func2 *owner_arg,
65
			  Item **a1, Item **a2)
66
  {
67
    return set_cmp_func(owner_arg, a1, a2,
68
                        item_cmp_type((*a1)->result_type(),
69
                                      (*a2)->result_type()));
70
  }
71
  inline int compare() { return (this->*func)(); }
72
73
  int compare_string();		 // compare args[0] & args[1]
74
  int compare_binary_string();	 // compare args[0] & args[1]
75
  int compare_real();            // compare args[0] & args[1]
76
  int compare_decimal();         // compare args[0] & args[1]
77
  int compare_int_signed();      // compare args[0] & args[1]
78
  int compare_int_signed_unsigned();
79
  int compare_int_unsigned_signed();
80
  int compare_int_unsigned();
81
  int compare_row();             // compare args[0] & args[1]
82
  int compare_e_string();	 // compare args[0] & args[1]
83
  int compare_e_binary_string(); // compare args[0] & args[1]
84
  int compare_e_real();          // compare args[0] & args[1]
85
  int compare_e_decimal();       // compare args[0] & args[1]
86
  int compare_e_int();           // compare args[0] & args[1]
87
  int compare_e_int_diff_signedness();
88
  int compare_e_row();           // compare args[0] & args[1]
89
  int compare_real_fixed();
90
  int compare_e_real_fixed();
91
  int compare_datetime();        // compare args[0] & args[1] as DATETIMEs
92
93
  static enum enum_date_cmp_type can_compare_as_dates(Item *a, Item *b,
94
                                                      ulonglong *const_val_arg);
95
96
  void set_datetime_cmp_func(Item **a1, Item **b1);
97
  static arg_cmp_func comparator_matrix [5][2];
98
99
  friend class Item_func;
100
};
101
102
class Item_bool_func :public Item_int_func
103
{
104
public:
105
  Item_bool_func() :Item_int_func() {}
106
  Item_bool_func(Item *a) :Item_int_func(a) {}
107
  Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
108
  Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {}
109
  bool is_bool_func() { return 1; }
110
  void fix_length_and_dec() { decimals=0; max_length=1; }
111
  uint decimal_precision() const { return 1; }
112
};
113
114
115
/**
116
  Abstract Item class, to represent <code>X IS [NOT] (TRUE | FALSE)</code>
117
  boolean predicates.
118
*/
119
120
class Item_func_truth : public Item_bool_func
121
{
122
public:
123
  virtual bool val_bool();
124
  virtual longlong val_int();
125
  virtual void fix_length_and_dec();
126
  virtual void print(String *str, enum_query_type query_type);
127
128
protected:
129
  Item_func_truth(Item *a, bool a_value, bool a_affirmative)
130
  : Item_bool_func(a), value(a_value), affirmative(a_affirmative)
131
  {}
132
133
  ~Item_func_truth()
134
  {}
135
private:
136
  /**
137
    True for <code>X IS [NOT] TRUE</code>,
138
    false for <code>X IS [NOT] FALSE</code> predicates.
139
  */
140
  const bool value;
141
  /**
142
    True for <code>X IS Y</code>, false for <code>X IS NOT Y</code> predicates.
143
  */
144
  const bool affirmative;
145
};
146
147
148
/**
149
  This Item represents a <code>X IS TRUE</code> boolean predicate.
150
*/
151
152
class Item_func_istrue : public Item_func_truth
153
{
154
public:
155
  Item_func_istrue(Item *a) : Item_func_truth(a, true, true) {}
156
  ~Item_func_istrue() {}
157
  virtual const char* func_name() const { return "istrue"; }
158
};
159
160
161
/**
162
  This Item represents a <code>X IS NOT TRUE</code> boolean predicate.
163
*/
164
165
class Item_func_isnottrue : public Item_func_truth
166
{
167
public:
168
  Item_func_isnottrue(Item *a) : Item_func_truth(a, true, false) {}
169
  ~Item_func_isnottrue() {}
170
  virtual const char* func_name() const { return "isnottrue"; }
171
};
172
173
174
/**
175
  This Item represents a <code>X IS FALSE</code> boolean predicate.
176
*/
177
178
class Item_func_isfalse : public Item_func_truth
179
{
180
public:
181
  Item_func_isfalse(Item *a) : Item_func_truth(a, false, true) {}
182
  ~Item_func_isfalse() {}
183
  virtual const char* func_name() const { return "isfalse"; }
184
};
185
186
187
/**
188
  This Item represents a <code>X IS NOT FALSE</code> boolean predicate.
189
*/
190
191
class Item_func_isnotfalse : public Item_func_truth
192
{
193
public:
194
  Item_func_isnotfalse(Item *a) : Item_func_truth(a, false, false) {}
195
  ~Item_func_isnotfalse() {}
196
  virtual const char* func_name() const { return "isnotfalse"; }
197
};
198
199
200
class Item_cache;
201
#define UNKNOWN ((my_bool)-1)
202
203
204
/*
205
  Item_in_optimizer(left_expr, Item_in_subselect(...))
206
207
  Item_in_optimizer is used to wrap an instance of Item_in_subselect. This
208
  class does the following:
209
   - Evaluate the left expression and store it in Item_cache_* object (to
210
     avoid re-evaluating it many times during subquery execution)
211
   - Shortcut the evaluation of "NULL IN (...)" to NULL in the cases where we
212
     don't care if the result is NULL or FALSE.
213
214
  NOTE
215
    It is not quite clear why the above listed functionality should be
216
    placed into a separate class called 'Item_in_optimizer'.
217
*/
218
219
class Item_in_optimizer: public Item_bool_func
220
{
221
protected:
222
  Item_cache *cache;
223
  bool save_cache;
224
  /* 
225
    Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
226
      UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
227
      FALSE   - result is FALSE
228
      TRUE    - result is NULL
229
  */
230
  my_bool result_for_null_param;
231
public:
232
  Item_in_optimizer(Item *a, Item_in_subselect *b):
233
    Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0),
234
    save_cache(0), result_for_null_param(UNKNOWN)
235
  { with_subselect= TRUE; }
236
  bool fix_fields(THD *, Item **);
237
  bool fix_left(THD *thd, Item **ref);
238
  bool is_null();
239
  longlong val_int();
240
  void cleanup();
241
  const char *func_name() const { return "<in_optimizer>"; }
242
  Item_cache **get_cache() { return &cache; }
243
  void keep_top_level_cache();
244
  Item *transform(Item_transformer transformer, uchar *arg);
245
};
246
247
class Comp_creator
248
{
249
public:
250
  Comp_creator() {}                           /* Remove gcc warning */
251
  virtual ~Comp_creator() {}                  /* Remove gcc warning */
252
  virtual Item_bool_func2* create(Item *a, Item *b) const = 0;
253
  virtual const char* symbol(bool invert) const = 0;
254
  virtual bool eqne_op() const = 0;
255
  virtual bool l_op() const = 0;
256
};
257
258
class Eq_creator :public Comp_creator
259
{
260
public:
261
  Eq_creator() {}                             /* Remove gcc warning */
262
  virtual ~Eq_creator() {}                    /* Remove gcc warning */
263
  virtual Item_bool_func2* create(Item *a, Item *b) const;
264
  virtual const char* symbol(bool invert) const { return invert? "<>" : "="; }
265
  virtual bool eqne_op() const { return 1; }
266
  virtual bool l_op() const { return 0; }
267
};
268
269
class Ne_creator :public Comp_creator
270
{
271
public:
272
  Ne_creator() {}                             /* Remove gcc warning */
273
  virtual ~Ne_creator() {}                    /* Remove gcc warning */
274
  virtual Item_bool_func2* create(Item *a, Item *b) const;
275
  virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; }
276
  virtual bool eqne_op() const { return 1; }
277
  virtual bool l_op() const { return 0; }
278
};
279
280
class Gt_creator :public Comp_creator
281
{
282
public:
283
  Gt_creator() {}                             /* Remove gcc warning */
284
  virtual ~Gt_creator() {}                    /* Remove gcc warning */
285
  virtual Item_bool_func2* create(Item *a, Item *b) const;
286
  virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
287
  virtual bool eqne_op() const { return 0; }
288
  virtual bool l_op() const { return 0; }
289
};
290
291
class Lt_creator :public Comp_creator
292
{
293
public:
294
  Lt_creator() {}                             /* Remove gcc warning */
295
  virtual ~Lt_creator() {}                    /* Remove gcc warning */
296
  virtual Item_bool_func2* create(Item *a, Item *b) const;
297
  virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
298
  virtual bool eqne_op() const { return 0; }
299
  virtual bool l_op() const { return 1; }
300
};
301
302
class Ge_creator :public Comp_creator
303
{
304
public:
305
  Ge_creator() {}                             /* Remove gcc warning */
306
  virtual ~Ge_creator() {}                    /* Remove gcc warning */
307
  virtual Item_bool_func2* create(Item *a, Item *b) const;
308
  virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
309
  virtual bool eqne_op() const { return 0; }
310
  virtual bool l_op() const { return 0; }
311
};
312
313
class Le_creator :public Comp_creator
314
{
315
public:
316
  Le_creator() {}                             /* Remove gcc warning */
317
  virtual ~Le_creator() {}                    /* Remove gcc warning */
318
  virtual Item_bool_func2* create(Item *a, Item *b) const;
319
  virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
320
  virtual bool eqne_op() const { return 0; }
321
  virtual bool l_op() const { return 1; }
322
};
323
324
class Item_bool_func2 :public Item_int_func
325
{						/* Bool with 2 string args */
326
protected:
327
  Arg_comparator cmp;
328
  String tmp_value1,tmp_value2;
329
  bool abort_on_null;
330
331
public:
332
  Item_bool_func2(Item *a,Item *b)
333
    :Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1), abort_on_null(FALSE) {}
334
  void fix_length_and_dec();
335
  void set_cmp_func()
336
  {
337
    cmp.set_cmp_func(this, tmp_arg, tmp_arg+1);
338
  }
339
  optimize_type select_optimize() const { return OPTIMIZE_OP; }
340
  virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
341
  bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
342
343
  virtual inline void print(String *str, enum_query_type query_type)
344
  {
345
    Item_func::print_op(str, query_type);
346
  }
347
348
  bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
349
  bool is_bool_func() { return 1; }
350
  CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
351
  uint decimal_precision() const { return 1; }
352
  void top_level_item() { abort_on_null= TRUE; }
353
354
  friend class  Arg_comparator;
355
};
356
357
class Item_bool_rowready_func2 :public Item_bool_func2
358
{
359
public:
360
  Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b)
361
  {
362
    allowed_arg_cols= 0;  // Fetch this value from first argument
363
  }
364
  Item *neg_transformer(THD *thd);
365
  virtual Item *negated_item();
77.1.7 by Monty Taylor
Heap builds clean.
366
  bool subst_argument_checker(uchar **arg __attribute__((__unused__)))
367
  { return TRUE; }
1 by brian
clean slate
368
};
369
370
class Item_func_not :public Item_bool_func
371
{
372
public:
373
  Item_func_not(Item *a) :Item_bool_func(a) {}
374
  longlong val_int();
375
  enum Functype functype() const { return NOT_FUNC; }
376
  const char *func_name() const { return "not"; }
377
  Item *neg_transformer(THD *thd);
378
  virtual void print(String *str, enum_query_type query_type);
379
};
380
381
class Item_maxmin_subselect;
382
383
/*
384
  trigcond<param>(arg) ::= param? arg : TRUE
385
386
  The class Item_func_trig_cond is used for guarded predicates 
387
  which are employed only for internal purposes.
388
  A guarded predicate is an object consisting of an a regular or
389
  a guarded predicate P and a pointer to a boolean guard variable g. 
390
  A guarded predicate P/g is evaluated to true if the value of the
391
  guard g is false, otherwise it is evaluated to the same value that
392
  the predicate P: val(P/g)= g ? val(P):true.
393
  Guarded predicates allow us to include predicates into a conjunction
394
  conditionally. Currently they are utilized for pushed down predicates
395
  in queries with outer join operations.
396
397
  In the future, probably, it makes sense to extend this class to
398
  the objects consisting of three elements: a predicate P, a pointer
399
  to a variable g and a firing value s with following evaluation
400
  rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
401
  one item for the objects of the form P/g1/g2... 
402
403
  Objects of this class are built only for query execution after
404
  the execution plan has been already selected. That's why this
405
  class needs only val_int out of generic methods. 
406
 
407
  Current uses of Item_func_trig_cond objects:
408
   - To wrap selection conditions when executing outer joins
409
   - To wrap condition that is pushed down into subquery
410
*/
411
412
class Item_func_trig_cond: public Item_bool_func
413
{
414
  bool *trig_var;
415
public:
416
  Item_func_trig_cond(Item *a, bool *f) : Item_bool_func(a) { trig_var= f; }
417
  longlong val_int() { return *trig_var ? args[0]->val_int() : 1; }
418
  enum Functype functype() const { return TRIG_COND_FUNC; };
419
  const char *func_name() const { return "trigcond"; };
420
  bool const_item() const { return FALSE; }
421
  bool *get_trig_var() { return trig_var; }
422
  /* The following is needed for ICP: */
423
  table_map used_tables() const { return args[0]->used_tables(); }
424
};
425
426
class Item_func_not_all :public Item_func_not
427
{
428
  /* allow to check presence of values in max/min optimization */
429
  Item_sum_hybrid *test_sum_item;
430
  Item_maxmin_subselect *test_sub_item;
431
432
  bool abort_on_null;
433
public:
434
  bool show;
435
436
  Item_func_not_all(Item *a)
437
    :Item_func_not(a), test_sum_item(0), test_sub_item(0), abort_on_null(0),
438
     show(0)
439
    {}
440
  virtual void top_level_item() { abort_on_null= 1; }
441
  bool top_level() { return abort_on_null; }
442
  longlong val_int();
443
  enum Functype functype() const { return NOT_ALL_FUNC; }
444
  const char *func_name() const { return "<not>"; }
445
  virtual void print(String *str, enum_query_type query_type);
446
  void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
447
  void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
448
  bool empty_underlying_subquery();
449
  Item *neg_transformer(THD *thd);
450
};
451
452
453
class Item_func_nop_all :public Item_func_not_all
454
{
455
public:
456
457
  Item_func_nop_all(Item *a) :Item_func_not_all(a) {}
458
  longlong val_int();
459
  const char *func_name() const { return "<nop>"; }
460
  Item *neg_transformer(THD *thd);
461
};
462
463
464
class Item_func_eq :public Item_bool_rowready_func2
465
{
466
public:
467
  Item_func_eq(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
468
  longlong val_int();
469
  enum Functype functype() const { return EQ_FUNC; }
470
  enum Functype rev_functype() const { return EQ_FUNC; }
471
  cond_result eq_cmp_result() const { return COND_TRUE; }
472
  const char *func_name() const { return "="; }
473
  Item *negated_item();
474
};
475
476
class Item_func_equal :public Item_bool_rowready_func2
477
{
478
public:
479
  Item_func_equal(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
480
  longlong val_int();
481
  void fix_length_and_dec();
482
  table_map not_null_tables() const { return 0; }
483
  enum Functype functype() const { return EQUAL_FUNC; }
484
  enum Functype rev_functype() const { return EQUAL_FUNC; }
485
  cond_result eq_cmp_result() const { return COND_TRUE; }
486
  const char *func_name() const { return "<=>"; }
77.1.7 by Monty Taylor
Heap builds clean.
487
  Item *neg_transformer(THD *thd __attribute__((__unused__))) { return 0; }
1 by brian
clean slate
488
};
489
490
491
class Item_func_ge :public Item_bool_rowready_func2
492
{
493
public:
494
  Item_func_ge(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
495
  longlong val_int();
496
  enum Functype functype() const { return GE_FUNC; }
497
  enum Functype rev_functype() const { return LE_FUNC; }
498
  cond_result eq_cmp_result() const { return COND_TRUE; }
499
  const char *func_name() const { return ">="; }
500
  Item *negated_item();
501
};
502
503
504
class Item_func_gt :public Item_bool_rowready_func2
505
{
506
public:
507
  Item_func_gt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
508
  longlong val_int();
509
  enum Functype functype() const { return GT_FUNC; }
510
  enum Functype rev_functype() const { return LT_FUNC; }
511
  cond_result eq_cmp_result() const { return COND_FALSE; }
512
  const char *func_name() const { return ">"; }
513
  Item *negated_item();
514
};
515
516
517
class Item_func_le :public Item_bool_rowready_func2
518
{
519
public:
520
  Item_func_le(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
521
  longlong val_int();
522
  enum Functype functype() const { return LE_FUNC; }
523
  enum Functype rev_functype() const { return GE_FUNC; }
524
  cond_result eq_cmp_result() const { return COND_TRUE; }
525
  const char *func_name() const { return "<="; }
526
  Item *negated_item();
527
};
528
529
530
class Item_func_lt :public Item_bool_rowready_func2
531
{
532
public:
533
  Item_func_lt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
534
  longlong val_int();
535
  enum Functype functype() const { return LT_FUNC; }
536
  enum Functype rev_functype() const { return GT_FUNC; }
537
  cond_result eq_cmp_result() const { return COND_FALSE; }
538
  const char *func_name() const { return "<"; }
539
  Item *negated_item();
540
};
541
542
543
class Item_func_ne :public Item_bool_rowready_func2
544
{
545
public:
546
  Item_func_ne(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
547
  longlong val_int();
548
  enum Functype functype() const { return NE_FUNC; }
549
  cond_result eq_cmp_result() const { return COND_FALSE; }
550
  optimize_type select_optimize() const { return OPTIMIZE_KEY; } 
551
  const char *func_name() const { return "<>"; }
552
  Item *negated_item();
553
};
554
555
556
/*
557
  The class Item_func_opt_neg is defined to factor out the functionality
558
  common for the classes Item_func_between and Item_func_in. The objects
559
  of these classes can express predicates or there negations.
560
  The alternative approach would be to create pairs Item_func_between,
561
  Item_func_notbetween and Item_func_in, Item_func_notin.
562
563
*/
564
565
class Item_func_opt_neg :public Item_int_func
566
{
567
public:
568
  bool negated;     /* <=> the item represents NOT <func> */
569
  bool pred_level;  /* <=> [NOT] <func> is used on a predicate level */
570
public:
571
  Item_func_opt_neg(Item *a, Item *b, Item *c)
572
    :Item_int_func(a, b, c), negated(0), pred_level(0) {}
573
  Item_func_opt_neg(List<Item> &list)
574
    :Item_int_func(list), negated(0), pred_level(0) {}
575
public:
576
  inline void negate() { negated= !negated; }
577
  inline void top_level_item() { pred_level= 1; }
77.1.7 by Monty Taylor
Heap builds clean.
578
  Item *neg_transformer(THD *thd __attribute__((__unused__)))
1 by brian
clean slate
579
  {
580
    negated= !negated;
581
    return this;
582
  }
583
  bool eq(const Item *item, bool binary_cmp) const;
77.1.7 by Monty Taylor
Heap builds clean.
584
  bool subst_argument_checker(uchar **arg __attribute__((__unused__)))
585
  { return TRUE; }
1 by brian
clean slate
586
};
587
588
589
class Item_func_between :public Item_func_opt_neg
590
{
591
  DTCollation cmp_collation;
592
public:
593
  Item_result cmp_type;
594
  String value0,value1,value2;
595
  /* TRUE <=> arguments will be compared as dates. */
596
  bool compare_as_dates;
597
  /* Comparators used for DATE/DATETIME comparison. */
598
  Arg_comparator ge_cmp, le_cmp;
599
  Item_func_between(Item *a, Item *b, Item *c)
600
    :Item_func_opt_neg(a, b, c), compare_as_dates(FALSE) {}
601
  longlong val_int();
602
  optimize_type select_optimize() const { return OPTIMIZE_KEY; }
603
  enum Functype functype() const   { return BETWEEN; }
604
  const char *func_name() const { return "between"; }
605
  bool fix_fields(THD *, Item **);
606
  void fix_length_and_dec();
607
  virtual void print(String *str, enum_query_type query_type);
608
  bool is_bool_func() { return 1; }
609
  CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
610
  uint decimal_precision() const { return 1; }
611
};
612
613
614
class Item_func_strcmp :public Item_bool_func2
615
{
616
public:
617
  Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {}
618
  longlong val_int();
619
  optimize_type select_optimize() const { return OPTIMIZE_NONE; }
620
  const char *func_name() const { return "strcmp"; }
621
622
  virtual inline void print(String *str, enum_query_type query_type)
623
  {
624
    Item_func::print(str, query_type);
625
  }
626
};
627
628
629
struct interval_range
630
{
631
  Item_result type;
632
  double dbl;
633
  my_decimal dec;
634
};
635
636
class Item_func_interval :public Item_int_func
637
{
638
  Item_row *row;
639
  my_bool use_decimal_comparison;
640
  interval_range *intervals;
641
public:
642
  Item_func_interval(Item_row *a)
643
    :Item_int_func(a),row(a),intervals(0)
644
  {
645
    allowed_arg_cols= 0;    // Fetch this value from first argument
646
  }
647
  longlong val_int();
648
  void fix_length_and_dec();
649
  const char *func_name() const { return "interval"; }
650
  uint decimal_precision() const { return 2; }
651
};
652
653
654
class Item_func_coalesce :public Item_func_numhybrid
655
{
656
protected:
657
  enum_field_types cached_field_type;
658
  Item_func_coalesce(Item *a, Item *b) :Item_func_numhybrid(a, b) {}
659
public:
660
  Item_func_coalesce(List<Item> &list) :Item_func_numhybrid(list) {}
661
  double real_op();
662
  longlong int_op();
663
  String *str_op(String *);
664
  my_decimal *decimal_op(my_decimal *);
665
  void fix_length_and_dec();
666
  void find_num_type() {}
667
  enum Item_result result_type () const { return hybrid_type; }
668
  const char *func_name() const { return "coalesce"; }
669
  table_map not_null_tables() const { return 0; }
670
  enum_field_types field_type() const { return cached_field_type; }
671
};
672
673
674
class Item_func_ifnull :public Item_func_coalesce
675
{
676
protected:
677
  bool field_type_defined;
678
public:
679
  Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
680
  double real_op();
681
  longlong int_op();
682
  String *str_op(String *str);
683
  my_decimal *decimal_op(my_decimal *);
684
  enum_field_types field_type() const;
685
  void fix_length_and_dec();
686
  const char *func_name() const { return "ifnull"; }
687
  Field *tmp_table_field(TABLE *table);
688
  uint decimal_precision() const;
689
};
690
691
692
class Item_func_if :public Item_func
693
{
694
  enum Item_result cached_result_type;
695
  enum_field_types cached_field_type;
696
public:
697
  Item_func_if(Item *a,Item *b,Item *c)
698
    :Item_func(a,b,c), cached_result_type(INT_RESULT)
699
  {}
700
  double val_real();
701
  longlong val_int();
702
  String *val_str(String *str);
703
  my_decimal *val_decimal(my_decimal *);
704
  enum Item_result result_type () const { return cached_result_type; }
705
  enum_field_types field_type() const { return cached_field_type; }
706
  bool fix_fields(THD *, Item **);
707
  void fix_length_and_dec();
708
  uint decimal_precision() const;
709
  const char *func_name() const { return "if"; }
710
};
711
712
713
class Item_func_nullif :public Item_bool_func2
714
{
715
  enum Item_result cached_result_type;
716
public:
717
  Item_func_nullif(Item *a,Item *b)
718
    :Item_bool_func2(a,b), cached_result_type(INT_RESULT)
719
  {}
720
  double val_real();
721
  longlong val_int();
722
  String *val_str(String *str);
723
  my_decimal *val_decimal(my_decimal *);
724
  enum Item_result result_type () const { return cached_result_type; }
725
  void fix_length_and_dec();
726
  uint decimal_precision() const { return args[0]->decimal_precision(); }
727
  const char *func_name() const { return "nullif"; }
728
729
  virtual inline void print(String *str, enum_query_type query_type)
730
  {
731
    Item_func::print(str, query_type);
732
  }
733
734
  table_map not_null_tables() const { return 0; }
735
  bool is_null();
736
};
737
738
739
/* Functions to handle the optimized IN */
740
741
742
/* A vector of values of some type  */
743
744
class in_vector :public Sql_alloc
745
{
746
public:
747
  char *base;
748
  uint size;
749
  qsort2_cmp compare;
750
  CHARSET_INFO *collation;
751
  uint count;
752
  uint used_count;
753
  in_vector() {}
754
  in_vector(uint elements,uint element_length,qsort2_cmp cmp_func, 
755
  	    CHARSET_INFO *cmp_coll)
756
    :base((char*) sql_calloc(elements*element_length)),
757
     size(element_length), compare(cmp_func), collation(cmp_coll),
758
     count(elements), used_count(elements) {}
759
  virtual ~in_vector() {}
760
  virtual void set(uint pos,Item *item)=0;
761
  virtual uchar *get_value(Item *item)=0;
762
  void sort()
763
  {
764
    my_qsort2(base,used_count,size,compare,collation);
765
  }
766
  int find(Item *item);
767
  
768
  /* 
769
    Create an instance of Item_{type} (e.g. Item_decimal) constant object
770
    which type allows it to hold an element of this vector without any
771
    conversions.
772
    The purpose of this function is to be able to get elements of this
773
    vector in form of Item_xxx constants without creating Item_xxx object
774
    for every array element you get (i.e. this implements "FlyWeight" pattern)
775
  */
776
  virtual Item* create_item() { return NULL; }
777
  
778
  /*
779
    Store the value at position #pos into provided item object
780
    SYNOPSIS
781
      value_to_item()
782
        pos   Index of value to store
783
        item  Constant item to store value into. The item must be of the same
784
              type that create_item() returns.
785
  */
77.1.7 by Monty Taylor
Heap builds clean.
786
  virtual void value_to_item(uint pos __attribute__((__unused__)),
787
                             Item *item __attribute__((__unused__))) { }
1 by brian
clean slate
788
  
789
  /* Compare values number pos1 and pos2 for equality */
790
  bool compare_elems(uint pos1, uint pos2)
791
  {
792
    return test(compare(collation, base + pos1*size, base + pos2*size));
793
  }
794
  virtual Item_result result_type()= 0;
795
};
796
797
class in_string :public in_vector
798
{
799
  char buff[STRING_BUFFER_USUAL_SIZE];
800
  String tmp;
801
public:
802
  in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs);
803
  ~in_string();
804
  void set(uint pos,Item *item);
805
  uchar *get_value(Item *item);
806
  Item* create_item()
807
  { 
808
    return new Item_string(collation);
809
  }
810
  void value_to_item(uint pos, Item *item)
811
  {    
812
    String *str=((String*) base)+pos;
813
    Item_string *to= (Item_string*)item;
814
    to->str_value= *str;
815
  }
816
  Item_result result_type() { return STRING_RESULT; }
817
};
818
819
class in_longlong :public in_vector
820
{
821
protected:
822
  /*
823
    Here we declare a temporary variable (tmp) of the same type as the
824
    elements of this vector. tmp is used in finding if a given value is in 
825
    the list. 
826
  */
827
  struct packed_longlong 
828
  {
829
    longlong val;
830
    longlong unsigned_flag;  // Use longlong, not bool, to preserve alignment
831
  } tmp;
832
public:
833
  in_longlong(uint elements);
834
  void set(uint pos,Item *item);
835
  uchar *get_value(Item *item);
836
  
837
  Item* create_item()
838
  { 
839
    /* 
840
      We're created a signed INT, this may not be correct in 
841
      general case (see BUG#19342).
842
    */
843
    return new Item_int((longlong)0);
844
  }
845
  void value_to_item(uint pos, Item *item)
846
  {
847
    ((Item_int*) item)->value= ((packed_longlong*) base)[pos].val;
848
    ((Item_int*) item)->unsigned_flag= (my_bool)
849
      ((packed_longlong*) base)[pos].unsigned_flag;
850
  }
851
  Item_result result_type() { return INT_RESULT; }
852
853
  friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
854
};
855
856
857
/*
858
  Class to represent a vector of constant DATE/DATETIME values.
859
  Values are obtained with help of the get_datetime_value() function.
860
  If the left item is a constant one then its value is cached in the
861
  lval_cache variable.
862
*/
863
class in_datetime :public in_longlong
864
{
865
public:
866
  THD *thd;
867
  /* An item used to issue warnings. */
868
  Item *warn_item;
869
  /* Cache for the left item. */
870
  Item *lval_cache;
871
872
  in_datetime(Item *warn_item_arg, uint elements)
873
    :in_longlong(elements), thd(current_thd), warn_item(warn_item_arg),
874
     lval_cache(0) {};
875
  void set(uint pos,Item *item);
876
  uchar *get_value(Item *item);
877
  friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
878
};
879
880
881
class in_double :public in_vector
882
{
883
  double tmp;
884
public:
885
  in_double(uint elements);
886
  void set(uint pos,Item *item);
887
  uchar *get_value(Item *item);
888
  Item *create_item()
889
  { 
890
    return new Item_float(0.0, 0);
891
  }
892
  void value_to_item(uint pos, Item *item)
893
  {
894
    ((Item_float*)item)->value= ((double*) base)[pos];
895
  }
896
  Item_result result_type() { return REAL_RESULT; }
897
};
898
899
900
class in_decimal :public in_vector
901
{
902
  my_decimal val;
903
public:
904
  in_decimal(uint elements);
905
  void set(uint pos, Item *item);
906
  uchar *get_value(Item *item);
907
  Item *create_item()
908
  { 
909
    return new Item_decimal(0, FALSE);
910
  }
911
  void value_to_item(uint pos, Item *item)
912
  {
913
    my_decimal *dec= ((my_decimal *)base) + pos;
914
    Item_decimal *item_dec= (Item_decimal*)item;
915
    item_dec->set_decimal_value(dec);
916
  }
917
  Item_result result_type() { return DECIMAL_RESULT; }
918
919
};
920
921
922
/*
923
** Classes for easy comparing of non const items
924
*/
925
926
class cmp_item :public Sql_alloc
927
{
928
public:
929
  CHARSET_INFO *cmp_charset;
930
  cmp_item() { cmp_charset= &my_charset_bin; }
931
  virtual ~cmp_item() {}
932
  virtual void store_value(Item *item)= 0;
933
  virtual int cmp(Item *item)= 0;
934
  // for optimized IN with row
935
  virtual int compare(cmp_item *item)= 0;
936
  static cmp_item* get_comparator(Item_result type, CHARSET_INFO *cs);
937
  virtual cmp_item *make_same()= 0;
77.1.7 by Monty Taylor
Heap builds clean.
938
  virtual void store_value_by_template(cmp_item *tmpl  __attribute__((__unused__)),
939
                                       Item *item)
1 by brian
clean slate
940
  {
941
    store_value(item);
942
  }
943
};
944
945
class cmp_item_string :public cmp_item 
946
{
947
protected:
948
  String *value_res;
949
public:
950
  cmp_item_string () {}
951
  cmp_item_string (CHARSET_INFO *cs) { cmp_charset= cs; }
952
  void set_charset(CHARSET_INFO *cs) { cmp_charset= cs; }
953
  friend class cmp_item_sort_string;
954
  friend class cmp_item_sort_string_in_static;
955
};
956
957
class cmp_item_sort_string :public cmp_item_string
958
{
959
protected:
960
  char value_buff[STRING_BUFFER_USUAL_SIZE];
961
  String value;
962
public:
963
  cmp_item_sort_string():
964
    cmp_item_string() {}
965
  cmp_item_sort_string(CHARSET_INFO *cs):
966
    cmp_item_string(cs),
967
    value(value_buff, sizeof(value_buff), cs) {}
968
  void store_value(Item *item)
969
  {
970
    value_res= item->val_str(&value);
971
  }
972
  int cmp(Item *arg)
973
  {
974
    char buff[STRING_BUFFER_USUAL_SIZE];
975
    String tmp(buff, sizeof(buff), cmp_charset), *res;
976
    res= arg->val_str(&tmp);
977
    return (value_res ? (res ? sortcmp(value_res, res, cmp_charset) : 1) :
978
            (res ? -1 : 0));
979
  }
980
  int compare(cmp_item *ci)
981
  {
982
    cmp_item_string *l_cmp= (cmp_item_string *) ci;
983
    return sortcmp(value_res, l_cmp->value_res, cmp_charset);
984
  } 
985
  cmp_item *make_same();
986
  void set_charset(CHARSET_INFO *cs)
987
  {
988
    cmp_charset= cs;
989
    value.set_quick(value_buff, sizeof(value_buff), cs);
990
  }
991
};
992
993
class cmp_item_int :public cmp_item
994
{
995
  longlong value;
996
public:
997
  cmp_item_int() {}                           /* Remove gcc warning */
998
  void store_value(Item *item)
999
  {
1000
    value= item->val_int();
1001
  }
1002
  int cmp(Item *arg)
1003
  {
1004
    return value != arg->val_int();
1005
  }
1006
  int compare(cmp_item *ci)
1007
  {
1008
    cmp_item_int *l_cmp= (cmp_item_int *)ci;
1009
    return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
1010
  }
1011
  cmp_item *make_same();
1012
};
1013
1014
/*
1015
  Compare items in the DATETIME context.
1016
  Values are obtained with help of the get_datetime_value() function.
1017
  If the left item is a constant one then its value is cached in the
1018
  lval_cache variable.
1019
*/
1020
class cmp_item_datetime :public cmp_item
1021
{
1022
  ulonglong value;
1023
public:
1024
  THD *thd;
1025
  /* Item used for issuing warnings. */
1026
  Item *warn_item;
1027
  /* Cache for the left item. */
1028
  Item *lval_cache;
1029
1030
  cmp_item_datetime(Item *warn_item_arg)
1031
    :thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
1032
  void store_value(Item *item);
1033
  int cmp(Item *arg);
1034
  int compare(cmp_item *ci);
1035
  cmp_item *make_same();
1036
};
1037
1038
class cmp_item_real :public cmp_item
1039
{
1040
  double value;
1041
public:
1042
  cmp_item_real() {}                          /* Remove gcc warning */
1043
  void store_value(Item *item)
1044
  {
1045
    value= item->val_real();
1046
  }
1047
  int cmp(Item *arg)
1048
  {
1049
    return value != arg->val_real();
1050
  }
1051
  int compare(cmp_item *ci)
1052
  {
1053
    cmp_item_real *l_cmp= (cmp_item_real *) ci;
1054
    return (value < l_cmp->value)? -1 : ((value == l_cmp->value) ? 0 : 1);
1055
  }
1056
  cmp_item *make_same();
1057
};
1058
1059
1060
class cmp_item_decimal :public cmp_item
1061
{
1062
  my_decimal value;
1063
public:
1064
  cmp_item_decimal() {}                       /* Remove gcc warning */
1065
  void store_value(Item *item);
1066
  int cmp(Item *arg);
1067
  int compare(cmp_item *c);
1068
  cmp_item *make_same();
1069
};
1070
1071
1072
/* 
1073
   cmp_item for optimized IN with row (right part string, which never
1074
   be changed)
1075
*/
1076
1077
class cmp_item_sort_string_in_static :public cmp_item_string
1078
{
1079
 protected:
1080
  String value;
1081
public:
1082
  cmp_item_sort_string_in_static(CHARSET_INFO *cs):
1083
    cmp_item_string(cs) {}
1084
  void store_value(Item *item)
1085
  {
1086
    value_res= item->val_str(&value);
1087
  }
77.1.7 by Monty Taylor
Heap builds clean.
1088
  int cmp(Item *item __attribute__((__unused__)))
1 by brian
clean slate
1089
  {
1090
    // Should never be called
1091
    DBUG_ASSERT(0);
1092
    return 1;
1093
  }
1094
  int compare(cmp_item *ci)
1095
  {
1096
    cmp_item_string *l_cmp= (cmp_item_string *) ci;
1097
    return sortcmp(value_res, l_cmp->value_res, cmp_charset);
1098
  }
1099
  cmp_item *make_same()
1100
  {
1101
    return new cmp_item_sort_string_in_static(cmp_charset);
1102
  }
1103
};
1104
1105
1106
/*
1107
  The class Item_func_case is the CASE ... WHEN ... THEN ... END function
1108
  implementation.
1109
1110
  When there is no expression between CASE and the first WHEN 
1111
  (the CASE expression) then this function simple checks all WHEN expressions
1112
  one after another. When some WHEN expression evaluated to TRUE then the
1113
  value of the corresponding THEN expression is returned.
1114
1115
  When the CASE expression is specified then it is compared to each WHEN
1116
  expression individually. When an equal WHEN expression is found
1117
  corresponding THEN expression is returned.
1118
  In order to do correct comparisons several comparators are used. One for
1119
  each result type. Different result types that are used in particular
1120
  CASE ... END expression are collected in the fix_length_and_dec() member
1121
  function and only comparators for there result types are used.
1122
*/
1123
1124
class Item_func_case :public Item_func
1125
{
1126
  int first_expr_num, else_expr_num;
1127
  enum Item_result cached_result_type, left_result_type;
1128
  String tmp_value;
1129
  uint ncases;
1130
  Item_result cmp_type;
1131
  DTCollation cmp_collation;
1132
  enum_field_types cached_field_type;
1133
  cmp_item *cmp_items[5]; /* For all result types */
1134
  cmp_item *case_item;
1135
public:
1136
  Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
1137
    :Item_func(), first_expr_num(-1), else_expr_num(-1),
1138
    cached_result_type(INT_RESULT), left_result_type(INT_RESULT), case_item(0)
1139
  {
1140
    ncases= list.elements;
1141
    if (first_expr_arg)
1142
    {
1143
      first_expr_num= list.elements;
1144
      list.push_back(first_expr_arg);
1145
    }
1146
    if (else_expr_arg)
1147
    {
1148
      else_expr_num= list.elements;
1149
      list.push_back(else_expr_arg);
1150
    }
1151
    set_arguments(list);
1152
    bzero(&cmp_items, sizeof(cmp_items));
1153
  }
1154
  double val_real();
1155
  longlong val_int();
1156
  String *val_str(String *);
1157
  my_decimal *val_decimal(my_decimal *);
1158
  bool fix_fields(THD *thd, Item **ref);
1159
  void fix_length_and_dec();
1160
  uint decimal_precision() const;
1161
  table_map not_null_tables() const { return 0; }
1162
  enum Item_result result_type () const { return cached_result_type; }
1163
  enum_field_types field_type() const { return cached_field_type; }
1164
  const char *func_name() const { return "case"; }
1165
  virtual void print(String *str, enum_query_type query_type);
1166
  Item *find_item(String *str);
1167
  CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1168
  void cleanup();
1169
  void agg_str_lengths(Item *arg);
1170
  void agg_num_lengths(Item *arg);
1171
};
1172
1173
/*
1174
  The Item_func_in class implements the in_expr IN(values_list) function.
1175
1176
  The current implementation distinguishes 2 cases:
1177
  1) all items in the value_list are constants and have the same
1178
    result type. This case is handled by in_vector class.
1179
  2) items in the value_list have different result types or there is some
1180
    non-constant items.
1181
    In this case Item_func_in employs several cmp_item objects to performs
1182
    comparisons of in_expr and an item from the values_list. One cmp_item
1183
    object for each result type. Different result types are collected in the
1184
    fix_length_and_dec() member function by means of collect_cmp_types()
1185
    function.
1186
*/
1187
class Item_func_in :public Item_func_opt_neg
1188
{
1189
public:
1190
  /* 
1191
    an array of values when the right hand arguments of IN
1192
    are all SQL constant and there are no nulls 
1193
  */
1194
  in_vector *array;
1195
  bool have_null;
1196
  /* 
1197
    true when all arguments of the IN clause are of compatible types
1198
    and can be used safely as comparisons for key conditions
1199
  */
1200
  bool arg_types_compatible;
1201
  Item_result left_result_type;
1202
  cmp_item *cmp_items[6]; /* One cmp_item for each result type */
1203
  DTCollation cmp_collation;
1204
1205
  Item_func_in(List<Item> &list)
1206
    :Item_func_opt_neg(list), array(0), have_null(0),
1207
    arg_types_compatible(FALSE)
1208
  {
1209
    bzero(&cmp_items, sizeof(cmp_items));
1210
    allowed_arg_cols= 0;  // Fetch this value from first argument
1211
  }
1212
  longlong val_int();
1213
  bool fix_fields(THD *, Item **);
1214
  void fix_length_and_dec();
1215
  uint decimal_precision() const { return 1; }
1216
  void cleanup()
1217
  {
1218
    uint i;
1219
    DBUG_ENTER("Item_func_in::cleanup");
1220
    Item_int_func::cleanup();
1221
    delete array;
1222
    array= 0;
1223
    for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
1224
    {
1225
      delete cmp_items[i];
1226
      cmp_items[i]= 0;
1227
    }
1228
    DBUG_VOID_RETURN;
1229
  }
1230
  optimize_type select_optimize() const
1231
    { return OPTIMIZE_KEY; }
1232
  virtual void print(String *str, enum_query_type query_type);
1233
  enum Functype functype() const { return IN_FUNC; }
1234
  const char *func_name() const { return " IN "; }
1235
  bool nulls_in_row();
1236
  bool is_bool_func() { return 1; }
1237
  CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1238
};
1239
1240
class cmp_item_row :public cmp_item
1241
{
1242
  cmp_item **comparators;
1243
  uint n;
1244
public:
1245
  cmp_item_row(): comparators(0), n(0) {}
1246
  ~cmp_item_row();
1247
  void store_value(Item *item);
1248
  inline void alloc_comparators();
1249
  int cmp(Item *arg);
1250
  int compare(cmp_item *arg);
1251
  cmp_item *make_same();
1252
  void store_value_by_template(cmp_item *tmpl, Item *);
1253
  friend void Item_func_in::fix_length_and_dec();
1254
};
1255
1256
1257
class in_row :public in_vector
1258
{
1259
  cmp_item_row tmp;
1260
public:
1261
  in_row(uint elements, Item *);
1262
  ~in_row();
1263
  void set(uint pos,Item *item);
1264
  uchar *get_value(Item *item);
1265
  friend void Item_func_in::fix_length_and_dec();
1266
  Item_result result_type() { return ROW_RESULT; }
1267
};
1268
1269
/* Functions used by where clause */
1270
1271
class Item_func_isnull :public Item_bool_func
1272
{
1273
protected:
1274
  longlong cached_value;
1275
public:
1276
  Item_func_isnull(Item *a) :Item_bool_func(a) {}
1277
  longlong val_int();
1278
  enum Functype functype() const { return ISNULL_FUNC; }
1279
  void fix_length_and_dec()
1280
  {
1281
    decimals=0; max_length=1; maybe_null=0;
1282
    update_used_tables();
1283
  }
1284
  const char *func_name() const { return "isnull"; }
1285
  /* Optimize case of not_null_column IS NULL */
1286
  virtual void update_used_tables()
1287
  {
1288
    if (!args[0]->maybe_null)
1289
    {
1290
      used_tables_cache= 0;			/* is always false */
1291
      const_item_cache= 1;
1292
      cached_value= (longlong) 0;
1293
    }
1294
    else
1295
    {
1296
      args[0]->update_used_tables();
1297
      if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())) &&
1298
          !with_subselect)
1299
      {
1300
	/* Remember if the value is always NULL or never NULL */
1301
	cached_value= (longlong) args[0]->is_null();
1302
      }
1303
    }
1304
  }
1305
  table_map not_null_tables() const { return 0; }
1306
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1307
  Item *neg_transformer(THD *thd);
1308
  CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1309
};
1310
1311
/* Functions used by HAVING for rewriting IN subquery */
1312
1313
class Item_in_subselect;
1314
1315
/* 
1316
  This is like IS NOT NULL but it also remembers if it ever has
1317
  encountered a NULL.
1318
*/
1319
class Item_is_not_null_test :public Item_func_isnull
1320
{
1321
  Item_in_subselect* owner;
1322
public:
1323
  Item_is_not_null_test(Item_in_subselect* ow, Item *a)
1324
    :Item_func_isnull(a), owner(ow)
1325
  {}
1326
  enum Functype functype() const { return ISNOTNULLTEST_FUNC; }
1327
  longlong val_int();
1328
  const char *func_name() const { return "<is_not_null_test>"; }
1329
  void update_used_tables();
1330
  /*
1331
    we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
1332
  */
1333
  table_map used_tables() const
1334
    { return used_tables_cache | RAND_TABLE_BIT; }
1335
};
1336
1337
1338
class Item_func_isnotnull :public Item_bool_func
1339
{
1340
  bool abort_on_null;
1341
public:
1342
  Item_func_isnotnull(Item *a) :Item_bool_func(a), abort_on_null(0) {}
1343
  longlong val_int();
1344
  enum Functype functype() const { return ISNOTNULL_FUNC; }
1345
  void fix_length_and_dec()
1346
  {
1347
    decimals=0; max_length=1; maybe_null=0;
1348
  }
1349
  const char *func_name() const { return "isnotnull"; }
1350
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1351
  table_map not_null_tables() const
1352
  { return abort_on_null ? not_null_tables_cache : 0; }
1353
  Item *neg_transformer(THD *thd);
1354
  virtual void print(String *str, enum_query_type query_type);
1355
  CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1356
  void top_level_item() { abort_on_null=1; }
1357
};
1358
1359
1360
class Item_func_like :public Item_bool_func2
1361
{
1362
  // Turbo Boyer-Moore data
1363
  bool        canDoTurboBM;	// pattern is '%abcd%' case
1364
  const char* pattern;
1365
  int         pattern_len;
1366
1367
  // TurboBM buffers, *this is owner
1368
  int* bmGs; //   good suffix shift table, size is pattern_len + 1
1369
  int* bmBc; // bad character shift table, size is alphabet_size
1370
1371
  void turboBM_compute_suffixes(int* suff);
1372
  void turboBM_compute_good_suffix_shifts(int* suff);
1373
  void turboBM_compute_bad_character_shifts();
1374
  bool turboBM_matches(const char* text, int text_len) const;
1375
  enum { alphabet_size = 256 };
1376
1377
  Item *escape_item;
1378
  
1379
  bool escape_used_in_parsing;
1380
1381
public:
1382
  int escape;
1383
1384
  Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
1385
    :Item_bool_func2(a,b), canDoTurboBM(FALSE), pattern(0), pattern_len(0), 
1386
     bmGs(0), bmBc(0), escape_item(escape_arg),
1387
     escape_used_in_parsing(escape_used) {}
1388
  longlong val_int();
1389
  enum Functype functype() const { return LIKE_FUNC; }
1390
  optimize_type select_optimize() const;
1391
  cond_result eq_cmp_result() const { return COND_TRUE; }
1392
  const char *func_name() const { return "like"; }
1393
  bool fix_fields(THD *thd, Item **ref);
1394
  void cleanup();
1395
};
1396
1397
1398
typedef class Item COND;
1399
1400
class Item_cond :public Item_bool_func
1401
{
1402
protected:
1403
  List<Item> list;
1404
  bool abort_on_null;
1405
  table_map and_tables_cache;
1406
1407
public:
1408
  /* Item_cond() is only used to create top level items */
1409
  Item_cond(): Item_bool_func(), abort_on_null(1)
1410
  { const_item_cache=0; }
1411
  Item_cond(Item *i1,Item *i2)
1412
    :Item_bool_func(), abort_on_null(0)
1413
  {
1414
    list.push_back(i1);
1415
    list.push_back(i2);
1416
  }
1417
  Item_cond(THD *thd, Item_cond *item);
1418
  Item_cond(List<Item> &nlist)
1419
    :Item_bool_func(), list(nlist), abort_on_null(0) {}
1420
  bool add(Item *item) { return list.push_back(item); }
1421
  bool add_at_head(Item *item) { return list.push_front(item); }
1422
  void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
1423
  bool fix_fields(THD *, Item **ref);
1424
  void fix_after_pullout(st_select_lex *new_parent, Item **ref);
1425
1426
  enum Type type() const { return COND_ITEM; }
1427
  List<Item>* argument_list() { return &list; }
1428
  table_map used_tables() const;
1429
  void update_used_tables();
1430
  virtual void print(String *str, enum_query_type query_type);
1431
  void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
1432
  friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
1433
                         COND **conds);
1434
  void top_level_item() { abort_on_null=1; }
1435
  void copy_andor_arguments(THD *thd, Item_cond *item);
1436
  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
1437
  Item *transform(Item_transformer transformer, uchar *arg);
1438
  void traverse_cond(Cond_traverser, void *arg, traverse_order order);
1439
  void neg_arguments(THD *thd);
1440
  enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
77.1.7 by Monty Taylor
Heap builds clean.
1441
  bool subst_argument_checker(uchar **arg __attribute__((__unused__)))
1442
  { return TRUE; }
1 by brian
clean slate
1443
  Item *compile(Item_analyzer analyzer, uchar **arg_p,
1444
                Item_transformer transformer, uchar *arg_t);
1445
};
1446
1447
1448
/*
1449
  The class Item_equal is used to represent conjunctions of equality
1450
  predicates of the form field1 = field2, and field=const in where
1451
  conditions and on expressions.
1452
1453
  All equality predicates of the form field1=field2 contained in a
1454
  conjunction are substituted for a sequence of items of this class.
1455
  An item of this class Item_equal(f1,f2,...fk) represents a
1456
  multiple equality f1=f2=...=fk.
1457
1458
  If a conjunction contains predicates f1=f2 and f2=f3, a new item of
1459
  this class is created Item_equal(f1,f2,f3) representing the multiple
1460
  equality f1=f2=f3 that substitutes the above equality predicates in
1461
  the conjunction.
1462
  A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
1463
  substituted for the item representing the same multiple equality
1464
  f1=f2=f3.
1465
  An item Item_equal(f1,f2) can appear instead of a conjunction of 
1466
  f2=f1 and f1=f2, or instead of just the predicate f1=f2.
1467
1468
  An item of the class Item_equal inherits equalities from outer 
1469
  conjunctive levels.
1470
1471
  Suppose we have a where condition of the following form:
1472
  WHERE f1=f2 AND f3=f4 AND f3=f5 AND ... AND (...OR (f1=f3 AND ...)).
1473
  In this case:
1474
    f1=f2 will be substituted for Item_equal(f1,f2);
1475
    f3=f4 and f3=f5  will be substituted for Item_equal(f3,f4,f5);
1476
    f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
1477
1478
  An object of the class Item_equal can contain an optional constant
1479
  item c. Then it represents a multiple equality of the form 
1480
  c=f1=...=fk.
1481
1482
  Objects of the class Item_equal are used for the following:
1483
1484
  1. An object Item_equal(t1.f1,...,tk.fk) allows us to consider any
1485
  pair of tables ti and tj as joined by an equi-condition.
1486
  Thus it provide us with additional access paths from table to table.
1487
1488
  2. An object Item_equal(t1.f1,...,tk.fk) is applied to deduce new
1489
  SARGable predicates:
1490
    f1=...=fk AND P(fi) => f1=...=fk AND P(fi) AND P(fj).
1491
  It also can give us additional index scans and can allow us to
1492
  improve selectivity estimates.
1493
1494
  3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the 
1495
  selected execution plan for the query: if table ti is accessed 
1496
  before the table tj then in any predicate P in the where condition
1497
  the occurrence of tj.fj is substituted for ti.fi. This can allow
1498
  an evaluation of the predicate at an earlier step.
1499
1500
  When feature 1 is supported they say that join transitive closure 
1501
  is employed.
1502
  When feature 2 is supported they say that search argument transitive
1503
  closure is employed.
1504
  Both features are usually supported by preprocessing original query and
1505
  adding additional predicates.
1506
  We do not just add predicates, we rather dynamically replace some
1507
  predicates that can not be used to access tables in the investigated
1508
  plan for those, obtained by substitution of some fields for equal fields,
1509
  that can be used.     
1510
1511
  Prepared Statements/Stored Procedures note: instances of class
1512
  Item_equal are created only at the time a PS/SP is executed and
1513
  are deleted in the end of execution. All changes made to these
1514
  objects need not be registered in the list of changes of the parse
1515
  tree and do not harm PS/SP re-execution.
1516
1517
  Item equal objects are employed only at the optimize phase. Usually they are
1518
  not supposed to be evaluated.  Yet in some cases we call the method val_int()
1519
  for them. We have to take care of restricting the predicate such an
1520
  object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.
1521
*/
1522
1523
class Item_equal: public Item_bool_func
1524
{
1525
  List<Item_field> fields; /* list of equal field items                    */
1526
  Item *const_item;        /* optional constant item equal to fields items */
1527
  cmp_item *eval_item;
1528
  bool cond_false;
1529
public:
1530
  inline Item_equal()
1531
    : Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
1532
  { const_item_cache=0 ;}
1533
  Item_equal(Item_field *f1, Item_field *f2);
1534
  Item_equal(Item *c, Item_field *f);
1535
  Item_equal(Item_equal *item_equal);
1536
  inline Item* get_const() { return const_item; }
1537
  void add(Item *c);
1538
  void add(Item_field *f);
1539
  uint members();
1540
  bool contains(Field *field);
1541
  Item_field* get_first() { return fields.head(); }
1542
  void merge(Item_equal *item);
1543
  void update_const();
1544
  enum Functype functype() const { return MULT_EQUAL_FUNC; }
1545
  longlong val_int(); 
1546
  const char *func_name() const { return "multiple equal"; }
1547
  optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
1548
  void sort(Item_field_cmpfunc cmp, void *arg);
1549
  friend class Item_equal_iterator;
1550
  void fix_length_and_dec();
1551
  bool fix_fields(THD *thd, Item **ref);
1552
  void update_used_tables();
1553
  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
1554
  Item *transform(Item_transformer transformer, uchar *arg);
1555
  virtual void print(String *str, enum_query_type query_type);
1556
  CHARSET_INFO *compare_collation() 
1557
  { return fields.head()->collation.collation; }
1558
}; 
1559
1560
class COND_EQUAL: public Sql_alloc
1561
{
1562
public:
1563
  uint max_members;               /* max number of members the current level
1564
                                     list and all lower level lists */ 
1565
  COND_EQUAL *upper_levels;       /* multiple equalities of upper and levels */
1566
  List<Item_equal> current_level; /* list of multiple equalities of 
1567
                                     the current and level           */
1568
  COND_EQUAL()
1569
  { 
1570
    upper_levels= 0;
1571
  }
1572
};
1573
1574
1575
class Item_equal_iterator : public List_iterator_fast<Item_field>
1576
{
1577
public:
1578
  inline Item_equal_iterator(Item_equal &item_equal) 
1579
    :List_iterator_fast<Item_field> (item_equal.fields)
1580
  {}
1581
  inline Item_field* operator++(int)
1582
  { 
1583
    Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
1584
    return  item;
1585
  }
1586
  inline void rewind(void) 
1587
  { 
1588
    List_iterator_fast<Item_field>::rewind();
1589
  }
1590
};
1591
1592
class Item_cond_and :public Item_cond
1593
{
1594
public:
1595
  COND_EQUAL cond_equal;  /* contains list of Item_equal objects for 
1596
                             the current and level and reference
1597
                             to multiple equalities of upper and levels */  
1598
  Item_cond_and() :Item_cond() {}
1599
  Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1600
  Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
1601
  Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
1602
  enum Functype functype() const { return COND_AND_FUNC; }
1603
  longlong val_int();
1604
  const char *func_name() const { return "and"; }
1605
  table_map not_null_tables() const
1606
  { return abort_on_null ? not_null_tables_cache: and_tables_cache; }
1607
  Item* copy_andor_structure(THD *thd)
1608
  {
1609
    Item_cond_and *item;
1610
    if ((item= new Item_cond_and(thd, this)))
1611
       item->copy_andor_arguments(thd, this);
1612
    return item;
1613
  }
1614
  Item *neg_transformer(THD *thd);
1615
};
1616
1617
inline bool is_cond_and(Item *item)
1618
{
1619
  if (item->type() != Item::COND_ITEM)
1620
    return FALSE;
1621
1622
  Item_cond *cond_item= (Item_cond*) item;
1623
  return (cond_item->functype() == Item_func::COND_AND_FUNC);
1624
}
1625
1626
class Item_cond_or :public Item_cond
1627
{
1628
public:
1629
  Item_cond_or() :Item_cond() {}
1630
  Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1631
  Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
1632
  Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
1633
  enum Functype functype() const { return COND_OR_FUNC; }
1634
  longlong val_int();
1635
  const char *func_name() const { return "or"; }
1636
  table_map not_null_tables() const { return and_tables_cache; }
1637
  Item* copy_andor_structure(THD *thd)
1638
  {
1639
    Item_cond_or *item;
1640
    if ((item= new Item_cond_or(thd, this)))
1641
      item->copy_andor_arguments(thd, this);
1642
    return item;
1643
  }
1644
  Item *neg_transformer(THD *thd);
1645
};
1646
1647
inline bool is_cond_or(Item *item)
1648
{
1649
  if (item->type() != Item::COND_ITEM)
1650
    return FALSE;
1651
1652
  Item_cond *cond_item= (Item_cond*) item;
1653
  return (cond_item->functype() == Item_func::COND_OR_FUNC);
1654
}
1655
1656
/*
1657
  XOR is Item_cond, not an Item_int_func because we could like to
1658
  optimize (a XOR b) later on. It's low prio, though
1659
*/
1660
1661
class Item_cond_xor :public Item_cond
1662
{
1663
public:
1664
  Item_cond_xor() :Item_cond() {}
1665
  Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1666
  enum Functype functype() const { return COND_XOR_FUNC; }
1667
  /* TODO: remove the next line when implementing XOR optimization */
1668
  enum Type type() const { return FUNC_ITEM; }
1669
  longlong val_int();
1670
  const char *func_name() const { return "xor"; }
1671
  void top_level_item() {}
1672
};
1673
1674
1675
/* Some useful inline functions */
1676
1677
inline Item *and_conds(Item *a, Item *b)
1678
{
1679
  if (!b) return a;
1680
  if (!a) return b;
1681
  return new Item_cond_and(a, b);
1682
}
1683
1684
Item *and_expressions(Item *a, Item *b, Item **org_item);