~linuxjedi/drizzle/trunk-bug-667053

« back to all changes in this revision

Viewing changes to sql/item_cmpfunc.h

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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();
 
366
  bool subst_argument_checker(uchar **arg) { return TRUE; }
 
367
};
 
368
 
 
369
class Item_func_not :public Item_bool_func
 
370
{
 
371
public:
 
372
  Item_func_not(Item *a) :Item_bool_func(a) {}
 
373
  longlong val_int();
 
374
  enum Functype functype() const { return NOT_FUNC; }
 
375
  const char *func_name() const { return "not"; }
 
376
  Item *neg_transformer(THD *thd);
 
377
  virtual void print(String *str, enum_query_type query_type);
 
378
};
 
379
 
 
380
class Item_maxmin_subselect;
 
381
 
 
382
/*
 
383
  trigcond<param>(arg) ::= param? arg : TRUE
 
384
 
 
385
  The class Item_func_trig_cond is used for guarded predicates 
 
386
  which are employed only for internal purposes.
 
387
  A guarded predicate is an object consisting of an a regular or
 
388
  a guarded predicate P and a pointer to a boolean guard variable g. 
 
389
  A guarded predicate P/g is evaluated to true if the value of the
 
390
  guard g is false, otherwise it is evaluated to the same value that
 
391
  the predicate P: val(P/g)= g ? val(P):true.
 
392
  Guarded predicates allow us to include predicates into a conjunction
 
393
  conditionally. Currently they are utilized for pushed down predicates
 
394
  in queries with outer join operations.
 
395
 
 
396
  In the future, probably, it makes sense to extend this class to
 
397
  the objects consisting of three elements: a predicate P, a pointer
 
398
  to a variable g and a firing value s with following evaluation
 
399
  rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
 
400
  one item for the objects of the form P/g1/g2... 
 
401
 
 
402
  Objects of this class are built only for query execution after
 
403
  the execution plan has been already selected. That's why this
 
404
  class needs only val_int out of generic methods. 
 
405
 
 
406
  Current uses of Item_func_trig_cond objects:
 
407
   - To wrap selection conditions when executing outer joins
 
408
   - To wrap condition that is pushed down into subquery
 
409
*/
 
410
 
 
411
class Item_func_trig_cond: public Item_bool_func
 
412
{
 
413
  bool *trig_var;
 
414
public:
 
415
  Item_func_trig_cond(Item *a, bool *f) : Item_bool_func(a) { trig_var= f; }
 
416
  longlong val_int() { return *trig_var ? args[0]->val_int() : 1; }
 
417
  enum Functype functype() const { return TRIG_COND_FUNC; };
 
418
  const char *func_name() const { return "trigcond"; };
 
419
  bool const_item() const { return FALSE; }
 
420
  bool *get_trig_var() { return trig_var; }
 
421
  /* The following is needed for ICP: */
 
422
  table_map used_tables() const { return args[0]->used_tables(); }
 
423
};
 
424
 
 
425
class Item_func_not_all :public Item_func_not
 
426
{
 
427
  /* allow to check presence of values in max/min optimization */
 
428
  Item_sum_hybrid *test_sum_item;
 
429
  Item_maxmin_subselect *test_sub_item;
 
430
 
 
431
  bool abort_on_null;
 
432
public:
 
433
  bool show;
 
434
 
 
435
  Item_func_not_all(Item *a)
 
436
    :Item_func_not(a), test_sum_item(0), test_sub_item(0), abort_on_null(0),
 
437
     show(0)
 
438
    {}
 
439
  virtual void top_level_item() { abort_on_null= 1; }
 
440
  bool top_level() { return abort_on_null; }
 
441
  longlong val_int();
 
442
  enum Functype functype() const { return NOT_ALL_FUNC; }
 
443
  const char *func_name() const { return "<not>"; }
 
444
  virtual void print(String *str, enum_query_type query_type);
 
445
  void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
 
446
  void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
 
447
  bool empty_underlying_subquery();
 
448
  Item *neg_transformer(THD *thd);
 
449
};
 
450
 
 
451
 
 
452
class Item_func_nop_all :public Item_func_not_all
 
453
{
 
454
public:
 
455
 
 
456
  Item_func_nop_all(Item *a) :Item_func_not_all(a) {}
 
457
  longlong val_int();
 
458
  const char *func_name() const { return "<nop>"; }
 
459
  Item *neg_transformer(THD *thd);
 
460
};
 
461
 
 
462
 
 
463
class Item_func_eq :public Item_bool_rowready_func2
 
