~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to sql/item_cmpfunc.h

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

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