~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 };
151 by Brian Aker
Ulonglong to uint64_t
45
  uint64_t (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg,
1 by brian
clean slate
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,
151 by Brian Aker
Ulonglong to uint64_t
94
                                                      uint64_t *const_val_arg);
1 by brian
clean slate
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();
152 by Brian Aker
longlong replacement
124
  virtual int64_t val_int();
1 by brian
clean slate
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)
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
235
  { with_subselect= true; }
1 by brian
clean slate
236
  bool fix_fields(THD *, Item **);
237
  bool fix_left(THD *thd, Item **ref);
238
  bool is_null();
152 by Brian Aker
longlong replacement
239
  int64_t val_int();
1 by brian
clean slate
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)
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
333
    :Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1), abort_on_null(false) {}
1 by brian
clean slate
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; }
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
352
  void top_level_item() { abort_on_null= true; }
1 by brian
clean slate
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();
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
366
  bool subst_argument_checker(uchar **arg __attribute__((unused)))
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
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) {}
152 by Brian Aker
longlong replacement
374
  int64_t val_int();
1 by brian
clean slate
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; }
152 by Brian Aker
longlong replacement
417
  int64_t val_int() { return *trig_var ? args[0]->val_int() : 1; }
1 by brian
clean slate
418
  enum Functype functype() const { return TRIG_COND_FUNC; };
419
  const char *func_name() const { return "trigcond"; };
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
420
  bool const_item() const { return false; }
1 by brian
clean slate
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; }
152 by Brian Aker
longlong replacement
442
  int64_t val_int();
1 by brian
clean slate
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) {}
152 by Brian Aker
longlong replacement
458
  int64_t val_int();
1 by brian
clean slate
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) {}
152 by Brian Aker
longlong replacement
468
  int64_t val_int();
1 by brian
clean slate
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) {};
152 by Brian Aker
longlong replacement
480
  int64_t val_int();
1 by brian
clean slate
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 "<=>"; }
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
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) {};
152 by Brian Aker
longlong replacement
495
  int64_t val_int();
1 by brian
clean slate
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) {};
152 by Brian Aker
longlong replacement
508
  int64_t val_int();
1 by brian
clean slate
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) {};
152 by Brian Aker
longlong replacement
521
  int64_t val_int();
1 by brian
clean slate
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) {}
152 by Brian Aker
longlong replacement
534
  int64_t val_int();
1 by brian
clean slate
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) {}
152 by Brian Aker
longlong replacement
547
  int64_t val_int();
1 by brian
clean slate
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; }
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
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;
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
584
  bool subst_argument_checker(uchar **arg __attribute__((unused)))
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
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)
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
600
    :Item_func_opt_neg(a, b, c), compare_as_dates(false) {}
152 by Brian Aker
longlong replacement
601
  int64_t val_int();
1 by brian
clean slate
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) {}
152 by Brian Aker
longlong replacement
618
  int64_t val_int();
1 by brian
clean slate
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
  }
152 by Brian Aker
longlong replacement
647
  int64_t val_int();
1 by brian
clean slate
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();
152 by Brian Aker
longlong replacement
662
  int64_t int_op();
1 by brian
clean slate
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();
152 by Brian Aker
longlong replacement
681
  int64_t int_op();
1 by brian
clean slate
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();
152 by Brian Aker
longlong replacement
701
  int64_t val_int();
1 by brian
clean slate
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();
152 by Brian Aker
longlong replacement
721
  int64_t val_int();
1 by brian
clean slate
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
  */
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
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
152 by Brian Aker
longlong replacement
819
class in_int64_t :public in_vector
1 by brian
clean slate
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
  */
152 by Brian Aker
longlong replacement
827
  struct packed_int64_t 
1 by brian
clean slate
828
  {
152 by Brian Aker
longlong replacement
829
    int64_t val;
830
    int64_t unsigned_flag;  // Use int64_t, not bool, to preserve alignment
1 by brian
clean slate
831
  } tmp;
832
public:
152 by Brian Aker
longlong replacement
833
  in_int64_t(uint elements);
1 by brian
clean slate
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
    */
152 by Brian Aker
longlong replacement
843
    return new Item_int((int64_t)0);
1 by brian
clean slate
844
  }
845
  void value_to_item(uint pos, Item *item)