464
{
 
465
public:
 
466
  Item_func_eq(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
 
467
  longlong val_int();
 
468
  enum Functype functype() const { return EQ_FUNC; }
 
469
  enum Functype rev_functype() const { return EQ_FUNC; }
 
470
  cond_result eq_cmp_result() const { return COND_TRUE; }
 
471
  const char *func_name() const { return "="; }
 
472
  Item *negated_item();
 
473
};
 
474
 
 
475
class Item_func_equal :public Item_bool_rowready_func2
 
476
{
 
477
public:
 
478
  Item_func_equal(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
 
479
  longlong val_int();
 
480
  void fix_length_and_dec();
 
481
  table_map not_null_tables() const { return 0; }
 
482
  enum Functype functype() const { return EQUAL_FUNC; }
 
483
  enum Functype rev_functype() const { return EQUAL_FUNC; }
 
484
  cond_result eq_cmp_result() const { return COND_TRUE; }
 
485
  const char *func_name() const { return "<=>"; }
 
486
  Item *neg_transformer(THD *thd) { return 0; }
 
487
};
 
488
 
 
489
 
 
490
class Item_func_ge :public Item_bool_rowready_func2
 
491
{
 
492
public:
 
493
  Item_func_ge(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
 
494
  longlong val_int();
 
495
  enum Functype functype() const { return GE_FUNC; }
 
496
  enum Functype rev_functype() const { return LE_FUNC; }
 
497
  cond_result eq_cmp_result() const { return COND_TRUE; }
 
498
  const char *func_name() const { return ">="; }
 
499
  Item *negated_item();
 
500
};
 
501
 
 
502
 
 
503
class Item_func_gt :public Item_bool_rowready_func2
 
504
{
 
505
public:
 
506
  Item_func_gt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
 
507
  longlong val_int();
 
508
  enum Functype functype() const { return GT_FUNC; }
 
509
  enum Functype rev_functype() const { return LT_FUNC; }
 
510
  cond_result eq_cmp_result() const { return COND_FALSE; }
 
511
  const char *func_name() const { return ">"; }
 
512
  Item *negated_item();
 
513
};
 
514
 
 
515
 
 
516
class Item_func_le :public Item_bool_rowready_func2
 
517
{
 
518
public:
 
519
  Item_func_le(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
 
520
  longlong val_int();
 
521
  enum Functype functype() const { return LE_FUNC; }
 
522
  enum Functype rev_functype() const { return GE_FUNC; }
 
523
  cond_result eq_cmp_result() const { return COND_TRUE; }
 
524
  const char *func_name() const { return "<="; }
 
525
  Item *negated_item();
 
526
};
 
527
 
 
528
 
 
529
class Item_func_lt :public Item_bool_rowready_func2
 
530
{
 
531
public:
 
532
  Item_func_lt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
 
533
  longlong val_int();
 
534
  enum Functype functype() const { return LT_FUNC; }
 
535
  enum Functype rev_functype() const { return GT_FUNC; }
 
536
  cond_result eq_cmp_result() const { return COND_FALSE; }
 
537
  const char *func_name() const { return "<"; }
 
538
  Item *negated_item();
 
539
};
 
540
 
 
541
 
 
542
class Item_func_ne :public Item_bool_rowready_func2
 
543
{
 
544
public:
 
545
  Item_func_ne(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
 
546
  longlong val_int();
 
547
  enum Functype functype() const { return NE_FUNC; }
 
548
  cond_result eq_cmp_result() const { return COND_FALSE; }
 
549
  optimize_type select_optimize() const { return OPTIMIZE_KEY; } 
 
550
  const char *func_name() const { return "<>"; }
 
551
  Item *negated_item();
 
552
};
 
553
 
 
554
 
 
555
/*
 
556
  The class Item_func_opt_neg is defined to factor out the functionality
 
557
  common for the classes Item_func_between and Item_func_in. The objects
 
558
  of these classes can express predicates or there negations.
 
559
  The alternative approach would be to create pairs Item_func_between,
 
560
  Item_func_notbetween and Item_func_in, Item_func_notin.
 
561
 
 
562
*/
 
563
 
 
564
class Item_func_opt_neg :public Item_int_func
 
565
{
 
566
public:
 
567
  bool negated;     /* <=> the item represents NOT <func> */
 
568
  bool pred_level;  /* <=> [NOT] <func> is used on a predicate level */
 
569
public:
 
570
  Item_func_opt_neg(Item *a, Item *b, Item *c)
 
571
    :Item_int_func(a, b, c), negated(0), pred_level(0) {}
 
572
  Item_func_opt_neg(List<Item> &list)
 
573
    :Item_int_func(list), negated(0), pred_level(0) {}
 
574
public:
 
575
  inline void negate() { negated= !negated; }
 
576
  inline void top_level_item() { pred_level= 1; }
 
577
  Item *neg_transformer(THD *thd)
 
578
  {
 
579
    negated= !negated;
 
580
    return this;
 
581
  }
 
582
  bool eq(const Item *item, bool binary_cmp) const;
 
583
  bool subst_argument_checker(uchar **arg) { return TRUE; }
 
584
};
 
585
 
 
586
 
 
587
class Item_func_between :public Item_func_opt_neg
 
588
{
 
589
  DTCollation cmp_collation;
 
590
public:
 
591
  Item_result cmp_type;
 
592
  String value0,value1,value2;
 
593
  /* TRUE <=> arguments will be compared as dates. */
 
594
  bool compare_as_dates;
 
595
  /* Comparators used for DATE/DATETIME comparison. */
 
596
  Arg_comparator ge_cmp, le_cmp;
 
597
  Item_func_between(Item *a, Item *b, Item *c)
 
598
    :Item_func_opt_neg(a, b, c), compare_as_dates(FALSE) {}
 
599
  longlong val_int();
 
600
  optimize_type select_optimize() const { return OPTIMIZE_KEY; }
 
601
  enum Functype functype() const   { return BETWEEN; }
 
602
  const char *func_name() const { return "between"; }
 
603
  bool fix_fields(THD *, Item **);
 
604
  void fix_length_and_dec();
 
605
  virtual void print(String *str, enum_query_type query_type);
 
606
  bool is_bool_func() { return 1; }
 
607
  CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
 
608
  uint decimal_precision() const { return 1; }
 
609
};
 
610
 
 
611
 
 
612
class Item_func_strcmp :public Item_bool_func2
 
613
{
 
614
public:
 
615
  Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {}
 
616
  longlong val_int();
 
617
  optimize_type select_optimize() const { return OPTIMIZE_NONE; }
 
618
  const char *func_name() const { return "strcmp"; }
 
619
 
 
620
  virtual inline void print(String *str, enum_query_type query_type)
 
621
  {
 
622
    Item_func::print(str, query_type);
 
623
  }
 
624
};
 
625
 
 
626
 
 
627
struct interval_range
 
628
{
 
629
  Item_result type;
 
630
  double dbl;
 
631
  my_decimal dec;
 
632
};
 
633
 
 
634
class Item_func_interval :public Item_int_func
 
635
{
 
636
  Item_row *row;
 
637
  my_bool use_decimal_comparison;
 
638
  interval_range *intervals;
 
639
public:
 
640
  Item_func_interval(Item_row *a)
 
641
    :Item_int_func(a),row(a),intervals(0)
 
642
  {
 
643
    allowed_arg_cols= 0;    // Fetch this value from first argument
 
644
  }
 
645
  longlong val_int();
 
646
  void fix_length_and_dec();
 
647
  const char *func_name() const { return "interval"; }
 
648
  uint decimal_precision() const { return 2; }
 
649
};
 
650
 
 
651
 
 
652
class Item_func_coalesce :public Item_func_numhybrid
 
653
{
 
654
protected:
 
655
  enum_field_types cached_field_type;
 
656
  Item_func_coalesce(Item *a, Item *b) :Item_func_numhybrid(a, b) {}
 
657
public:
 
658
  Item_func_coalesce(List<Item> &list) :Item_func_numhybrid(list) {}
 
659
  double real_op();
 
660
  longlong int_op();
 
661
  String *str_op(String *);
 
662
  my_decimal *decimal_op(my_decimal *);
 
663
  void fix_length_and_dec();
 
664
  void find_num_type() {}
 
665
  enum Item_result result_type () const { return hybrid_type; }
 
666
  const char *func_name() const { return "coalesce"; }
 
667
  table_map not_null_tables() const { return 0; }
 
668
  enum_field_types field_type() const { return cached_field_type; }
 
669
};
 
670
 
 
671
 
 
672
class Item_func_ifnull :public Item_func_coalesce
 
673
{
 
674
protected:
 
675
  bool field_type_defined;
 
676
public:
 
677
  Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
 
678
  double real_op();
 
679
  longlong int_op();
 
680
  String *str_op(String *str);
 
681
  my_decimal *decimal_op(my_decimal *);
 
682
  enum_field_types field_type() const;
 
683
  void fix_length_and_dec();
 
684
  const char *func_name() const { return "ifnull"; }
 
685
  Field *tmp_table_field(TABLE *table);
 
686
  uint decimal_precision() const;
 
687
};
 
688
 
 
689
 
 
690
class Item_func_if :public Item_func
 
691
{
 
692
  enum Item_result cached_result_type;
 
693
  enum_field_types cached_field_type;
 
694
public:
 
695
  Item_func_if(Item *a,Item *b,Item *c)
 
696
    :Item_func(a,b,c), cached_result_type(INT_RESULT)
 
697
  {}
 
698
  double val_real();
 
699
  longlong val_int();
 
700
  String *val_str(String *str);
 
701
  my_decimal *val_decimal(my_decimal *);
 
702
  enum Item_result result_type () const { return cached_result_type; }
 
703
  enum_field_types field_type() const { return cached_field_type; }
 
704
  bool fix_fields(THD *, Item **);
 
705
  void fix_length_and_dec();
 
706
  uint decimal_precision() const;
 
707
  const char *func_name() const { return "if"; }
 
708
};
 
709
 
 
710
 
 
711
class Item_func_nullif :public Item_bool_func2
 
712
{
 
713
  enum Item_result cached_result_type;
 
714
public:
 
715
  Item_func_nullif(Item *a,Item *b)
 
716
    :Item_bool_func2(a,b), cached_result_type(INT_RESULT)
 
717
  {}
 
718
  double val_real();
 
719
  longlong val_int();
 
720
  String *val_str(String *str);
 
721
  my_decimal *val_decimal(my_decimal *);
 
722
  enum Item_result result_type () const { return cached_result_type; }
 
723
  void fix_length_and_dec();
 
724
  uint decimal_precision() const { return args[0]->decimal_precision(); }
 
725
  const char *func_name() const { return "nullif"; }
 
726
 
 
727
  virtual inline void print(String *str, enum_query_type query_type)
 
728
  {
 
729
    Item_func::print(str, query_type);
 
730
  }
 
731
 
 
732
  table_map not_null_tables() const { return 0; }
 
733
  bool is_null();
 
734
};
 
735
 
 
736
 
 
737
/* Functions to handle the optimized IN */
 
738
 
 
739
 
 
740
/* A vector of values of some type  */
 
741
 
 
742
class in_vector :public Sql_alloc
 
743
{
 
744
public:
 
745
  char *base;
 
746
  uint size;
 
747
  qsort2_cmp compare;
 
748
  CHARSET_INFO *collation;
 
749
  uint count;
 
750
  uint used_count;
 
751
  in_vector() {}
 
752
  in_vector(uint elements,uint element_length,qsort2_cmp cmp_func, 
 
753
            CHARSET_INFO *cmp_coll)
 
754
    :base((char*) sql_calloc(elements*element_length)),
 
755
     size(element_length), compare(cmp_func), collation(cmp_coll),
 
756
     count(elements), used_count(elements) {}
 
757
  virtual ~in_vector() {}
 
758
  virtual void set(uint pos,Item *item)=0;
 
759
  virtual uchar *get_value(Item *item)=0;
 
760
  void sort()
 
761
  {
 
762
    my_qsort2(base,used_count,size,compare,collation);
 
763
  }
 
764
  int find(Item *item);
 
765
  
 
766
  /* 
 
767
    Create an instance of Item_{type} (e.g. Item_decimal) constant object
 
768
    which type allows it to hold an element of this vector without any
 
769
    conversions.
 
770
    The purpose of this function is to be able to get elements of this
 
771
    vector in form of Item_xxx constants without creating Item_xxx object
 
772
    for every array element you get (i.e. this implements "FlyWeight" pattern)
 
773
  */
 
774
  virtual Item* create_item() { return NULL; }
 
775
  
 
776
  /*
 
777
    Store the value at position #pos into provided item object
 
778
    SYNOPSIS
 
779
      value_to_item()
 
780
        pos   Index of value to store
 
781
        item  Constant item to store value into. The item must be of the same
 
782
              type that create_item() returns.
 
783
  */
 
784
  virtual void value_to_item(uint pos, Item *item) { }
 
785
  
 
786
  /* Compare values number pos1 and pos2 for equality */
 
787
  bool compare_elems(uint pos1, uint pos2)
 
788
  {
 
789
    return test(compare(collation, base + pos1*size, base + pos2*size));
 
790
  }
 
791
  virtual Item_result result_type()= 0;
 
792
};
 
793
 
 
794
class in_string :public in_vector
 
795
{
 
796
  char buff[STRING_BUFFER_USUAL_SIZE];
 
797
  String tmp;
 
798
public:
 
799
  in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs);
 
800
  ~in_string();
 
801
  void set(uint pos,Item *item);
 
802
  uchar *get_value(Item *item);
 
803
  Item* create_item()
 
804
  { 
 
805
    return new Item_string(collation);
 
806
  }
 
807
  void value_to_item(uint pos, Item *item)
 
808
  {    
 
809
    String *str=((String*) base)+pos;
 
810
    Item_string *to= (Item_string*)item;
 
811
    to->str_value= *str;
 
812
  }
 
813
  Item_result result_type() { return STRING_RESULT; }
 
814
};
 
815
 
 
816
class in_longlong :public in_vector
 
817
{
 
818
protected:
 
819
  /*
 
820
    Here we declare a temporary variable (tmp) of the same type as the
 
821
    elements of this vector. tmp is used in finding if a given value is in 
 
822
    the list. 
 
823
  */
 
824
  struct packed_longlong 
 
825
  {
 
826
    longlong val;
 
827
    longlong unsigned_flag;  // Use longlong, not bool, to preserve alignment
 
828
  } tmp;
 
829
public:
 
830
  in_longlong(uint elements);
 
831
  void set(uint pos,Item *item);
 
832
  uchar *get_value(Item *item);
 
833
  
 
834
  Item* create_item()
 
835
  { 
 
836
    /* 
 
837
      We're created a signed INT, this may not be correct in 
 
838
      general case (see BUG#19342).
 
839
    */
 
840
    return new Item_int((longlong)0);
 
841
  }
 
842
  void value_to_item(uint pos, Item *item)
 
843
  {
 
844
    ((Item_int*) item)->value= ((packed_longlong*) base)[pos].val;
 
845
    ((Item_int*) item)->unsigned_flag= (my_bool)
 
846
      ((packed_longlong*) base)[pos].unsigned_flag;
 
847
  }
 
848
  Item_result result_type() { return INT_RESULT; }
 
849
 
 
850
  friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
 
851
};
 
852
 
 
853
 
 
854
/*
 
855
  Class to represent a vector of constant DATE/DATETIME values.
 
856
  Values are obtained with help of the get_datetime_value() function.
 
857
  If the left item is a constant one then its value is cached in the
 
858
  lval_cache variable.
 
859
*/
 
860
class in_datetime :public in_longlong
 
861
{
 
862
public:
 
863
  THD *thd;
 
864
  /* An item used to issue warnings. */
 
865
  Item *warn_item;
 
866
  /* Cache for the left item. */
 
867
  Item *lval_cache;
 
868
 
 
869
  in_datetime(Item *warn_item_arg, uint elements)
 
870
    :in_longlong(elements), thd(current_thd), warn_item(warn_item_arg),
 
871
     lval_cache(0) {};
 
872
  void set(uint pos,Item *item);
 
873
  uchar *get_value(Item *item);
 
874
  friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
 
875
};
 
876
 
 
877
 
 
878
class in_double :public in_vector
 
879
{
 
880
  double tmp;
 
881
public:
 
882
  in_double(uint elements);
 
883
  void set(uint pos,Item *item);
 
884
  uchar *get_value(Item *item);
 
885
  Item *create_item()
 
886
  { 
 
887
    return new Item_float(0.0, 0);
 
888
  }
 
889
  void value_to_item(uint pos, Item *item)
 
890
  {
 
891
    ((Item_float*)item)->value= ((double*) base)[pos];
 
892
  }
 
893
  Item_result result_type() { return REAL_RESULT; }
 
894
};
 
895
 
 
896
 
 
897
class in_decimal :public in_vector
 
898
{
 
899
  my_decimal val;
 
900
public:
 
901
  in_decimal(uint elements);
 
902
  void set(uint pos, Item *item);
 
903
  uchar *get_value(Item *item);
 
904
  Item *create_item()
 
905
  { 
 
906
    return new Item_decimal(0, FALSE);
 
907
  }
 
908
  void value_to_item(uint pos, Item *item)
 
909
  {
 
910
    my_decimal *dec= ((my_decimal *)base) + pos;
 
911
    Item_decimal *item_dec= (Item_decimal*)item;
 
912
    item_dec->set_decimal_value(dec);
 
913
  }
 
914
  Item_result result_type() { return DECIMAL_RESULT; }
 
915
 
 
916
};
 
917
 
 
918
 
 
919
/*
 
920
** Classes for easy comparing of non const items
 
921
*/
 
922
 
 
923
class cmp_item :public Sql_alloc
 
924
{
 
925
public:
 
926
  CHARSET_INFO *cmp_charset;
 
927
  cmp_item() { cmp_charset= &my_charset_bin; }
 
928
  virtual ~cmp_item() {}
 
929
  virtual void store_value(Item *item)= 0;
 
930
  virtual int cmp(Item *item)= 0;
 
931
  // for optimized IN with row
 
932
  virtual int compare(cmp_item *item)= 0;
 
933
  static cmp_item* get_comparator(Item_result type, CHARSET_INFO *cs);
 
934
  virtual cmp_item *make_same()= 0;
 
935
  virtual void store_value_by_template(cmp_item *tmpl, Item *item)
 
936
  {
 
937
    store_value(item);
 
938
  }
 
939
};
 
940
 
 
941
class cmp_item_string :public cmp_item 
 
942
{
 
943
protected:
 
944
  String *value_res;
 
945
public:
 
946
  cmp_item_string () {}
 
947
  cmp_item_string (CHARSET_INFO *cs) { cmp_charset= cs; }
 
948
  void set_charset(CHARSET_INFO *cs) { cmp_charset= cs; }
 
949
  friend class cmp_item_sort_string;
 
950
  friend class cmp_item_sort_string_in_static;
 
951
};
 
952
 
 
953
class cmp_item_sort_string :public cmp_item_string
 
954
{
 
955
protected:
 
956
  char value_buff[STRING_BUFFER_USUAL_SIZE];
 
957
  String value;
 
958
public:
 
959
  cmp_item_sort_string():
 
960
    cmp_item_string() {}
 
961
  cmp_item_sort_string(CHARSET_INFO *cs):
 
962
    cmp_item_string(cs),
 
963
    value(value_buff, sizeof(value_buff), cs) {}
 
964
  void store_value(Item *item)
 
965
  {
 
966
    value_res= item->val_str(&value);
 
967
  }
 
968
  int cmp(Item *arg)
 
969
  {
 
970
    char buff[STRING_BUFFER_USUAL_SIZE];
 
971
    String tmp(buff, sizeof(buff), cmp_charset), *res;
 
972
    res= arg->val_str(&tmp);
 
973
    return (value_res ? (res ? sortcmp(value_res, res, cmp_charset) : 1) :
 
974
            (res ? -1 : 0));
 
975
  }
 
976
  int compare(cmp_item *ci)
 
977
  {
 
978
    cmp_item_string *l_cmp= (cmp_item_string *) ci;
 
979
    return sortcmp(value_res, l_cmp->value_res, cmp_charset);
 
980
  } 
 
981
  cmp_item *make_same();
 
982
  void set_charset(CHARSET_INFO *cs)
 
983
  {
 
984
    cmp_charset= cs;
 
985
    value.set_quick(value_buff, sizeof(value_buff), cs);
 
986
  }
 
987
};
 
988
 
 
989
class cmp_item_int :public cmp_item
 
990
{
 
991
  longlong value;
 
992
public:
 
993
  cmp_item_int() {}                           /* Remove gcc warning */
 
994
  void store_value(Item *item)
 
995
  {
 
996
    value= item->val_int();
 
997
  }
 
998
  int cmp(Item *arg)
 
999
  {
 
1000
    return value != arg->val_int();
 
1001
  }
 
1002
  int compare(cmp_item *ci)
 
1003
  {
 
1004
    cmp_item_int *l_cmp= (cmp_item_int *)ci;
 
1005
    return (value < l_cmp->value) ? -1 : ((value == l_cmp->value) ? 0 : 1);
 
1006
  }
 
1007
  cmp_item *make_same();
 
1008
};
 
1009
 
 
1010
/*
 
1011
  Compare items in the DATETIME context.
 
1012
  Values are obtained with help of the get_datetime_value() function.
 
1013
  If the left item is a constant one then its value is cached in the
 
1014
  lval_cache variable.
 
1015
*/
 
1016
class cmp_item_datetime :public cmp_item
 
1017
{
 
1018
  ulonglong value;
 
1019
public:
 
1020
  THD *thd;
 
1021
  /* Item used for issuing warnings. */
 
1022
  Item *warn_item;
 
1023
  /* Cache for the left item. */
 
1024
  Item *lval_cache;
 
1025
 
 
1026
  cmp_item_datetime(Item *warn_item_arg)
 
1027
    :thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
 
1028
  void store_value(Item *item);
 
1029
  int cmp(Item *arg);
 
1030
  int compare(cmp_item *ci);
 
1031
  cmp_item *make_same();
 
1032
};
 
1033
 
 
1034
class cmp_item_real :public cmp_item
 
1035
{
 
1036
  double value;
 
1037
public:
 
1038
  cmp_item_real() {}                          /* Remove gcc warning */
 
1039
  void store_value(Item *item)
 
1040
  {
 
1041
    value= item->val_real();
 
1042
  }
 
1043
  int cmp(Item *arg)
 
1044
  {
 
1045
    return value != arg->val_real();
 
1046
  }
 
1047
  int compare(cmp_item *ci)
 
1048
  {
 
1049
    cmp_item_real *l_cmp= (cmp_item_real *) ci;
 
1050
    return (value < l_cmp->value)? -1 : ((value == l_cmp->value) ? 0 : 1);
 
1051
  }
 
1052
  cmp_item *make_same();
 
1053
};
 
1054
 
 
1055
 
 
1056
class cmp_item_decimal :public cmp_item
 
1057
{
 
1058
  my_decimal value;
 
1059
public:
 
1060
  cmp_item_decimal() {}                       /* Remove gcc warning */
 
1061
  void store_value(Item *item);
 
1062
  int cmp(Item *arg);
 
1063
  int compare(cmp_item *c);
 
1064
  cmp_item *make_same();
 
1065
};
 
1066
 
 
1067
 
 
1068
/* 
 
1069
   cmp_item for optimized IN with row (right part string, which never
 
1070
   be changed)
 
1071
*/
 
1072
 
 
1073
class cmp_item_sort_string_in_static :public cmp_item_string
 
1074
{
 
1075
 protected:
 
1076
  String value;
 
1077
public:
 
1078
  cmp_item_sort_string_in_static(CHARSET_INFO *cs):
 
1079
    cmp_item_string(cs) {}
 
1080
  void store_value(Item *item)
 
1081
  {
 
1082
    value_res= item->val_str(&value);
 
1083
  }
 
1084
  int cmp(Item *item)
 
1085
  {
 
1086
    // Should never be called
 
1087
    DBUG_ASSERT(0);
 
1088
    return 1;
 
1089
  }
 
1090
  int compare(cmp_item *ci)
 
1091
  {
 
1092
    cmp_item_string *l_cmp= (cmp_item_string *) ci;
 
1093
    return sortcmp(value_res, l_cmp->value_res, cmp_charset);
 
1094
  }
 
1095
  cmp_item *make_same()
 
1096
  {
 
1097
    return new cmp_item_sort_string_in_static(cmp_charset);
 
1098
  }
 
1099
};
 
1100
 
 
1101
 
 
1102
/*
 
1103
  The class Item_func_case is the CASE ... WHEN ... THEN ... END function
 
1104
  implementation.
 
1105
 
 
1106
  When there is no expression between CASE and the first WHEN 
 
1107
  (the CASE expression) then this function simple checks all WHEN expressions
 
1108
  one after another. When some WHEN expression evaluated to TRUE then the
 
1109
  value of the corresponding THEN expression is returned.
 
1110
 
 
1111
  When the CASE expression is specified then it is compared to each WHEN
 
1112
  expression individually. When an equal WHEN expression is found
 
1113
  corresponding THEN expression is returned.
 
1114
  In order to do correct comparisons several comparators are used. One for
 
1115
  each result type. Different result types that are used in particular
 
1116
  CASE ... END expression are collected in the fix_length_and_dec() member
 
1117
  function and only comparators for there result types are used.
 
1118
*/
 
1119
 
 
1120
class Item_func_case :public Item_func
 
1121
{
 
1122
  int first_expr_num, else_expr_num;
 
1123
  enum Item_result cached_result_type, left_result_type;
 
1124
  String tmp_value;
 
1125
  uint ncases;
 
1126
  Item_result cmp_type;
 
1127
  DTCollation cmp_collation;
 
1128
  enum_field_types cached_field_type;
 
1129
  cmp_item *cmp_items[5]; /* For all result types */
 
1130
  cmp_item *case_item;
 
1131
public:
 
1132
  Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
 
1133
    :Item_func(), first_expr_num(-1), else_expr_num(-1),
 
1134
    cached_result_type(INT_RESULT), left_result_type(INT_RESULT), case_item(0)
 
1135
  {
 
1136
    ncases= list.elements;
 
1137
    if (first_expr_arg)
 
1138
    {
 
1139
      first_expr_num= list.elements;
 
1140
      list.push_back(first_expr_arg);
 
1141
    }
 
1142
    if (else_expr_arg)
 
1143
    {
 
1144
      else_expr_num= list.elements;
 
1145
      list.push_back(else_expr_arg);
 
1146
    }
 
1147
    set_arguments(list);
 
1148
    bzero(&cmp_items, sizeof(cmp_items));
 
1149
  }
 
1150
  double val_real();
 
1151
  longlong val_int();
 
1152
  String *val_str(String *);
 
1153
  my_decimal *val_decimal(my_decimal *);
 
1154
  bool fix_fields(THD *thd, Item **ref);
 
1155
  void fix_length_and_dec();
 
1156
  uint decimal_precision() const;
 
1157
  table_map not_null_tables() const { return 0; }
 
1158
  enum Item_result result_type () const { return cached_result_type; }
 
1159
  enum_field_types field_type() const { return cached_field_type; }
 
1160
  const char *func_name() const { return "case"; }
 
1161
  virtual void print(String *str, enum_query_type query_type);
 
1162
  Item *find_item(String *str);
 
1163
  CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
 
1164
  void cleanup();
 
1165
  void agg_str_lengths(Item *arg);
 
1166
  void agg_num_lengths(Item *arg);
 
1167
};
 
1168
 
 
1169
/*
 
1170
  The Item_func_in class implements the in_expr IN(values_list) function.
 
1171
 
 
1172
  The current implementation distinguishes 2 cases:
 
1173
  1) all items in the value_list are constants and have the same
 
1174
    result type. This case is handled by in_vector class.
 
1175
  2) items in the value_list have different result types or there is some
 
1176
    non-constant items.
 
1177
    In this case Item_func_in employs several cmp_item objects to performs
 
1178
    comparisons of in_expr and an item from the values_list. One cmp_item
 
1179
    object for each result type. Different result types are collected in the
 
1180
    fix_length_and_dec() member function by means of collect_cmp_types()
 
1181
    function.
 
1182
*/
 
1183
class Item_func_in :public Item_func_opt_neg
 
1184
{
 
1185
public:
 
1186
  /* 
 
1187
    an array of values when the right hand arguments of IN
 
1188
    are all SQL constant and there are no nulls 
 
1189
  */
 
1190
  in_vector *array;
 
1191
  bool have_null;
 
1192
  /* 
 
1193
    true when all arguments of the IN clause are of compatible types
 
1194
    and can be used safely as comparisons for key conditions
 
1195
  */
 
1196
  bool arg_types_compatible;
 
1197
  Item_result left_result_type;
 
1198
  cmp_item *cmp_items[6]; /* One cmp_item for each result type */
 
1199
  DTCollation cmp_collation;
 
1200
 
 
1201
  Item_func_in(List<Item> &list)
 
1202
    :Item_func_opt_neg(list), array(0), have_null(0),
 
1203
    arg_types_compatible(FALSE)
 
1204
  {
 
1205
    bzero(&cmp_items, sizeof(cmp_items));
 
1206
    allowed_arg_cols= 0;  // Fetch this value from first argument
 
1207
  }
 
1208
  longlong val_int();
 
1209
  bool fix_fields(THD *, Item **);
 
1210
  void fix_length_and_dec();
 
1211
  uint decimal_precision() const { return 1; }
 
1212
  void cleanup()
 
1213
  {
 
1214
    uint i;
 
1215
    DBUG_ENTER("Item_func_in::cleanup");
 
1216
    Item_int_func::cleanup();
 
1217
    delete array;
 
1218
    array= 0;
 
1219
    for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
 
1220
    {
 
1221
      delete cmp_items[i];
 
1222
      cmp_items[i]= 0;
 
1223
    }
 
1224
    DBUG_VOID_RETURN;
 
1225
  }
 
1226
  optimize_type select_optimize() const
 
1227
    { return OPTIMIZE_KEY; }
 
1228
  virtual void print(String *str, enum_query_type query_type);
 
1229
  enum Functype functype() const { return IN_FUNC; }
 
1230
  const char *func_name() const { return " IN "; }
 
1231
  bool nulls_in_row();
 
1232
  bool is_bool_func() { return 1; }
 
1233
  CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
 
1234
};
 
1235
 
 
1236
class cmp_item_row :public cmp_item
 
1237
{
 
1238
  cmp_item **comparators;
 
1239
  uint n;
 
1240
public:
 
1241
  cmp_item_row(): comparators(0), n(0) {}
 
1242
  ~cmp_item_row();
 
1243
  void store_value(Item *item);
 
1244
  inline void alloc_comparators();
 
1245
  int cmp(Item *arg);
 
1246
  int compare(cmp_item *arg);
 
1247
  cmp_item *make_same();
 
1248
  void store_value_by_template(cmp_item *tmpl, Item *);
 
1249
  friend void Item_func_in::fix_length_and_dec();
 
1250
};
 
1251
 
 
1252
 
 
1253
class in_row :public in_vector
 
1254
{
 
1255
  cmp_item_row tmp;
 
1256
public:
 
1257
  in_row(uint elements, Item *);
 
1258
  ~in_row();
 
1259
  void set(uint pos,Item *item);
 
1260
  uchar *get_value(Item *item);
 
1261
  friend void Item_func_in::fix_length_and_dec();
 
1262
  Item_result result_type() { return ROW_RESULT; }
 
1263
};
 
1264
 
 
1265
/* Functions used by where clause */
 
1266
 
 
1267
class Item_func_isnull :public Item_bool_func
 
1268
{
 
1269
protected:
 
1270
  longlong cached_value;
 
1271
public:
 
1272
  Item_func_isnull(Item *a) :Item_bool_func(a) {}
 
1273
  longlong val_int();
 
1274
  enum Functype functype() const { return ISNULL_FUNC; }
 
1275
  void fix_length_and_dec()
 
1276
  {
 
1277
    decimals=0; max_length=1; maybe_null=0;
 
1278
    update_used_tables();
 
1279
  }
 
1280
  const char *func_name() const { return "isnull"; }
 
1281
  /* Optimize case of not_null_column IS NULL */
 
1282
  virtual void update_used_tables()
 
1283
  {
 
1284
    if (!args[0]->maybe_null)
 
1285
    {
 
1286
      used_tables_cache= 0;                     /* is always false */
 
1287
      const_item_cache= 1;
 
1288
      cached_value= (longlong) 0;
 
1289
    }
 
1290
    else
 
1291
    {
 
1292
      args[0]->update_used_tables();
 
1293
      if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())) &&
 
1294
          !with_subselect)
 
1295
      {
 
1296
        /* Remember if the value is always NULL or never NULL */
 
1297
        cached_value= (longlong) args[0]->is_null();
 
1298
      }
 
1299
    }
 
1300
  }
 
1301
  table_map not_null_tables() const { return 0; }
 
1302
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
 
1303
  Item *neg_transformer(THD *thd);
 
1304
  CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
 
1305
};
 
1306
 
 
1307
/* Functions used by HAVING for rewriting IN subquery */
 
1308
 
 
1309
class Item_in_subselect;
 
1310
 
 
1311
/* 
 
1312
  This is like IS NOT NULL but it also remembers if it ever has
 
1313
  encountered a NULL.
 
1314
*/
 
1315
class Item_is_not_null_test :public Item_func_isnull
 
1316
{
 
1317
  Item_in_subselect* owner;
 
1318
public:
 
1319
  Item_is_not_null_test(Item_in_subselect* ow, Item *a)
 
1320
    :Item_func_isnull(a), owner(ow)
 
1321
  {}
 
1322
  enum Functype functype() const { return ISNOTNULLTEST_FUNC; }
 
1323
  longlong val_int();
 
1324
  const char *func_name() const { return "<is_not_null_test>"; }
 
1325
  void update_used_tables();
 
1326
  /*
 
1327
    we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
 
1328
  */
 
1329
  table_map used_tables() const
 
1330
    { return used_tables_cache | RAND_TABLE_BIT; }
 
1331
};
 
1332
 
 
1333
 
 
1334
class Item_func_isnotnull :public Item_bool_func
 
1335
{
 
1336
  bool abort_on_null;
 
1337
public:
 
1338
  Item_func_isnotnull(Item *a) :Item_bool_func(a), abort_on_null(0) {}
 
1339
  longlong val_int();
 
1340
  enum Functype functype() const { return ISNOTNULL_FUNC; }
 
1341
  void fix_length_and_dec()
 
1342
  {
 
1343
    decimals=0; max_length=1; maybe_null=0;
 
1344
  }
 
1345
  const char *func_name() const { return "isnotnull"; }
 
1346
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
 
1347
  table_map not_null_tables() const
 
1348
  { return abort_on_null ? not_null_tables_cache : 0; }
 
1349
  Item *neg_transformer(THD *thd);
 
1350
  virtual void print(String *str, enum_query_type query_type);
 
1351
  CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
 
1352
  void top_level_item() { abort_on_null=1; }
 
1353
};
 
1354
 
 
1355
 
 
1356
class Item_func_like :public Item_bool_func2
 
1357
{
 
1358
  // Turbo Boyer-Moore data
 
1359
  bool        canDoTurboBM;     // pattern is '%abcd%' case
 
1360
  const char* pattern;
 
1361
  int         pattern_len;
 
1362
 
 
1363
  // TurboBM buffers, *this is owner
 
1364
  int* bmGs; //   good suffix shift table, size is pattern_len + 1
 
1365
  int* bmBc; // bad character shift table, size is alphabet_size
 
1366
 
 
1367
  void turboBM_compute_suffixes(int* suff);
 
1368
  void turboBM_compute_good_suffix_shifts(int* suff);
 
1369
  void turboBM_compute_bad_character_shifts();
 
1370
  bool turboBM_matches(const char* text, int text_len) const;
 
1371
  enum { alphabet_size = 256 };
 
1372
 
 
1373
  Item *escape_item;
 
1374
  
 
1375
  bool escape_used_in_parsing;
 
1376
 
 
1377
public:
 
1378
  int escape;
 
1379
 
 
1380
  Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
 
1381
    :Item_bool_func2(a,b), canDoTurboBM(FALSE), pattern(0), pattern_len(0), 
 
1382
     bmGs(0), bmBc(0), escape_item(escape_arg),
 
1383
     escape_used_in_parsing(escape_used) {}
 
1384
  longlong val_int();
 
1385
  enum Functype functype() const { return LIKE_FUNC; }
 
1386
  optimize_type select_optimize() const;
 
1387
  cond_result eq_cmp_result() const { return COND_TRUE; }
 
1388
  const char *func_name() const { return "like"; }
 
1389
  bool fix_fields(THD *thd, Item **ref);
 
1390
  void cleanup();
 
1391
};
 
1392
 
 
1393
 
 
1394
typedef class Item COND;
 
1395
 
 
1396
class Item_cond :public Item_bool_func
 
1397
{
 
1398
protected:
 
1399
  List<Item> list;
 
1400
  bool abort_on_null;
 
1401
  table_map and_tables_cache;
 
1402
 
 
1403
public:
 
1404
  /* Item_cond() is only used to create top level items */
 
1405
  Item_cond(): Item_bool_func(), abort_on_null(1)
 
1406
  { const_item_cache=0; }
 
1407
  Item_cond(Item *i1,Item *i2)
 
1408
    :Item_bool_func(), abort_on_null(0)
 
1409
  {
 
1410
    list.push_back(i1);
 
1411
    list.push_back(i2);
 
1412
  }
 
1413
  Item_cond(THD *thd, Item_cond *item);
 
1414
  Item_cond(List<Item> &nlist)
 
1415
    :Item_bool_func(), list(nlist), abort_on_null(0) {}
 
1416
  bool add(Item *item) { return list.push_back(item); }
 
1417
  bool add_at_head(Item *item) { return list.push_front(item); }
 
1418
  void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
 
1419
  bool fix_fields(THD *, Item **ref);
 
1420
  void fix_after_pullout(st_select_lex *new_parent, Item **ref);
 
1421
 
 
1422
  enum Type type() const { return COND_ITEM; }
 
1423
  List<Item>* argument_list() { return &list; }
 
1424
  table_map used_tables() const;
 
1425
  void update_used_tables();
 
1426
  virtual void print(String *str, enum_query_type query_type);
 
1427
  void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
 
1428
  friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
 
1429
                         COND **conds);
 
1430
  void top_level_item() { abort_on_null=1; }
 
1431
  void copy_andor_arguments(THD *thd, Item_cond *item);
 
1432
  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
 
1433
  Item *transform(Item_transformer transformer, uchar *arg);
 
1434
  void traverse_cond(Cond_traverser, void *arg, traverse_order order);
 
1435
  void neg_arguments(THD *thd);
 
1436
  enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
 
1437
  bool subst_argument_checker(uchar **arg) { return TRUE; }
 
1438
  Item *compile(Item_analyzer analyzer, uchar **arg_p,
 
1439
                Item_transformer transformer, uchar *arg_t);
 
1440
};
 
1441
 
 
1442
 
 
1443
/*
 
1444
  The class Item_equal is used to represent conjunctions of equality
 
1445
  predicates of the form field1 = field2, and field=const in where
 
1446
  conditions and on expressions.
 
1447
 
 
1448
  All equality predicates of the form field1=field2 contained in a
 
1449
  conjunction are substituted for a sequence of items of this class.
 
1450
  An item of this class Item_equal(f1,f2,...fk) represents a
 
1451
  multiple equality f1=f2=...=fk.
 
1452
 
 
1453
  If a conjunction contains predicates f1=f2 and f2=f3, a new item of
 
1454
  this class is created Item_equal(f1,f2,f3) representing the multiple
 
1455
  equality f1=f2=f3 that substitutes the above equality predicates in
 
1456
  the conjunction.
 
1457
  A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
 
1458
  substituted for the item representing the same multiple equality
 
1459
  f1=f2=f3.
 
1460
  An item Item_equal(f1,f2) can appear instead of a conjunction of 
 
1461
  f2=f1 and f1=f2, or instead of just the predicate f1=f2.
 
1462
 
 
1463
  An item of the class Item_equal inherits equalities from outer 
 
1464
  conjunctive levels.
 
1465
 
 
1466
  Suppose we have a where condition of the following form:
 
1467
  WHERE f1=f2 AND f3=f4 AND f3=f5 AND ... AND (...OR (f1=f3 AND ...)).
 
1468
  In this case:
 
1469
    f1=f2 will be substituted for Item_equal(f1,f2);
 
1470
    f3=f4 and f3=f5  will be substituted for Item_equal(f3,f4,f5);
 
1471
    f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
 
1472
 
 
1473
  An object of the class Item_equal can contain an optional constant
 
1474
  item c. Then it represents a multiple equality of the form 
 
1475
  c=f1=...=fk.
 
1476
 
 
1477
  Objects of the class Item_equal are used for the following:
 
1478
 
 
1479
  1. An object Item_equal(t1.f1,...,tk.fk) allows us to consider any
 
1480
  pair of tables ti and tj as joined by an equi-condition.
 
1481
  Thus it provide us with additional access paths from table to table.
 
1482
 
 
1483
  2. An object Item_equal(t1.f1,...,tk.fk) is applied to deduce new
 
1484
  SARGable predicates:
 
1485
    f1=...=fk AND P(fi) => f1=...=fk AND P(fi) AND P(fj).
 
1486
  It also can give us additional index scans and can allow us to
 
1487
  improve selectivity estimates.
 
1488
 
 
1489
  3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the 
 
1490
  selected execution plan for the query: if table ti is accessed 
 
1491
  before the table tj then in any predicate P in the where condition
 
1492
  the occurrence of tj.fj is substituted for ti.fi. This can allow
 
1493
  an evaluation of the predicate at an earlier step.
 
1494
 
 
1495
  When feature 1 is supported they say that join transitive closure 
 
1496
  is employed.
 
1497
  When feature 2 is supported they say that search argument transitive
 
1498
  closure is employed.
 
1499
  Both features are usually supported by preprocessing original query and
 
1500
  adding additional predicates.
 
1501
  We do not just add predicates, we rather dynamically replace some
 
1502
  predicates that can not be used to access tables in the investigated
 
1503
  plan for those, obtained by substitution of some fields for equal fields,
 
1504
  that can be used.     
 
1505
 
 
1506
  Prepared Statements/Stored Procedures note: instances of class
 
1507
  Item_equal are created only at the time a PS/SP is executed and
 
1508
  are deleted in the end of execution. All changes made to these
 
1509
  objects need not be registered in the list of changes of the parse
 
1510
  tree and do not harm PS/SP re-execution.
 
1511
 
 
1512
  Item equal objects are employed only at the optimize phase. Usually they are
 
1513
  not supposed to be evaluated.  Yet in some cases we call the method val_int()
 
1514
  for them. We have to take care of restricting the predicate such an
 
1515
  object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.
 
1516
*/
 