846
  {
152 by Brian Aker
longlong replacement
847
    ((Item_int*) item)->value= ((packed_int64_t*) base)[pos].val;
1 by brian
clean slate
848
    ((Item_int*) item)->unsigned_flag= (my_bool)
152 by Brian Aker
longlong replacement
849
      ((packed_int64_t*) base)[pos].unsigned_flag;
1 by brian
clean slate
850
  }
851
  Item_result result_type() { return INT_RESULT; }
852
152 by Brian Aker
longlong replacement
853
  friend int cmp_int64_t(void *cmp_arg, packed_int64_t *a,packed_int64_t *b);
1 by brian
clean slate
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
*/
152 by Brian Aker
longlong replacement
863
class in_datetime :public in_int64_t
1 by brian
clean slate
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)
152 by Brian Aker
longlong replacement
873
    :in_int64_t(elements), thd(current_thd), warn_item(warn_item_arg),
1 by brian
clean slate
874
     lval_cache(0) {};
875
  void set(uint pos,Item *item);
876
  uchar *get_value(Item *item);
152 by Brian Aker
longlong replacement
877
  friend int cmp_int64_t(void *cmp_arg, packed_int64_t *a,packed_int64_t *b);
1 by brian
clean slate
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
  { 
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
909
    return new Item_decimal(0, false);
1 by brian
clean slate
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;
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
938
  virtual void store_value_by_template(cmp_item *tmpl  __attribute__((unused)),
77.1.7 by Monty Taylor
Heap builds clean.
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
{
152 by Brian Aker
longlong replacement
995
  int64_t value;
1 by brian
clean slate
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
{
151 by Brian Aker
Ulonglong to uint64_t
1022
  uint64_t value;
1 by brian
clean slate
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
  }
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
1088
  int cmp(Item *item __attribute__((unused)))
1 by brian
clean slate
1089
  {
1090
    // Should never be called
51.1.17 by Jay Pipes
Removed/replaced DBUG symbols
1091
    assert(0);
1 by brian
clean slate
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();
152 by Brian Aker
longlong replacement
1155
  int64_t val_int();
1 by brian
clean slate
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),
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
1207
    arg_types_compatible(false)
1 by brian
clean slate
1208
  {
1209
    bzero(&cmp_items, sizeof(cmp_items));
1210
    allowed_arg_cols= 0;  // Fetch this value from first argument
1211
  }
152 by Brian Aker
longlong replacement
1212
  int64_t val_int();
1 by brian
clean slate
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
    Item_int_func::cleanup();
1220
    delete array;
1221
    array= 0;
1222
    for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
1223
    {
1224
      delete cmp_items[i];
1225
      cmp_items[i]= 0;
1226
    }
51.1.17 by Jay Pipes
Removed/replaced DBUG symbols
1227
    return;
1 by brian
clean slate
1228
  }
1229
  optimize_type select_optimize() const
1230
    { return OPTIMIZE_KEY; }
1231
  virtual void print(String *str, enum_query_type query_type);
1232
  enum Functype functype() const { return IN_FUNC; }
1233
  const char *func_name() const { return " IN "; }
1234
  bool nulls_in_row();
1235
  bool is_bool_func() { return 1; }
1236
  CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1237
};
1238
1239
class cmp_item_row :public cmp_item
1240
{
1241
  cmp_item **comparators;
1242
  uint n;
1243
public:
1244
  cmp_item_row(): comparators(0), n(0) {}
1245
  ~cmp_item_row();
1246
  void store_value(Item *item);
1247
  inline void alloc_comparators();
1248
  int cmp(Item *arg);
1249
  int compare(cmp_item *arg);
1250
  cmp_item *make_same();
1251
  void store_value_by_template(cmp_item *tmpl, Item *);
1252
  friend void Item_func_in::fix_length_and_dec();
1253
};
1254
1255
1256
class in_row :public in_vector
1257
{
1258
  cmp_item_row tmp;
1259
public:
1260
  in_row(uint elements, Item *);
1261
  ~in_row();
1262
  void set(uint pos,Item *item);
1263
  uchar *get_value(Item *item);
1264
  friend void Item_func_in::fix_length_and_dec();
1265
  Item_result result_type() { return ROW_RESULT; }
1266
};
1267
1268
/* Functions used by where clause */
1269
1270
class Item_func_isnull :public Item_bool_func
1271
{
1272
protected:
152 by Brian Aker
longlong replacement
1273
  int64_t cached_value;
1 by brian
clean slate
1274
public:
1275
  Item_func_isnull(Item *a) :Item_bool_func(a) {}
152 by Brian Aker
longlong replacement
1276
  int64_t val_int();
1 by brian
clean slate
1277
  enum Functype functype() const { return ISNULL_FUNC; }
1278
  void fix_length_and_dec()
1279
  {
1280
    decimals=0; max_length=1; maybe_null=0;
1281
    update_used_tables();
1282
  }
1283
  const char *func_name() const { return "isnull"; }
1284
  /* Optimize case of not_null_column IS NULL */
1285
  virtual void update_used_tables()
1286
  {
1287
    if (!args[0]->maybe_null)
1288
    {
1289
      used_tables_cache= 0;			/* is always false */
1290
      const_item_cache= 1;
152 by Brian Aker
longlong replacement
1291
      cached_value= (int64_t) 0;
1 by brian
clean slate
1292
    }
1293
    else
1294
    {
1295
      args[0]->update_used_tables();
1296
      if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())) &&
1297
          !with_subselect)
1298
      {
1299
	/* Remember if the value is always NULL or never NULL */
152 by Brian Aker
longlong replacement
1300
	cached_value= (int64_t) args[0]->is_null();
1 by brian
clean slate
1301
      }
1302
    }