1517
 
 
1518
class Item_equal: public Item_bool_func
 
1519
{
 
1520
  List<Item_field> fields; /* list of equal field items                    */
 
1521
  Item *const_item;        /* optional constant item equal to fields items */
 
1522
  cmp_item *eval_item;
 
1523
  bool cond_false;
 
1524
public:
 
1525
  inline Item_equal()
 
1526
    : Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
 
1527
  { const_item_cache=0 ;}
 
1528
  Item_equal(Item_field *f1, Item_field *f2);
 
1529
  Item_equal(Item *c, Item_field *f);
 
1530
  Item_equal(Item_equal *item_equal);
 
1531
  inline Item* get_const() { return const_item; }
 
1532
  void add(Item *c);
 
1533
  void add(Item_field *f);
 
1534
  uint members();
 
1535
  bool contains(Field *field);
 
1536
  Item_field* get_first() { return fields.head(); }
 
1537
  void merge(Item_equal *item);
 
1538
  void update_const();
 
1539
  enum Functype functype() const { return MULT_EQUAL_FUNC; }
 
1540
  longlong val_int(); 
 
1541
  const char *func_name() const { return "multiple equal"; }
 
1542
  optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
 
1543
  void sort(Item_field_cmpfunc cmp, void *arg);
 
1544
  friend class Item_equal_iterator;
 
1545
  void fix_length_and_dec();
 
1546
  bool fix_fields(THD *thd, Item **ref);
 
1547
  void update_used_tables();
 
1548
  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
 
1549
  Item *transform(Item_transformer transformer, uchar *arg);
 
1550
  virtual void print(String *str, enum_query_type query_type);
 
1551
  CHARSET_INFO *compare_collation() 
 
1552
  { return fields.head()->collation.collation; }
 
1553
}; 
 
1554
 
 
1555
class COND_EQUAL: public Sql_alloc
 
1556
{
 
1557
public:
 
1558
  uint max_members;               /* max number of members the current level
 
1559
                                     list and all lower level lists */ 
 
1560
  COND_EQUAL *upper_levels;       /* multiple equalities of upper and levels */
 
1561
  List<Item_equal> current_level; /* list of multiple equalities of 
 
1562
                                     the current and level           */
 
1563
  COND_EQUAL()
 
1564
  { 
 
1565
    upper_levels= 0;
 
1566
  }
 
1567
};
 
1568
 
 
1569
 
 
1570
class Item_equal_iterator : public List_iterator_fast<Item_field>
 
1571
{
 
1572
public:
 
1573
  inline Item_equal_iterator(Item_equal &item_equal) 
 
1574
    :List_iterator_fast<Item_field> (item_equal.fields)
 
1575
  {}
 
1576
  inline Item_field* operator++(int)
 
1577
  { 
 
1578
    Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
 
1579
    return  item;
 
1580
  }
 
1581
  inline void rewind(void) 
 
1582
  { 
 
1583
    List_iterator_fast<Item_field>::rewind();
 
1584
  }
 
1585
};
 
1586
 
 
1587
class Item_cond_and :public Item_cond
 