1303
  }
1304
  table_map not_null_tables() const { return 0; }
1305
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1306
  Item *neg_transformer(THD *thd);
1307
  CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1308
};
1309
1310
/* Functions used by HAVING for rewriting IN subquery */
1311
1312
class Item_in_subselect;
1313
1314
/* 
1315
  This is like IS NOT NULL but it also remembers if it ever has
1316
  encountered a NULL.
1317
*/
1318
class Item_is_not_null_test :public Item_func_isnull
1319
{
1320
  Item_in_subselect* owner;
1321
public:
1322
  Item_is_not_null_test(Item_in_subselect* ow, Item *a)
1323
    :Item_func_isnull(a), owner(ow)
1324
  {}
1325
  enum Functype functype() const { return ISNOTNULLTEST_FUNC; }
152 by Brian Aker
longlong replacement
1326
  int64_t val_int();
1 by brian
clean slate
1327
  const char *func_name() const { return "<is_not_null_test>"; }
1328
  void update_used_tables();
1329
  /*
1330
    we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
1331
  */
1332
  table_map used_tables() const
1333
    { return used_tables_cache | RAND_TABLE_BIT; }
1334
};
1335
1336
1337
class Item_func_isnotnull :public Item_bool_func
1338
{
1339
  bool abort_on_null;
1340
public:
1341
  Item_func_isnotnull(Item *a) :Item_bool_func(a), abort_on_null(0) {}
152 by Brian Aker
longlong replacement
1342
  int64_t val_int();
1 by brian
clean slate
1343
  enum Functype functype() const { return ISNOTNULL_FUNC; }
1344
  void fix_length_and_dec()
1345
  {
1346
    decimals=0; max_length=1; maybe_null=0;
1347
  }
1348
  const char *func_name() const { return "isnotnull"; }
1349
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1350
  table_map not_null_tables() const
1351
  { return abort_on_null ? not_null_tables_cache : 0; }
1352
  Item *neg_transformer(THD *thd);
1353
  virtual void print(String *str, enum_query_type query_type);
1354
  CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1355
  void top_level_item() { abort_on_null=1; }
1356
};
1357
1358
1359
class Item_func_like :public Item_bool_func2
1360
{
1361
  // Turbo Boyer-Moore data
1362
  bool        canDoTurboBM;	// pattern is '%abcd%' case
1363
  const char* pattern;
1364
  int         pattern_len;
1365
1366
  // TurboBM buffers, *this is owner
1367
  int* bmGs; //   good suffix shift table, size is pattern_len + 1
1368
  int* bmBc; // bad character shift table, size is alphabet_size
1369
1370
  void turboBM_compute_suffixes(int* suff);
1371
  void turboBM_compute_good_suffix_shifts(int* suff);
1372
  void turboBM_compute_bad_character_shifts();
1373
  bool turboBM_matches(const char* text, int text_len) const;
1374
  enum { alphabet_size = 256 };
1375
1376
  Item *escape_item;
1377
  
1378
  bool escape_used_in_parsing;
1379
1380
public:
1381
  int escape;
1382
1383
  Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
1384
    :Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0), 