1588
{
 
1589
public:
 
1590
  COND_EQUAL cond_equal;  /* contains list of Item_equal objects for 
 
1591
                             the current and level and reference
 
1592
                             to multiple equalities of upper and levels */  
 
1593
  Item_cond_and() :Item_cond() {}
 
1594
  Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
 
1595
  Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
 
1596
  Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
 
1597
  enum Functype functype() const { return COND_AND_FUNC; }
 
1598
  longlong val_int();
 
1599
  const char *func_name() const { return "and"; }
 
1600
  table_map not_null_tables() const
 
1601
  { return abort_on_null ? not_null_tables_cache: and_tables_cache; }
 
1602
  Item* copy_andor_structure(THD *thd)
 
1603
  {
 
1604
    Item_cond_and *item;
 
1605
    if ((item= new Item_cond_and(thd, this)))
 
1606
       item->copy_andor_arguments(thd, this);
 
1607
    return item;
 
1608
  }
 
1609
  Item *neg_transformer(THD *thd);
 
1610
};
 
1611
 
 
1612
inline bool is_cond_and(Item *item)
 
1613
{
 
1614
  if (item->type() != Item::COND_ITEM)
 
1615
    return FALSE;
 
1616
 
 
1617
  Item_cond *cond_item= (Item_cond*) item;
 
1618
  return (cond_item->functype() == Item_func::COND_AND_FUNC);
 
1619
}
 
1620
 
 
1621
class Item_cond_or :public Item_cond
 
1622
{
 
1623
public:
 
1624
  Item_cond_or() :Item_cond() {}
 
1625
  Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
 
1626
  Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
 
1627
  Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
 
1628
  enum Functype functype() const { return COND_OR_FUNC; }
 
1629
  longlong val_int();
 
1630
  const char *func_name() const { return "or"; }
 
1631
  table_map not_null_tables() const { return and_tables_cache; }
 
1632
  Item* copy_andor_structure(THD *thd)
 
1633
  {
 
1634
    Item_cond_or *item;
 
1635
    if ((item= new Item_cond_or(thd, this)))
 
1636
      item->copy_andor_arguments(thd, this);
 
1637
    return item;
 
1638
  }
 
1639
  Item *neg_transformer(THD *thd);
 
1640
};
 
1641
 
 
1642
inline bool is_cond_or(Item *item)
 
1643
{
 
1644
  if (item->type() != Item::COND_ITEM)
 
1645
    return FALSE;
 
1646
 
 
1647
  Item_cond *cond_item= (Item_cond*) item;
 
1648
  return (cond_item->functype() == Item_func::COND_OR_FUNC);
 
1649
}
 
1650
 
 
1651
/*
 
1652
  XOR is Item_cond, not an Item_int_func because we could like to
 
1653
  optimize (a XOR b) later on. It's low prio, though
 
1654
*/
 
1655
 
 
1656
class Item_cond_xor :public Item_cond
 
1657
{
 
1658
public:
 
1659
  Item_cond_xor() :Item_cond() {}
 
1660
  Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2) {}
 
1661
  enum Functype functype() const { return COND_XOR_FUNC; }
 
1662
  /* TODO: remove the next line when implementing XOR optimization */
 
1663
  enum Type type() const { return FUNC_ITEM; }
 
1664
  longlong val_int();
 
1665
  const char *func_name() const { return "xor"; }
 
1666
  void top_level_item() {}
 
1667
};
 
1668
 
 
1669
 
 
1670
/* Some useful inline functions */
 
1671
 
 
1672
inline Item *and_conds(Item *a, Item *b)
 
1673
{
 
1674
  if (!b) return a;
 
1675
  if (!a) return b;
 
1676
  return new Item_cond_and(a, b);
 
1677
}
 
1678
 
 
1679
Item *and_expressions(Item *a, Item *b, Item **org_item);