1 by brian
clean slate
1385
     bmGs(0), bmBc(0), escape_item(escape_arg),
1386
     escape_used_in_parsing(escape_used) {}
152 by Brian Aker
longlong replacement
1387
  int64_t val_int();
1 by brian
clean slate
1388
  enum Functype functype() const { return LIKE_FUNC; }
1389
  optimize_type select_optimize() const;
1390
  cond_result eq_cmp_result() const { return COND_TRUE; }
1391
  const char *func_name() const { return "like"; }
1392
  bool fix_fields(THD *thd, Item **ref);
1393
  void cleanup();
1394
};
1395
1396
1397
typedef class Item COND;
1398
1399
class Item_cond :public Item_bool_func
1400
{
1401
protected:
1402
  List<Item> list;
1403
  bool abort_on_null;
1404
  table_map and_tables_cache;
1405
1406
public:
1407
  /* Item_cond() is only used to create top level items */
1408
  Item_cond(): Item_bool_func(), abort_on_null(1)
1409
  { const_item_cache=0; }
1410
  Item_cond(Item *i1,Item *i2)
1411
    :Item_bool_func(), abort_on_null(0)
1412
  {
1413
    list.push_back(i1);
1414
    list.push_back(i2);
1415
  }
1416
  Item_cond(THD *thd, Item_cond *item);
1417
  Item_cond(List<Item> &nlist)
1418
    :Item_bool_func(), list(nlist), abort_on_null(0) {}
1419
  bool add(Item *item) { return list.push_back(item); }
1420
  bool add_at_head(Item *item) { return list.push_front(item); }
1421
  void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
1422
  bool fix_fields(THD *, Item **ref);
1423
  void fix_after_pullout(st_select_lex *new_parent, Item **ref);
1424
1425
  enum Type type() const { return COND_ITEM; }
1426
  List<Item>* argument_list() { return &list; }
1427
  table_map used_tables() const;
1428
  void update_used_tables();
1429
  virtual void print(String *str, enum_query_type query_type);
1430
  void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
1431
  friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
1432
                         COND **conds);
1433
  void top_level_item() { abort_on_null=1; }
1434
  void copy_andor_arguments(THD *thd, Item_cond *item);
1435
  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
1436
  Item *transform(Item_transformer transformer, uchar *arg);
1437
  void traverse_cond(Cond_traverser, void *arg, traverse_order order);
1438
  void neg_arguments(THD *thd);
212.2.1 by Patrick Galbraith
Renamed all MYSQL_TYPE... to FIELD_TYPE...
1439
  enum_field_types field_type() const { return FIELD_TYPE_LONGLONG; }
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
1440
  bool subst_argument_checker(uchar **arg __attribute__((unused)))
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
1441
  { return true; }
1 by brian
clean slate
1442
  Item *compile(Item_analyzer analyzer, uchar **arg_p,
1443
                Item_transformer transformer, uchar *arg_t);
1444
};
1445
1446
1447
/*
1448
  The class Item_equal is used to represent conjunctions of equality
1449
  predicates of the form field1 = field2, and field=const in where
1450
  conditions and on expressions.
1451
1452
  All equality predicates of the form field1=field2 contained in a
1453
  conjunction are substituted for a sequence of items of this class.
1454
  An item of this class Item_equal(f1,f2,...fk) represents a
1455
  multiple equality f1=f2=...=fk.
1456
1457
  If a conjunction contains predicates f1=f2 and f2=f3, a new item of
1458
  this class is created Item_equal(f1,f2,f3) representing the multiple
1459
  equality f1=f2=f3 that substitutes the above equality predicates in
1460
  the conjunction.
1461
  A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
1462
  substituted for the item representing the same multiple equality
1463
  f1=f2=f3.
1464
  An item Item_equal(f1,f2) can appear instead of a conjunction of 
1465
  f2=f1 and f1=f2, or instead of just the predicate f1=f2.
1466
1467
  An item of the class Item_equal inherits equalities from outer 
1468
  conjunctive levels.
1469
1470
  Suppose we have a where condition of the following form:
1471
  WHERE f1=f2 AND f3=f4 AND f3=f5 AND ... AND (...OR (f1=f3 AND ...)).
1472
  In this case:
1473
    f1=f2 will be substituted for Item_equal(f1,f2);
1474
    f3=f4 and f3=f5  will be substituted for Item_equal(f3,f4,f5);
1475
    f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
1476
1477
  An object of the class Item_equal can contain an optional constant
1478
  item c. Then it represents a multiple equality of the form 
1479
  c=f1=...=fk.
1480
1481
  Objects of the class Item_equal are used for the following:
1482
1483
  1. An object Item_equal(t1.f1,...,tk.fk) allows us to consider any
1484
  pair of tables ti and tj as joined by an equi-condition.
1485
  Thus it provide us with additional access paths from table to table.
1486
1487
  2. An object Item_equal(t1.f1,...,tk.fk) is applied to deduce new
1488
  SARGable predicates:
1489
    f1=...=fk AND P(fi) => f1=...=fk AND P(fi) AND P(fj).
1490
  It also can give us additional index scans and can allow us to
1491
  improve selectivity estimates.
1492
1493
  3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the 
1494
  selected execution plan for the query: if table ti is accessed 
1495
  before the table tj then in any predicate P in the where condition
1496
  the occurrence of tj.fj is substituted for ti.fi. This can allow
1497
  an evaluation of the predicate at an earlier step.
1498
1499
  When feature 1 is supported they say that join transitive closure 
1500
  is employed.
1501
  When feature 2 is supported they say that search argument transitive
1502
  closure is employed.
1503
  Both features are usually supported by preprocessing original query and
1504
  adding additional predicates.
1505
  We do not just add predicates, we rather dynamically replace some
1506
  predicates that can not be used to access tables in the investigated
1507
  plan for those, obtained by substitution of some fields for equal fields,
1508
  that can be used.     
1509
1510
  Prepared Statements/Stored Procedures note: instances of class
1511
  Item_equal are created only at the time a PS/SP is executed and
1512
  are deleted in the end of execution. All changes made to these
1513
  objects need not be registered in the list of changes of the parse
1514
  tree and do not harm PS/SP re-execution.
1515
1516
  Item equal objects are employed only at the optimize phase. Usually they are
1517
  not supposed to be evaluated.  Yet in some cases we call the method val_int()
1518
  for them. We have to take care of restricting the predicate such an
1519
  object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.
1520
*/
1521
1522
class Item_equal: public Item_bool_func
1523
{
1524
  List<Item_field> fields; /* list of equal field items                    */
1525
  Item *const_item;        /* optional constant item equal to fields items */
1526
  cmp_item *eval_item;
1527
  bool cond_false;
1528
public:
1529
  inline Item_equal()
1530
    : Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
1531
  { const_item_cache=0 ;}
1532
  Item_equal(Item_field *f1, Item_field *f2);
1533
  Item_equal(Item *c, Item_field *f);
1534
  Item_equal(Item_equal *item_equal);
1535
  inline Item* get_const() { return const_item; }
1536
  void add(Item *c);
1537
  void add(Item_field *f);
1538
  uint members();
1539
  bool contains(Field *field);
1540
  Item_field* get_first() { return fields.head(); }
1541
  void merge(Item_equal *item);
1542
  void update_const();
1543
  enum Functype functype() const { return MULT_EQUAL_FUNC; }
152 by Brian Aker
longlong replacement
1544
  int64_t val_int(); 
1 by brian
clean slate
1545
  const char *func_name() const { return "multiple equal"; }
1546
  optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
1547
  void sort(Item_field_cmpfunc cmp, void *arg);
1548
  friend class Item_equal_iterator;
1549
  void fix_length_and_dec();
1550
  bool fix_fields(THD *thd, Item **ref);
1551
  void update_used_tables();
1552
  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
1553
  Item *transform(Item_transformer transformer, uchar *arg);
1554
  virtual void print(String *str, enum_query_type query_type);
1555
  CHARSET_INFO *compare_collation() 
1556
  { return fields.head()->collation.collation; }
1557
}; 
1558
1559
class COND_EQUAL: public Sql_alloc
1560
{
1561
public:
1562
  uint max_members;               /* max number of members the current level
1563
                                     list and all lower level lists */ 
1564
  COND_EQUAL *upper_levels;       /* multiple equalities of upper and levels */
1565
  List<Item_equal> current_level; /* list of multiple equalities of 
1566
                                     the current and level           */
1567
  COND_EQUAL()
1568
  { 
1569
    upper_levels= 0;
1570
  }
1571
};
1572
1573
1574
class Item_equal_iterator : public List_iterator_fast<Item_field>
1575
{
1576
public:
1577
  inline Item_equal_iterator(Item_equal &item_equal) 
1578
    :List_iterator_fast<Item_field> (item_equal.fields)
1579
  {}
1580
  inline Item_field* operator++(int)
1581
  { 
1582
    Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
1583
    return  item;
1584
  }
1585
  inline void rewind(void) 
1586
  { 
1587
    List_iterator_fast<Item_field>::rewind();
1588
  }
1589
};
1590
1591
class Item_cond_and :public Item_cond
1592
{
1593
public:
1594
  COND_EQUAL cond_equal;  /* contains list of Item_equal objects for 
1595
                             the current and level and reference
1596
                             to multiple equalities of upper and levels */  
1597
  Item_cond_and() :Item_cond() {}
1598
  Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1599
  Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
1600
  Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
1601
  enum Functype functype() const { return COND_AND_FUNC; }
152 by Brian Aker
longlong replacement
1602
  int64_t val_int();
1 by brian
clean slate
1603
  const char *func_name() const { return "and"; }
1604
  table_map not_null_tables() const
1605
  { return abort_on_null ? not_null_tables_cache: and_tables_cache; }
1606
  Item* copy_andor_structure(THD *thd)
1607
  {
1608
    Item_cond_and *item;
1609
    if ((item= new Item_cond_and(thd, this)))
1610
       item->copy_andor_arguments(thd, this);
1611
    return item;
1612
  }
1613
  Item *neg_transformer(THD *thd);
1614
};
1615
1616
inline bool is_cond_and(Item *item)
1617
{
1618
  if (item->type() != Item::COND_ITEM)
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
1619
    return false;
1 by brian
clean slate
1620
1621
  Item_cond *cond_item= (Item_cond*) item;
1622
  return (cond_item->functype() == Item_func::COND_AND_FUNC);
1623
}
1624
1625
class Item_cond_or :public Item_cond
1626
{
1627
public:
1628
  Item_cond_or() :Item_cond() {}
1629
  Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1630
  Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
1631
  Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
1632
  enum Functype functype() const { return COND_OR_FUNC; }
152 by Brian Aker
longlong replacement
1633
  int64_t val_int();
1 by brian
clean slate
1634
  const char *func_name() const { return "or"; }
1635
  table_map not_null_tables() const { return and_tables_cache; }
1636
  Item* copy_andor_structure(THD *thd)
1637
  {
1638
    Item_cond_or *item;
1639
    if ((item= new Item_cond_or(thd, this)))
1640
      item->copy_andor_arguments(thd, this);
1641
    return item;
1642
  }
1643
  Item *neg_transformer(THD *thd);
1644
};
1645
1646
inline bool is_cond_or(Item *item)
1647
{
1648
  if (item->type() != Item::COND_ITEM)
51.1.77 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
1649
    return false;
1 by brian
clean slate
1650
1651
  Item_cond *cond_item= (Item_cond*) item;
1652
  return (cond_item->functype() == Item_func::COND_OR_FUNC);
1653
}
1654
1655
/*
1656
  XOR is Item_cond, not an Item_int_func because we could like to
1657
  optimize (a XOR b) later on. It's low prio, though
1658
*/
1659
1660
class Item_cond_xor :public Item_cond
1661
{
1662
public:
1663
  Item_cond_xor() :Item_cond() {}
1664
  Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1665
  enum Functype functype() const { return COND_XOR_FUNC; }
1666
  /* TODO: remove the next line when implementing XOR optimization */
1667
  enum Type type() const { return FUNC_ITEM; }
152 by Brian Aker
longlong replacement
1668
  int64_t val_int();
1 by brian
clean slate
1669
  const char *func_name() const { return "xor"; }
1670
  void top_level_item() {}
1671
};
1672
1673
1674
/* Some useful inline functions */
1675
1676
inline Item *and_conds(Item *a, Item *b)
1677
{
1678
  if (!b) return a;
1679
  if (!a) return b;
1680
  return new Item_cond_and(a, b);
1681
}
1682
1683
Item *and_expressions(Item *a, Item *b, Item **org_item);