item_cmpfunc.h 44.7 KB
Newer Older
unknown's avatar
unknown committed
1
/* Copyright (C) 2000-2003 MySQL AB
unknown's avatar
unknown committed
2

unknown's avatar
unknown committed
3 4
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
unknown's avatar
unknown committed
5
   the Free Software Foundation; version 2 of the License.
unknown's avatar
unknown committed
6

unknown's avatar
unknown committed
7 8 9 10
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
unknown's avatar
unknown committed
11

unknown's avatar
unknown committed
12 13 14 15 16 17 18
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */


/* compare and test functions */

19
#ifdef USE_PRAGMA_INTERFACE
unknown's avatar
unknown committed
20 21 22
#pragma interface			/* gcc class implementation */
#endif

23 24 25 26 27 28
extern Item_result item_cmp_type(Item_result a,Item_result b);
class Item_bool_func2;
class Arg_comparator;

typedef int (Arg_comparator::*arg_cmp_func)();

unknown's avatar
unknown committed
29 30
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg); 

31 32 33 34 35 36
class Arg_comparator: public Sql_alloc
{
  Item **a, **b;
  arg_cmp_func func;
  Item_bool_func2 *owner;
  Arg_comparator *comparators;   // used only for compare_row()
37
  double precision;
38 39

public:
40 41
  DTCollation cmp_collation;

42 43 44 45
  Arg_comparator() {};
  Arg_comparator(Item **a1, Item **a2): a(a1), b(a2) {};

  int set_compare_func(Item_bool_func2 *owner, Item_result type);
46
  inline int set_compare_func(Item_bool_func2 *owner_arg)
47
  {
unknown's avatar
unknown committed
48 49
    return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(),
                                                     (*b)->result_type()));
50
  }
51
  inline int set_cmp_func(Item_bool_func2 *owner_arg,
52 53 54 55 56
			  Item **a1, Item **a2,
			  Item_result type)
  {
    a= a1;
    b= a2;
57
    return set_compare_func(owner_arg, type);
58
  }
59
  inline int set_cmp_func(Item_bool_func2 *owner_arg,
60 61
			  Item **a1, Item **a2)
  {
unknown's avatar
unknown committed
62 63 64
    return set_cmp_func(owner_arg, a1, a2,
                        item_cmp_type((*a1)->result_type(),
                                      (*a2)->result_type()));
65 66 67 68
  }
  inline int compare() { return (this->*func)(); }

  int compare_string();		 // compare args[0] & args[1]
unknown's avatar
unknown committed
69
  int compare_binary_string();	 // compare args[0] & args[1]
70
  int compare_real();            // compare args[0] & args[1]
unknown's avatar
unknown committed
71
  int compare_decimal();         // compare args[0] & args[1]
72
  int compare_int_signed();      // compare args[0] & args[1]
73 74 75
  int compare_int_signed_unsigned();
  int compare_int_unsigned_signed();
  int compare_int_unsigned();
76 77
  int compare_row();             // compare args[0] & args[1]
  int compare_e_string();	 // compare args[0] & args[1]
unknown's avatar
unknown committed
78
  int compare_e_binary_string(); // compare args[0] & args[1]
79
  int compare_e_real();          // compare args[0] & args[1]
unknown's avatar
unknown committed
80
  int compare_e_decimal();       // compare args[0] & args[1]
81
  int compare_e_int();           // compare args[0] & args[1]
82
  int compare_e_int_diff_signedness();
83
  int compare_e_row();           // compare args[0] & args[1]
84 85
  int compare_real_fixed();
  int compare_e_real_fixed();
86

unknown's avatar
unknown committed
87
  static arg_cmp_func comparator_matrix [5][2];
88 89 90 91

  friend class Item_func;
};

unknown's avatar
unknown committed
92 93 94 95 96 97
class Item_bool_func :public Item_int_func
{
public:
  Item_bool_func() :Item_int_func() {}
  Item_bool_func(Item *a) :Item_int_func(a) {}
  Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
98
  Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {}
unknown's avatar
unknown committed
99
  bool is_bool_func() { return 1; }
unknown's avatar
unknown committed
100
  void fix_length_and_dec() { decimals=0; max_length=1; }
unknown's avatar
unknown committed
101
  uint decimal_precision() const { return 1; }
unknown's avatar
unknown committed
102 103
};

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189

/**
  Abstract Item class, to represent <code>X IS [NOT] (TRUE | FALSE)</code>
  boolean predicates.
*/

class Item_func_truth : public Item_bool_func
{
public:
  virtual bool val_bool();
  virtual longlong val_int();
  virtual void fix_length_and_dec();
  virtual void print(String *str);

protected:
  Item_func_truth(Item *a, bool a_value, bool a_affirmative)
  : Item_bool_func(a), value(a_value), affirmative(a_affirmative)
  {}

  ~Item_func_truth()
  {}
private:
  /**
    True for <code>X IS [NOT] TRUE</code>,
    false for <code>X IS [NOT] FALSE</code> predicates.
  */
  const bool value;
  /**
    True for <code>X IS Y</code>, false for <code>X IS NOT Y</code> predicates.
  */
  const bool affirmative;
};


/**
  This Item represents a <code>X IS TRUE</code> boolean predicate.
*/

class Item_func_istrue : public Item_func_truth
{
public:
  Item_func_istrue(Item *a) : Item_func_truth(a, true, true) {}
  ~Item_func_istrue() {}
  virtual const char* func_name() const { return "istrue"; }
};


/**
  This Item represents a <code>X IS NOT TRUE</code> boolean predicate.
*/

class Item_func_isnottrue : public Item_func_truth
{
public:
  Item_func_isnottrue(Item *a) : Item_func_truth(a, true, false) {}
  ~Item_func_isnottrue() {}
  virtual const char* func_name() const { return "isnottrue"; }
};


/**
  This Item represents a <code>X IS FALSE</code> boolean predicate.
*/

class Item_func_isfalse : public Item_func_truth
{
public:
  Item_func_isfalse(Item *a) : Item_func_truth(a, false, true) {}
  ~Item_func_isfalse() {}
  virtual const char* func_name() const { return "isfalse"; }
};


/**
  This Item represents a <code>X IS NOT FALSE</code> boolean predicate.
*/

class Item_func_isnotfalse : public Item_func_truth
{
public:
  Item_func_isnotfalse(Item *a) : Item_func_truth(a, false, false) {}
  ~Item_func_isnotfalse() {}
  virtual const char* func_name() const { return "isnotfalse"; }
};


190
class Item_cache;
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
#define UNKNOWN ((my_bool)-1)


/*
  Item_in_optimizer(left_expr, Item_in_subselect(...))

  Item_in_optimizer is used to wrap an instance of Item_in_subselect. This
  class does the following:
   - Evaluate the left expression and store it in Item_cache_* object (to
     avoid re-evaluating it many times during subquery execution)
   - Shortcut the evaluation of "NULL IN (...)" to NULL in the cases where we
     don't care if the result is NULL or FALSE.

  NOTE
    It is not quite clear why the above listed functionality should be
    placed into a separate class called 'Item_in_optimizer'.
*/

209 210 211
class Item_in_optimizer: public Item_bool_func
{
protected:
212
  Item_cache *cache;
213
  bool save_cache;
214 215 216 217 218 219 220
  /* 
    Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
      UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
      FALSE   - result is FALSE
      TRUE    - result is NULL
  */
  my_bool result_for_null_param;
221
public:
unknown's avatar
unknown committed
222
  Item_in_optimizer(Item *a, Item_in_subselect *b):
223 224
    Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0),
    save_cache(0), result_for_null_param(UNKNOWN)
225
  {}
226 227
  bool fix_fields(THD *, Item **);
  bool fix_left(THD *thd, Item **ref);
228
  bool is_null();
229
  longlong val_int();
unknown's avatar
unknown committed
230
  void cleanup();
231
  const char *func_name() const { return "<in_optimizer>"; }
unknown's avatar
unknown committed
232
  Item_cache **get_cache() { return &cache; }
233
  void keep_top_level_cache();
234 235
};

unknown's avatar
unknown committed
236 237 238
class Comp_creator
{
public:
239 240
  Comp_creator() {}                           /* Remove gcc warning */
  virtual ~Comp_creator() {}                  /* Remove gcc warning */
unknown's avatar
unknown committed
241 242 243 244 245 246 247 248 249
  virtual Item_bool_func2* create(Item *a, Item *b) const = 0;
  virtual const char* symbol(bool invert) const = 0;
  virtual bool eqne_op() const = 0;
  virtual bool l_op() const = 0;
};

class Eq_creator :public Comp_creator
{
public:
250 251
  Eq_creator() {}                             /* Remove gcc warning */
  virtual ~Eq_creator() {}                    /* Remove gcc warning */
unknown's avatar
unknown committed
252 253 254 255 256 257 258 259 260
  virtual Item_bool_func2* create(Item *a, Item *b) const;
  virtual const char* symbol(bool invert) const { return invert? "<>" : "="; }
  virtual bool eqne_op() const { return 1; }
  virtual bool l_op() const { return 0; }
};

class Ne_creator :public Comp_creator
{
public:
261 262
  Ne_creator() {}                             /* Remove gcc warning */
  virtual ~Ne_creator() {}                    /* Remove gcc warning */
unknown's avatar
unknown committed
263 264 265 266 267 268 269 270 271
  virtual Item_bool_func2* create(Item *a, Item *b) const;
  virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; }
  virtual bool eqne_op() const { return 1; }
  virtual bool l_op() const { return 0; }
};

class Gt_creator :public Comp_creator
{
public:
272 273
  Gt_creator() {}                             /* Remove gcc warning */
  virtual ~Gt_creator() {}                    /* Remove gcc warning */
unknown's avatar
unknown committed
274 275 276 277 278 279 280 281 282
  virtual Item_bool_func2* create(Item *a, Item *b) const;
  virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
  virtual bool eqne_op() const { return 0; }
  virtual bool l_op() const { return 0; }
};

class Lt_creator :public Comp_creator
{
public:
283 284
  Lt_creator() {}                             /* Remove gcc warning */
  virtual ~Lt_creator() {}                    /* Remove gcc warning */
unknown's avatar
unknown committed
285 286 287 288 289 290 291 292 293
  virtual Item_bool_func2* create(Item *a, Item *b) const;
  virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
  virtual bool eqne_op() const { return 0; }
  virtual bool l_op() const { return 1; }
};

class Ge_creator :public Comp_creator
{
public:
294 295
  Ge_creator() {}                             /* Remove gcc warning */
  virtual ~Ge_creator() {}                    /* Remove gcc warning */
unknown's avatar
unknown committed
296 297 298 299 300 301 302 303 304
  virtual Item_bool_func2* create(Item *a, Item *b) const;
  virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
  virtual bool eqne_op() const { return 0; }
  virtual bool l_op() const { return 0; }
};

class Le_creator :public Comp_creator
{
public:
305 306
  Le_creator() {}                             /* Remove gcc warning */
  virtual ~Le_creator() {}                    /* Remove gcc warning */
unknown's avatar
unknown committed
307 308 309 310 311 312
  virtual Item_bool_func2* create(Item *a, Item *b) const;
  virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
  virtual bool eqne_op() const { return 0; }
  virtual bool l_op() const { return 1; }
};

unknown's avatar
unknown committed
313 314 315
class Item_bool_func2 :public Item_int_func
{						/* Bool with 2 string args */
protected:
316
  Arg_comparator cmp;
unknown's avatar
unknown committed
317
  String tmp_value1,tmp_value2;
318
  bool abort_on_null;
319

unknown's avatar
unknown committed
320
public:
321
  Item_bool_func2(Item *a,Item *b)
322
    :Item_int_func(a,b), cmp(tmp_arg, tmp_arg+1), abort_on_null(FALSE) {}
unknown's avatar
unknown committed
323
  void fix_length_and_dec();
324
  void set_cmp_func()
unknown's avatar
unknown committed
325
  {
326
    cmp.set_cmp_func(this, tmp_arg, tmp_arg+1);
unknown's avatar
unknown committed
327
  }
unknown's avatar
unknown committed
328 329 330 331
  optimize_type select_optimize() const { return OPTIMIZE_OP; }
  virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
  bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
  void print(String *str) { Item_func::print_op(str); }
unknown's avatar
unknown committed
332
  bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
unknown's avatar
unknown committed
333
  bool is_bool_func() { return 1; }
334
  CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
unknown's avatar
unknown committed
335
  uint decimal_precision() const { return 1; }
336
  void top_level_item() { abort_on_null=1; }
unknown's avatar
unknown committed
337

338
  friend class  Arg_comparator;
unknown's avatar
unknown committed
339 340
};

unknown's avatar
unknown committed
341 342 343
class Item_bool_rowready_func2 :public Item_bool_func2
{
public:
344
  Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b)
unknown's avatar
unknown committed
345
  {
346
    allowed_arg_cols= 0;  // Fetch this value from first argument
unknown's avatar
unknown committed
347
  }
348 349
  Item *neg_transformer(THD *thd);
  virtual Item *negated_item();
350
  bool subst_argument_checker(byte **arg) { return TRUE; }
unknown's avatar
unknown committed
351
};
unknown's avatar
unknown committed
352 353 354 355 356 357

class Item_func_not :public Item_bool_func
{
public:
  Item_func_not(Item *a) :Item_bool_func(a) {}
  longlong val_int();
358
  enum Functype functype() const { return NOT_FUNC; }
unknown's avatar
unknown committed
359
  const char *func_name() const { return "not"; }
360
  Item *neg_transformer(THD *thd);
361
  void print(String *str);
unknown's avatar
unknown committed
362 363
};

364
class Item_maxmin_subselect;
365 366

/*
367 368
  trigcond<param>(arg) ::= param? arg : TRUE

369 370
  The class Item_func_trig_cond is used for guarded predicates 
  which are employed only for internal purposes.
371
  A guarded predicate is an object consisting of an a regular or
372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
  a guarded predicate P and a pointer to a boolean guard variable g. 
  A guarded predicate P/g is evaluated to true if the value of the
  guard g is false, otherwise it is evaluated to the same value that
  the predicate P: val(P/g)= g ? val(P):true.
  Guarded predicates allow us to include predicates into a conjunction
  conditionally. Currently they are utilized for pushed down predicates
  in queries with outer join operations.

  In the future, probably, it makes sense to extend this class to
  the objects consisting of three elements: a predicate P, a pointer
  to a variable g and a firing value s with following evaluation
  rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
  one item for the objects of the form P/g1/g2... 

  Objects of this class are built only for query execution after
  the execution plan has been already selected. That's why this
  class needs only val_int out of generic methods. 
389 390 391 392
 
  Current uses of Item_func_trig_cond objects:
   - To wrap selection conditions when executing outer joins
   - To wrap condition that is pushed down into subquery
393 394 395 396 397 398 399 400 401 402
*/

class Item_func_trig_cond: public Item_bool_func
{
  bool *trig_var;
public:
  Item_func_trig_cond(Item *a, bool *f) : Item_bool_func(a) { trig_var= f; }
  longlong val_int() { return *trig_var ? args[0]->val_int() : 1; }
  enum Functype functype() const { return TRIG_COND_FUNC; };
  const char *func_name() const { return "trigcond"; };
403
  bool const_item() const { return FALSE; }
404
  bool *get_trig_var() { return trig_var; }
405 406
};

407 408
class Item_func_not_all :public Item_func_not
{
unknown's avatar
unknown committed
409
  /* allow to check presence of values in max/min optimization */
410 411 412
  Item_sum_hybrid *test_sum_item;
  Item_maxmin_subselect *test_sub_item;

413 414
  bool abort_on_null;
public:
unknown's avatar
unknown committed
415 416
  bool show;

417 418 419 420
  Item_func_not_all(Item *a)
    :Item_func_not(a), test_sum_item(0), test_sub_item(0), abort_on_null(0),
     show(0)
    {}
421 422 423
  virtual void top_level_item() { abort_on_null= 1; }
  bool top_level() { return abort_on_null; }
  longlong val_int();
424
  enum Functype functype() const { return NOT_ALL_FUNC; }
unknown's avatar
unknown committed
425 426
  const char *func_name() const { return "<not>"; }
  void print(String *str);
427 428 429
  void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
  void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
  bool empty_underlying_subquery();
430
  Item *neg_transformer(THD *thd);
431 432
};

433 434 435 436 437 438 439 440

class Item_func_nop_all :public Item_func_not_all
{
public:

  Item_func_nop_all(Item *a) :Item_func_not_all(a) {}
  longlong val_int();
  const char *func_name() const { return "<nop>"; }
441
  Item *neg_transformer(THD *thd);
442 443 444
};


unknown's avatar
unknown committed
445
class Item_func_eq :public Item_bool_rowready_func2
unknown's avatar
unknown committed
446 447
{
public:
448
  Item_func_eq(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
unknown's avatar
unknown committed
449 450 451 452 453
  longlong val_int();
  enum Functype functype() const { return EQ_FUNC; }
  enum Functype rev_functype() const { return EQ_FUNC; }
  cond_result eq_cmp_result() const { return COND_TRUE; }
  const char *func_name() const { return "="; }
454
  Item *negated_item();
unknown's avatar
unknown committed
455 456
};

unknown's avatar
unknown committed
457
class Item_func_equal :public Item_bool_rowready_func2
unknown's avatar
unknown committed
458 459
{
public:
unknown's avatar
unknown committed
460
  Item_func_equal(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
unknown's avatar
unknown committed
461
  longlong val_int();
unknown's avatar
unknown committed
462
  void fix_length_and_dec();
463
  table_map not_null_tables() const { return 0; }
unknown's avatar
unknown committed
464 465 466 467
  enum Functype functype() const { return EQUAL_FUNC; }
  enum Functype rev_functype() const { return EQUAL_FUNC; }
  cond_result eq_cmp_result() const { return COND_TRUE; }
  const char *func_name() const { return "<=>"; }
468
  Item *neg_transformer(THD *thd) { return 0; }
unknown's avatar
unknown committed
469 470 471
};


unknown's avatar
unknown committed
472
class Item_func_ge :public Item_bool_rowready_func2
unknown's avatar
unknown committed
473 474
{
public:
475
  Item_func_ge(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
unknown's avatar
unknown committed
476 477 478 479 480
  longlong val_int();
  enum Functype functype() const { return GE_FUNC; }
  enum Functype rev_functype() const { return LE_FUNC; }
  cond_result eq_cmp_result() const { return COND_TRUE; }
  const char *func_name() const { return ">="; }
481
  Item *negated_item();
unknown's avatar
unknown committed
482 483 484
};


unknown's avatar
unknown committed
485
class Item_func_gt :public Item_bool_rowready_func2
unknown's avatar
unknown committed
486 487
{
public:
488
  Item_func_gt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
unknown's avatar
unknown committed
489 490 491 492 493
  longlong val_int();
  enum Functype functype() const { return GT_FUNC; }
  enum Functype rev_functype() const { return LT_FUNC; }
  cond_result eq_cmp_result() const { return COND_FALSE; }
  const char *func_name() const { return ">"; }
494
  Item *negated_item();
unknown's avatar
unknown committed
495 496 497
};


unknown's avatar
unknown committed
498
class Item_func_le :public Item_bool_rowready_func2
unknown's avatar
unknown committed
499 500
{
public:
501
  Item_func_le(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
unknown's avatar
unknown committed
502 503 504 505 506
  longlong val_int();
  enum Functype functype() const { return LE_FUNC; }
  enum Functype rev_functype() const { return GE_FUNC; }
  cond_result eq_cmp_result() const { return COND_TRUE; }
  const char *func_name() const { return "<="; }
507
  Item *negated_item();
unknown's avatar
unknown committed
508 509 510
};


unknown's avatar
unknown committed
511
class Item_func_lt :public Item_bool_rowready_func2
unknown's avatar
unknown committed
512 513
{
public:
514
  Item_func_lt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
unknown's avatar
unknown committed
515 516 517 518 519
  longlong val_int();
  enum Functype functype() const { return LT_FUNC; }
  enum Functype rev_functype() const { return GT_FUNC; }
  cond_result eq_cmp_result() const { return COND_FALSE; }
  const char *func_name() const { return "<"; }
520
  Item *negated_item();
unknown's avatar
unknown committed
521 522 523
};


unknown's avatar
unknown committed
524
class Item_func_ne :public Item_bool_rowready_func2
unknown's avatar
unknown committed
525 526
{
public:
527
  Item_func_ne(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
unknown's avatar
unknown committed
528 529 530
  longlong val_int();
  enum Functype functype() const { return NE_FUNC; }
  cond_result eq_cmp_result() const { return COND_FALSE; }
unknown's avatar
unknown committed
531
  optimize_type select_optimize() const { return OPTIMIZE_KEY; } 
unknown's avatar
unknown committed
532
  const char *func_name() const { return "<>"; }
533
  Item *negated_item();
unknown's avatar
unknown committed
534 535 536
};


unknown's avatar
unknown committed
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
/*
  The class Item_func_opt_neg is defined to factor out the functionality
  common for the classes Item_func_between and Item_func_in. The objects
  of these classes can express predicates or there negations.
  The alternative approach would be to create pairs Item_func_between,
  Item_func_notbetween and Item_func_in, Item_func_notin.

*/

class Item_func_opt_neg :public Item_int_func
{
public:
  bool negated;     /* <=> the item represents NOT <func> */
  bool pred_level;  /* <=> [NOT] <func> is used on a predicate level */
public:
  Item_func_opt_neg(Item *a, Item *b, Item *c)
    :Item_int_func(a, b, c), negated(0), pred_level(0) {}
  Item_func_opt_neg(List<Item> &list)
    :Item_int_func(list), negated(0), pred_level(0) {}
public:
  inline void negate() { negated= !negated; }
  inline void top_level_item() { pred_level= 1; }
  Item *neg_transformer(THD *thd)
  {
    negated= !negated;
    return this;
  }
unknown's avatar
unknown committed
564
  bool subst_argument_checker(byte **arg) { return TRUE; }
unknown's avatar
unknown committed
565 566 567 568
};


class Item_func_between :public Item_func_opt_neg
unknown's avatar
unknown committed
569
{
570
  DTCollation cmp_collation;
unknown's avatar
unknown committed
571 572 573
public:
  Item_result cmp_type;
  String value0,value1,value2;
unknown's avatar
unknown committed
574 575
  Item_func_between(Item *a, Item *b, Item *c)
    :Item_func_opt_neg(a, b, c) {}
unknown's avatar
unknown committed
576 577 578 579
  longlong val_int();
  optimize_type select_optimize() const { return OPTIMIZE_KEY; }
  enum Functype functype() const   { return BETWEEN; }
  const char *func_name() const { return "between"; }
580
  bool fix_fields(THD *, Item **);
unknown's avatar
unknown committed
581
  void fix_length_and_dec();
582
  void print(String *str);
unknown's avatar
unknown committed
583
  bool is_bool_func() { return 1; }
584
  CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
unknown's avatar
unknown committed
585
  uint decimal_precision() const { return 1; }
unknown's avatar
unknown committed
586 587 588 589 590 591 592 593 594 595
};


class Item_func_strcmp :public Item_bool_func2
{
public:
  Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {}
  longlong val_int();
  optimize_type select_optimize() const { return OPTIMIZE_NONE; }
  const char *func_name() const { return "strcmp"; }
596
  void print(String *str) { Item_func::print(str); }
unknown's avatar
unknown committed
597 598 599
};


unknown's avatar
unknown committed
600 601 602 603 604 605 606
struct interval_range
{
  Item_result type;
  double dbl;
  my_decimal dec;
};

unknown's avatar
unknown committed
607 608
class Item_func_interval :public Item_int_func
{
609
  Item_row *row;
unknown's avatar
unknown committed
610 611
  my_bool use_decimal_comparison;
  interval_range *intervals;
unknown's avatar
unknown committed
612
public:
613
  Item_func_interval(Item_row *a)
614 615 616 617
    :Item_int_func(a),row(a),intervals(0)
  {
    allowed_arg_cols= 0;    // Fetch this value from first argument
  }
unknown's avatar
unknown committed
618 619 620
  longlong val_int();
  void fix_length_and_dec();
  const char *func_name() const { return "interval"; }
unknown's avatar
unknown committed
621
  uint decimal_precision() const { return 2; }
unknown's avatar
unknown committed
622 623 624
};


unknown's avatar
unknown committed
625
class Item_func_coalesce :public Item_func_numhybrid
unknown's avatar
unknown committed
626
{
unknown's avatar
unknown committed
627
protected:
unknown's avatar
unknown committed
628
  Item_func_coalesce(Item *a, Item *b) :Item_func_numhybrid(a, b) {}
unknown's avatar
unknown committed
629
public:
unknown's avatar
unknown committed
630 631 632 633 634
  Item_func_coalesce(List<Item> &list) :Item_func_numhybrid(list) {}
  double real_op();
  longlong int_op();
  String *str_op(String *);
  my_decimal *decimal_op(my_decimal *);
unknown's avatar
unknown committed
635
  void fix_length_and_dec();
unknown's avatar
unknown committed
636 637
  void find_num_type() {}
  enum Item_result result_type () const { return hybrid_type; }
unknown's avatar
unknown committed
638 639 640 641 642 643 644 645
  const char *func_name() const { return "coalesce"; }
  table_map not_null_tables() const { return 0; }
};


class Item_func_ifnull :public Item_func_coalesce
{
protected:
646 647
  enum_field_types cached_field_type;
  bool field_type_defined;
unknown's avatar
unknown committed
648
public:
unknown's avatar
unknown committed
649
  Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
unknown's avatar
unknown committed
650 651 652 653
  double real_op();
  longlong int_op();
  String *str_op(String *str);
  my_decimal *decimal_op(my_decimal *);
654
  enum_field_types field_type() const;
unknown's avatar
unknown committed
655 656
  void fix_length_and_dec();
  const char *func_name() const { return "ifnull"; }
657
  Field *tmp_table_field(TABLE *table);
unknown's avatar
unknown committed
658
  uint decimal_precision() const;
unknown's avatar
unknown committed
659 660 661 662 663 664 665
};


class Item_func_if :public Item_func
{
  enum Item_result cached_result_type;
public:
666 667 668
  Item_func_if(Item *a,Item *b,Item *c)
    :Item_func(a,b,c), cached_result_type(INT_RESULT)
  {}
669
  double val_real();
unknown's avatar
unknown committed
670 671
  longlong val_int();
  String *val_str(String *str);
unknown's avatar
unknown committed
672
  my_decimal *val_decimal(my_decimal *);
unknown's avatar
unknown committed
673
  enum Item_result result_type () const { return cached_result_type; }
674
  bool fix_fields(THD *, Item **);
unknown's avatar
unknown committed
675
  void fix_length_and_dec();
unknown's avatar
unknown committed
676
  uint decimal_precision() const;
unknown's avatar
unknown committed
677 678 679 680 681 682 683 684
  const char *func_name() const { return "if"; }
};


class Item_func_nullif :public Item_bool_func2
{
  enum Item_result cached_result_type;
public:
685 686 687
  Item_func_nullif(Item *a,Item *b)
    :Item_bool_func2(a,b), cached_result_type(INT_RESULT)
  {}
688
  double val_real();
unknown's avatar
unknown committed
689 690
  longlong val_int();
  String *val_str(String *str);
unknown's avatar
unknown committed
691
  my_decimal *val_decimal(my_decimal *);
unknown's avatar
unknown committed
692 693
  enum Item_result result_type () const { return cached_result_type; }
  void fix_length_and_dec();
unknown's avatar
unknown committed
694
  uint decimal_precision() const { return args[0]->decimal_precision(); }
unknown's avatar
unknown committed
695
  const char *func_name() const { return "nullif"; }
696
  void print(String *str) { Item_func::print(str); }
697
  table_map not_null_tables() const { return 0; }
698
  bool is_null();
unknown's avatar
unknown committed
699 700 701 702 703
};


class Item_func_case :public Item_func
{
704
  int first_expr_num, else_expr_num;
unknown's avatar
unknown committed
705 706
  enum Item_result cached_result_type;
  String tmp_value;
707
  uint ncases;
708 709
  Item_result cmp_type;
  DTCollation cmp_collation;
unknown's avatar
unknown committed
710
public:
711
  Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
712
    :Item_func(), first_expr_num(-1), else_expr_num(-1),
713
    cached_result_type(INT_RESULT)
unknown's avatar
unknown committed
714
  {
715 716 717 718 719 720 721 722 723 724 725 726 727
    ncases= list.elements;
    if (first_expr_arg)
    {
      first_expr_num= list.elements;
      list.push_back(first_expr_arg);
    }
    if (else_expr_arg)
    {
      else_expr_num= list.elements;
      list.push_back(else_expr_arg);
    }
    set_arguments(list);
  }
728
  double val_real();
unknown's avatar
unknown committed
729 730
  longlong val_int();
  String *val_str(String *);
unknown's avatar
unknown committed
731
  my_decimal *val_decimal(my_decimal *);
unknown's avatar
unknown committed
732
  bool fix_fields(THD *thd, Item **ref);
unknown's avatar
unknown committed
733
  void fix_length_and_dec();
unknown's avatar
unknown committed
734
  uint decimal_precision() const;
735
  table_map not_null_tables() const { return 0; }
unknown's avatar
unknown committed
736 737 738 739
  enum Item_result result_type () const { return cached_result_type; }
  const char *func_name() const { return "case"; }
  void print(String *str);
  Item *find_item(String *str);
740
  CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
unknown's avatar
unknown committed
741 742 743 744 745
};


/* Functions to handle the optimized IN */

746 747 748

/* A vector of values of some type  */

unknown's avatar
unknown committed
749 750
class in_vector :public Sql_alloc
{
751
public:
unknown's avatar
unknown committed
752 753
  char *base;
  uint size;
754 755
  qsort2_cmp compare;
  CHARSET_INFO *collation;
unknown's avatar
unknown committed
756 757
  uint count;
  uint used_count;
unknown's avatar
unknown committed
758
  in_vector() {}
759 760
  in_vector(uint elements,uint element_length,qsort2_cmp cmp_func, 
  	    CHARSET_INFO *cmp_coll)
unknown's avatar
unknown committed
761
    :base((char*) sql_calloc(elements*element_length)),
762 763
     size(element_length), compare(cmp_func), collation(cmp_coll),
     count(elements), used_count(elements) {}
unknown's avatar
unknown committed
764 765 766 767
  virtual ~in_vector() {}
  virtual void set(uint pos,Item *item)=0;
  virtual byte *get_value(Item *item)=0;
  void sort()
768
  {
769
    qsort2(base,used_count,size,compare,collation);
770
  }
unknown's avatar
unknown committed
771
  int find(Item *item);
772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797
  
  /* 
    Create an instance of Item_{type} (e.g. Item_decimal) constant object
    which type allows it to hold an element of this vector without any
    conversions.
    The purpose of this function is to be able to get elements of this
    vector in form of Item_xxx constants without creating Item_xxx object
    for every array element you get (i.e. this implements "FlyWeight" pattern)
  */
  virtual Item* create_item() { return NULL; }
  
  /*
    Store the value at position #pos into provided item object
    SYNOPSIS
      value_to_item()
        pos   Index of value to store
        item  Constant item to store value into. The item must be of the same
              type that create_item() returns.
  */
  virtual void value_to_item(uint pos, Item *item) { }
  
  /* Compare values number pos1 and pos2 for equality */
  bool compare_elems(uint pos1, uint pos2)
  {
    return test(compare(collation, base + pos1*size, base + pos2*size));
  }
unknown's avatar
unknown committed
798 799 800 801
};

class in_string :public in_vector
{
unknown's avatar
unknown committed
802
  char buff[STRING_BUFFER_USUAL_SIZE];
unknown's avatar
unknown committed
803 804
  String tmp;
public:
805
  in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs);
unknown's avatar
unknown committed
806 807 808
  ~in_string();
  void set(uint pos,Item *item);
  byte *get_value(Item *item);
809 810 811 812 813 814 815 816 817 818
  Item* create_item()
  { 
    return new Item_string(collation);
  }
  void value_to_item(uint pos, Item *item)
  {    
    String *str=((String*) base)+pos;
    Item_string *to= (Item_string*)item;
    to->str_value= *str;
  }
unknown's avatar
unknown committed
819 820 821 822 823 824 825 826 827
};

class in_longlong :public in_vector
{
  longlong tmp;
public:
  in_longlong(uint elements);
  void set(uint pos,Item *item);
  byte *get_value(Item *item);
828 829 830 831 832 833 834
  
  Item* create_item()
  { 
    /* 
      We're created a signed INT, this may not be correct in 
      general case (see BUG#19342).
    */
unknown's avatar
unknown committed
835
    return new Item_int((longlong)0);
836 837 838 839 840
  }
  void value_to_item(uint pos, Item *item)
  {
    ((Item_int*)item)->value= ((longlong*)base)[pos];
  }
unknown's avatar
unknown committed
841 842 843 844 845 846 847 848 849
};

class in_double :public in_vector
{
  double tmp;
public:
  in_double(uint elements);
  void set(uint pos,Item *item);
  byte *get_value(Item *item);
850 851 852 853 854 855 856 857 858
  Item *create_item()
  { 
    return new Item_float(0.0);
  }
  void value_to_item(uint pos, Item *item)
  {
    ((Item_float*)item)->value= ((double*) base)[pos];
  }

unknown's avatar
unknown committed
859 860
};

unknown's avatar
unknown committed
861 862 863 864 865 866 867
class in_decimal :public in_vector
{
  my_decimal val;
public:
  in_decimal(uint elements);
  void set(uint pos, Item *item);
  byte *get_value(Item *item);
868 869 870 871 872 873 874 875 876 877
  Item *create_item()
  { 
    return new Item_decimal(0, FALSE);
  }
  void value_to_item(uint pos, Item *item)
  {
    my_decimal *dec= ((my_decimal *)base) + pos;
    Item_decimal *item_dec= (Item_decimal*)item;
    item_dec->set_decimal_value(dec);
  }
unknown's avatar
unknown committed
878 879 880
};


unknown's avatar
unknown committed
881 882 883 884 885 886 887
/*
** Classes for easy comparing of non const items
*/

class cmp_item :public Sql_alloc
{
public:
888 889
  CHARSET_INFO *cmp_charset;
  cmp_item() { cmp_charset= &my_charset_bin; }
unknown's avatar
unknown committed
890
  virtual ~cmp_item() {}
unknown's avatar
unknown committed
891 892 893 894
  virtual void store_value(Item *item)= 0;
  virtual int cmp(Item *item)= 0;
  // for optimized IN with row
  virtual int compare(cmp_item *item)= 0;
unknown's avatar
unknown committed
895
  static cmp_item* get_comparator(Item_result type, CHARSET_INFO *cs);
unknown's avatar
unknown committed
896 897 898 899 900
  virtual cmp_item *make_same()= 0;
  virtual void store_value_by_template(cmp_item *tmpl, Item *item)
  {
    store_value(item);
  }
unknown's avatar
unknown committed
901 902
};

unknown's avatar
unknown committed
903 904 905 906 907
class cmp_item_string :public cmp_item 
{
protected:
  String *value_res;
public:
908
  cmp_item_string (CHARSET_INFO *cs) { cmp_charset= cs; }
unknown's avatar
unknown committed
909 910 911
  friend class cmp_item_sort_string;
  friend class cmp_item_sort_string_in_static;
};
unknown's avatar
unknown committed
912

unknown's avatar
unknown committed
913 914 915
class cmp_item_sort_string :public cmp_item_string
{
protected:
unknown's avatar
unknown committed
916
  char value_buff[STRING_BUFFER_USUAL_SIZE];
unknown's avatar
unknown committed
917
  String value;
unknown's avatar
unknown committed
918
public:
919 920 921
  cmp_item_sort_string(CHARSET_INFO *cs):
    cmp_item_string(cs),
    value(value_buff, sizeof(value_buff), cs) {}
unknown's avatar
unknown committed
922
  void store_value(Item *item)
unknown's avatar
unknown committed
923 924 925
  {
    value_res= item->val_str(&value);
  }
unknown's avatar
unknown committed
926
  int cmp(Item *arg)
unknown's avatar
unknown committed
927
  {
unknown's avatar
unknown committed
928
    char buff[STRING_BUFFER_USUAL_SIZE];
unknown's avatar
unknown committed
929
    String tmp(buff, sizeof(buff), cmp_charset), *res;
930 931 932
    res= arg->val_str(&tmp);
    return (value_res ? (res ? sortcmp(value_res, res, cmp_charset) : 1) :
            (res ? -1 : 0));
unknown's avatar
unknown committed
933 934 935 936
  }
  int compare(cmp_item *c)
  {
    cmp_item_string *cmp= (cmp_item_string *)c;
937
    return sortcmp(value_res, cmp->value_res, cmp_charset);
unknown's avatar
unknown committed
938 939
  } 
  cmp_item *make_same();
unknown's avatar
unknown committed
940 941 942 943 944 945
};

class cmp_item_int :public cmp_item
{
  longlong value;
public:
946
  cmp_item_int() {}                           /* Remove gcc warning */
unknown's avatar
unknown committed
947
  void store_value(Item *item)
unknown's avatar
unknown committed
948 949 950
  {
    value= item->val_int();
  }
unknown's avatar
unknown committed
951
  int cmp(Item *arg)
unknown's avatar
unknown committed
952 953 954 955 956 957 958 959 960
  {
    return value != arg->val_int();
  }
  int compare(cmp_item *c)
  {
    cmp_item_int *cmp= (cmp_item_int *)c;
    return (value < cmp->value) ? -1 : ((value == cmp->value) ? 0 : 1);
  }
  cmp_item *make_same();
unknown's avatar
unknown committed
961 962 963 964 965 966
};

class cmp_item_real :public cmp_item
{
  double value;
public:
967
  cmp_item_real() {}                          /* Remove gcc warning */
unknown's avatar
unknown committed
968
  void store_value(Item *item)
unknown's avatar
unknown committed
969
  {
970
    value= item->val_real();
unknown's avatar
unknown committed
971
  }
unknown's avatar
unknown committed
972
  int cmp(Item *arg)
unknown's avatar
unknown committed
973
  {
974
    return value != arg->val_real();
unknown's avatar
unknown committed
975 976 977 978 979 980 981
  }
  int compare(cmp_item *c)
  {
    cmp_item_real *cmp= (cmp_item_real *)c;
    return (value < cmp->value)? -1 : ((value == cmp->value) ? 0 : 1);
  }
  cmp_item *make_same();
unknown's avatar
unknown committed
982 983
};

unknown's avatar
unknown committed
984 985 986 987 988

class cmp_item_decimal :public cmp_item
{
  my_decimal value;
public:
989
  cmp_item_decimal() {}                       /* Remove gcc warning */
unknown's avatar
unknown committed
990 991 992 993 994 995 996
  void store_value(Item *item);
  int cmp(Item *arg);
  int compare(cmp_item *c);
  cmp_item *make_same();
};


997 998 999 1000 1001
class cmp_item_row :public cmp_item
{
  cmp_item **comparators;
  uint n;
public:
unknown's avatar
unknown committed
1002
  cmp_item_row(): comparators(0), n(0) {}
1003
  ~cmp_item_row();
1004 1005
  void store_value(Item *item);
  int cmp(Item *arg);
unknown's avatar
unknown committed
1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016
  int compare(cmp_item *arg);
  cmp_item *make_same();
  void store_value_by_template(cmp_item *tmpl, Item *);
};


class in_row :public in_vector
{
  cmp_item_row tmp;
public:
  in_row(uint elements, Item *);
1017
  ~in_row();
unknown's avatar
unknown committed
1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031
  void set(uint pos,Item *item);
  byte *get_value(Item *item);
};

/* 
   cmp_item for optimized IN with row (right part string, which never
   be changed)
*/

class cmp_item_sort_string_in_static :public cmp_item_string
{
 protected:
  String value;
public:
1032 1033
  cmp_item_sort_string_in_static(CHARSET_INFO *cs):
    cmp_item_string(cs) {}
unknown's avatar
unknown committed
1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046
  void store_value(Item *item)
  {
    value_res= item->val_str(&value);
  }
  int cmp(Item *item)
  {
    // Should never be called
    DBUG_ASSERT(0);
    return 1;
  }
  int compare(cmp_item *c)
  {
    cmp_item_string *cmp= (cmp_item_string *)c;
1047
    return sortcmp(value_res, cmp->value_res, cmp_charset);
unknown's avatar
unknown committed
1048
  }
1049
  cmp_item *make_same()
unknown's avatar
unknown committed
1050
  {
1051
    return new cmp_item_sort_string_in_static(cmp_charset);
unknown's avatar
unknown committed
1052
  }
1053
};
unknown's avatar
unknown committed
1054

unknown's avatar
unknown committed
1055
class Item_func_in :public Item_func_opt_neg
unknown's avatar
unknown committed
1056
{
1057
public:
1058
  Item_result cmp_type;
1059 1060 1061 1062
  /* 
    an array of values when the right hand arguments of IN
    are all SQL constant and there are no nulls 
  */
unknown's avatar
unknown committed
1063 1064
  in_vector *array;
  cmp_item *in_item;
1065
  bool have_null;
1066
  DTCollation cmp_collation;
1067

1068
  Item_func_in(List<Item> &list)
unknown's avatar
unknown committed
1069
    :Item_func_opt_neg(list), array(0), in_item(0), have_null(0)
1070
  {
1071
    allowed_arg_cols= 0;  // Fetch this value from first argument
1072
  }
unknown's avatar
unknown committed
1073
  longlong val_int();
1074
  bool fix_fields(THD *, Item **);
unknown's avatar
unknown committed
1075
  void fix_length_and_dec();
unknown's avatar
unknown committed
1076
  uint decimal_precision() const { return 1; }
1077 1078
  void cleanup()
  {
unknown's avatar
unknown committed
1079
    DBUG_ENTER("Item_func_in::cleanup");
1080
    Item_int_func::cleanup();
1081 1082 1083 1084
    delete array;
    delete in_item;
    array= 0;
    in_item= 0;
unknown's avatar
unknown committed
1085
    DBUG_VOID_RETURN;
1086
  }
unknown's avatar
unknown committed
1087
  optimize_type select_optimize() const
1088
    { return OPTIMIZE_KEY; }
unknown's avatar
unknown committed
1089 1090 1091
  void print(String *str);
  enum Functype functype() const { return IN_FUNC; }
  const char *func_name() const { return " IN "; }
unknown's avatar
unknown committed
1092
  bool nulls_in_row();
unknown's avatar
unknown committed
1093
  bool is_bool_func() { return 1; }
1094
  CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
unknown's avatar
unknown committed
1095 1096 1097 1098 1099 1100
};

/* Functions used by where clause */

class Item_func_isnull :public Item_bool_func
{
1101
protected:
unknown's avatar
unknown committed
1102
  longlong cached_value;
unknown's avatar
unknown committed
1103 1104 1105 1106 1107 1108 1109
public:
  Item_func_isnull(Item *a) :Item_bool_func(a) {}
  longlong val_int();
  enum Functype functype() const { return ISNULL_FUNC; }
  void fix_length_and_dec()
  {
    decimals=0; max_length=1; maybe_null=0;
1110
    update_used_tables();
unknown's avatar
unknown committed
1111 1112 1113
  }
  const char *func_name() const { return "isnull"; }
  /* Optimize case of not_null_column IS NULL */
1114
  virtual void update_used_tables()
unknown's avatar
unknown committed
1115 1116 1117
  {
    if (!args[0]->maybe_null)
    {
1118
      used_tables_cache= 0;			/* is always false */
1119
      const_item_cache= 1;
1120
      cached_value= (longlong) 0;
unknown's avatar
unknown committed
1121
    }
1122
    else
unknown's avatar
unknown committed
1123
    {
1124
      args[0]->update_used_tables();
unknown's avatar
unknown committed
1125 1126
      if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())) &&
          !with_subselect)
1127 1128
      {
	/* Remember if the value is always NULL or never NULL */
1129
	cached_value= (longlong) args[0]->is_null();
1130
      }
unknown's avatar
unknown committed
1131
    }
unknown's avatar
unknown committed
1132
  }
1133
  table_map not_null_tables() const { return 0; }
unknown's avatar
unknown committed
1134
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1135
  Item *neg_transformer(THD *thd);
1136
  CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
unknown's avatar
unknown committed
1137 1138
};

1139 1140 1141
/* Functions used by HAVING for rewriting IN subquery */

class Item_in_subselect;
1142 1143 1144 1145 1146

/* 
  This is like IS NOT NULL but it also remembers if it ever has
  encountered a NULL.
*/
1147 1148 1149 1150 1151 1152 1153
class Item_is_not_null_test :public Item_func_isnull
{
  Item_in_subselect* owner;
public:
  Item_is_not_null_test(Item_in_subselect* ow, Item *a)
    :Item_func_isnull(a), owner(ow)
  {}
1154
  enum Functype functype() const { return ISNOTNULLTEST_FUNC; }
1155
  longlong val_int();
1156
  const char *func_name() const { return "<is_not_null_test>"; }
1157
  void update_used_tables();
1158 1159 1160 1161 1162
  /*
    we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
  */
  table_map used_tables() const
    { return used_tables_cache | RAND_TABLE_BIT; }
1163 1164 1165
};


unknown's avatar
unknown committed
1166 1167
class Item_func_isnotnull :public Item_bool_func
{
1168
  bool abort_on_null;
unknown's avatar
unknown committed
1169
public:
1170
  Item_func_isnotnull(Item *a) :Item_bool_func(a), abort_on_null(0) {}
unknown's avatar
unknown committed
1171 1172
  longlong val_int();
  enum Functype functype() const { return ISNOTNULL_FUNC; }
unknown's avatar
unknown committed
1173 1174 1175 1176
  void fix_length_and_dec()
  {
    decimals=0; max_length=1; maybe_null=0;
  }
unknown's avatar
unknown committed
1177 1178
  const char *func_name() const { return "isnotnull"; }
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1179 1180
  table_map not_null_tables() const
  { return abort_on_null ? not_null_tables_cache : 0; }
1181
  Item *neg_transformer(THD *thd);
1182
  void print(String *str);
1183
  CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1184
  void top_level_item() { abort_on_null=1; }
unknown's avatar
unknown committed
1185 1186
};

1187

unknown's avatar
unknown committed
1188 1189
class Item_func_like :public Item_bool_func2
{
1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204
  // Turbo Boyer-Moore data
  bool        canDoTurboBM;	// pattern is '%abcd%' case
  const char* pattern;
  int         pattern_len;

  // TurboBM buffers, *this is owner
  int* bmGs; //   good suffix shift table, size is pattern_len + 1
  int* bmBc; // bad character shift table, size is alphabet_size

  void turboBM_compute_suffixes(int* suff);
  void turboBM_compute_good_suffix_shifts(int* suff);
  void turboBM_compute_bad_character_shifts();
  bool turboBM_matches(const char* text, int text_len) const;
  enum { alphabet_size = 256 };

1205
  Item *escape_item;
1206 1207
  
  bool escape_used_in_parsing;
1208

unknown's avatar
unknown committed
1209
public:
unknown's avatar
unknown committed
1210
  int escape;
1211

1212
  Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
unknown's avatar
unknown committed
1213
    :Item_bool_func2(a,b), canDoTurboBM(FALSE), pattern(0), pattern_len(0), 
1214 1215
     bmGs(0), bmBc(0), escape_item(escape_arg),
     escape_used_in_parsing(escape_used) {}
unknown's avatar
unknown committed
1216 1217 1218 1219 1220
  longlong val_int();
  enum Functype functype() const { return LIKE_FUNC; }
  optimize_type select_optimize() const;
  cond_result eq_cmp_result() const { return COND_TRUE; }
  const char *func_name() const { return "like"; }
1221
  bool fix_fields(THD *thd, Item **ref);
1222
  void cleanup();
unknown's avatar
unknown committed
1223 1224 1225 1226
};

#ifdef USE_REGEX

unknown's avatar
unknown committed
1227
#include "my_regex.h"
unknown's avatar
unknown committed
1228 1229 1230

class Item_func_regex :public Item_bool_func
{
unknown's avatar
unknown committed
1231
  my_regex_t preg;
unknown's avatar
unknown committed
1232 1233 1234
  bool regex_compiled;
  bool regex_is_const;
  String prev_regexp;
1235
  DTCollation cmp_collation;
unknown's avatar
unknown committed
1236 1237 1238
public:
  Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b),
    regex_compiled(0),regex_is_const(0) {}
1239
  void cleanup();
unknown's avatar
unknown committed
1240
  longlong val_int();
1241
  bool fix_fields(THD *thd, Item **ref);
1242
  const char *func_name() const { return "regexp"; }
1243
  void print(String *str) { print_op(str); }
1244
  CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
unknown's avatar
unknown committed
1245 1246 1247 1248 1249 1250 1251 1252 1253 1254
};

#else

class Item_func_regex :public Item_bool_func
{
public:
  Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b) {}
  longlong val_int() { return 0;}
  const char *func_name() const { return "regex"; }
1255
  void print(String *str) { print_op(str); }
unknown's avatar
unknown committed
1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266
};

#endif /* USE_REGEX */


typedef class Item COND;

class Item_cond :public Item_bool_func
{
protected:
  List<Item> list;
1267
  bool abort_on_null;
1268 1269
  table_map and_tables_cache;

unknown's avatar
unknown committed
1270
public:
1271
  /* Item_cond() is only used to create top level items */
1272 1273
  Item_cond(): Item_bool_func(), abort_on_null(1)
  { const_item_cache=0; }
1274
  Item_cond(Item *i1,Item *i2)
1275 1276 1277 1278 1279
    :Item_bool_func(), abort_on_null(0)
  {
    list.push_back(i1);
    list.push_back(i2);
  }
1280
  Item_cond(THD *thd, Item_cond *item);
1281 1282
  Item_cond(List<Item> &nlist)
    :Item_bool_func(), list(nlist), abort_on_null(0) {}
unknown's avatar
unknown committed
1283
  bool add(Item *item) { return list.push_back(item); }
unknown's avatar
unknown committed
1284
  void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
1285
  bool fix_fields(THD *, Item **ref);
unknown's avatar
unknown committed
1286 1287 1288 1289 1290 1291

  enum Type type() const { return COND_ITEM; }
  List<Item>* argument_list() { return &list; }
  table_map used_tables() const;
  void update_used_tables();
  void print(String *str);
1292
  void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
1293
  friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
1294
                         COND **conds);
1295
  void top_level_item() { abort_on_null=1; }
1296
  void copy_andor_arguments(THD *thd, Item_cond *item);
unknown's avatar
unknown committed
1297
  bool walk(Item_processor processor, byte *arg);
unknown's avatar
unknown committed
1298
  Item *transform(Item_transformer transformer, byte *arg);
1299
  void traverse_cond(Cond_traverser, void *arg, traverse_order order);
1300
  void neg_arguments(THD *thd);
1301 1302 1303
  bool subst_argument_checker(byte **arg) { return TRUE; }
  Item *compile(Item_analyzer analyzer, byte **arg_p,
                Item_transformer transformer, byte *arg_t);
unknown's avatar
unknown committed
1304 1305 1306
};


unknown's avatar
unknown committed
1307
/*
unknown's avatar
unknown committed
1308
  The class Item_equal is used to represent conjunctions of equality
unknown's avatar
unknown committed
1309 1310
  predicates of the form field1 = field2, and field=const in where
  conditions and on expressions.
1311 1312

  All equality predicates of the form field1=field2 contained in a
unknown's avatar
unknown committed
1313 1314
  conjunction are substituted for a sequence of items of this class.
  An item of this class Item_equal(f1,f2,...fk) represents a
unknown's avatar
unknown committed
1315 1316
  multiple equality f1=f2=...=fk.

unknown's avatar
unknown committed
1317
  If a conjunction contains predicates f1=f2 and f2=f3, a new item of
unknown's avatar
unknown committed
1318 1319
  this class is created Item_equal(f1,f2,f3) representing the multiple
  equality f1=f2=f3 that substitutes the above equality predicates in
unknown's avatar
unknown committed
1320 1321
  the conjunction.
  A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
unknown's avatar
unknown committed
1322 1323
  substituted for the item representing the same multiple equality
  f1=f2=f3.
unknown's avatar
unknown committed
1324
  An item Item_equal(f1,f2) can appear instead of a conjunction of 
unknown's avatar
unknown committed
1325 1326
  f2=f1 and f1=f2, or instead of just the predicate f1=f2.

unknown's avatar
unknown committed
1327
  An item of the class Item_equal inherits equalities from outer 
unknown's avatar
unknown committed
1328 1329 1330 1331 1332 1333 1334 1335 1336 1337
  conjunctive levels.

  Suppose we have a where condition of the following form:
  WHERE f1=f2 AND f3=f4 AND f3=f5 AND ... AND (...OR (f1=f3 AND ...)).
  In this case:
    f1=f2 will be substituted for Item_equal(f1,f2);
    f3=f4 and f3=f5  will be substituted for Item_equal(f3,f4,f5);
    f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);

  An object of the class Item_equal can contain an optional constant
unknown's avatar
unknown committed
1338
  item c. Then it represents a multiple equality of the form 
unknown's avatar
unknown committed
1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355
  c=f1=...=fk.

  Objects of the class Item_equal are used for the following:

  1. An object Item_equal(t1.f1,...,tk.fk) allows us to consider any
  pair of tables ti and tj as joined by an equi-condition.
  Thus it provide us with additional access paths from table to table.

  2. An object Item_equal(t1.f1,...,tk.fk) is applied to deduce new
  SARGable predicates:
    f1=...=fk AND P(fi) => f1=...=fk AND P(fi) AND P(fj).
  It also can give us additional index scans and can allow us to
  improve selectivity estimates.

  3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the 
  selected execution plan for the query: if table ti is accessed 
  before the table tj then in any predicate P in the where condition
unknown's avatar
unknown committed
1356
  the occurrence of tj.fj is substituted for ti.fi. This can allow
unknown's avatar
unknown committed
1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368
  an evaluation of the predicate at an earlier step.

  When feature 1 is supported they say that join transitive closure 
  is employed.
  When feature 2 is supported they say that search argument transitive
  closure is employed.
  Both features are usually supported by preprocessing original query and
  adding additional predicates.
  We do not just add predicates, we rather dynamically replace some
  predicates that can not be used to access tables in the investigated
  plan for those, obtained by substitution of some fields for equal fields,
  that can be used.     
1369 1370 1371 1372 1373 1374

  Prepared Statements/Stored Procedures note: instances of class
  Item_equal are created only at the time a PS/SP is executed and
  are deleted in the end of execution. All changes made to these
  objects need not be registered in the list of changes of the parse
  tree and do not harm PS/SP re-execution.
1375 1376 1377 1378 1379

  Item equal objects are employed only at the optimize phase. Usually they are
  not supposed to be evaluated.  Yet in some cases we call the method val_int()
  for them. We have to take care of restricting the predicate such an
  object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.
unknown's avatar
unknown committed
1380 1381
*/

1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397
class Item_equal: public Item_bool_func
{
  List<Item_field> fields; /* list of equal field items                    */
  Item *const_item;        /* optional constant item equal to fields items */
  cmp_item *eval_item;
  bool cond_false;
public:
  inline Item_equal()
    : Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
  { const_item_cache=0 ;}
  Item_equal(Item_field *f1, Item_field *f2);
  Item_equal(Item *c, Item_field *f);
  Item_equal(Item_equal *item_equal);
  inline Item* get_const() { return const_item; }
  void add(Item *c);
  void add(Item_field *f);
unknown's avatar
unknown committed
1398
  uint members();
1399 1400 1401
  bool contains(Field *field);
  Item_field* get_first() { return fields.head(); }
  void merge(Item_equal *item);
1402
  void update_const();
1403 1404 1405 1406
  enum Functype functype() const { return MULT_EQUAL_FUNC; }
  longlong val_int(); 
  const char *func_name() const { return "multiple equal"; }
  optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
unknown's avatar
unknown committed
1407
  void sort(Item_field_cmpfunc cmp, void *arg);
1408 1409
  friend class Item_equal_iterator;
  void fix_length_and_dec();
1410
  bool fix_fields(THD *thd, Item **ref);
1411 1412
  void update_used_tables();
  bool walk(Item_processor processor, byte *arg);
unknown's avatar
unknown committed
1413
  Item *transform(Item_transformer transformer, byte *arg);
1414
  void print(String *str);
unknown's avatar
unknown committed
1415 1416
  CHARSET_INFO *compare_collation() 
  { return fields.head()->collation.collation; }
1417 1418
}; 

unknown's avatar
unknown committed
1419
class COND_EQUAL: public Sql_alloc
1420 1421
{
public:
unknown's avatar
unknown committed
1422 1423 1424 1425 1426 1427 1428 1429 1430 1431
  uint max_members;               /* max number of members the current level
                                     list and all lower level lists */ 
  COND_EQUAL *upper_levels;       /* multiple equalities of upper and levels */
  List<Item_equal> current_level; /* list of multiple equalities of 
                                     the current and level           */
  COND_EQUAL()
  { 
    max_members= 0;
    upper_levels= 0;
  }
1432 1433 1434
};


unknown's avatar
unknown committed
1435
class Item_equal_iterator : public List_iterator_fast<Item_field>
1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451
{
public:
  inline Item_equal_iterator(Item_equal &item_equal) 
    :List_iterator_fast<Item_field> (item_equal.fields)
  {}
  inline Item_field* operator++(int)
  { 
    Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
    return  item;
  }
  inline void rewind(void) 
  { 
    List_iterator_fast<Item_field>::rewind();
  }
};

unknown's avatar
unknown committed
1452 1453 1454
class Item_cond_and :public Item_cond
{
public:
unknown's avatar
unknown committed
1455 1456 1457
  COND_EQUAL cond_equal;  /* contains list of Item_equal objects for 
                             the current and level and reference
                             to multiple equalities of upper and levels */  
unknown's avatar
unknown committed
1458 1459
  Item_cond_and() :Item_cond() {}
  Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1460
  Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
1461
  Item_cond_and(List<Item> &list): Item_cond(list) {}
unknown's avatar
unknown committed
1462 1463 1464
  enum Functype functype() const { return COND_AND_FUNC; }
  longlong val_int();
  const char *func_name() const { return "and"; }
1465 1466
  table_map not_null_tables() const
  { return abort_on_null ? not_null_tables_cache: and_tables_cache; }
1467 1468 1469
  Item* copy_andor_structure(THD *thd)
  {
    Item_cond_and *item;
unknown's avatar
merge  
unknown committed
1470
    if ((item= new Item_cond_and(thd, this)))
1471 1472 1473
       item->copy_andor_arguments(thd, this);
    return item;
  }
1474
  Item *neg_transformer(THD *thd);
unknown's avatar
unknown committed
1475 1476 1477 1478 1479 1480 1481
};

class Item_cond_or :public Item_cond
{
public:
  Item_cond_or() :Item_cond() {}
  Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1482
  Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
1483
  Item_cond_or(List<Item> &list): Item_cond(list) {}
unknown's avatar
unknown committed
1484 1485 1486
  enum Functype functype() const { return COND_OR_FUNC; }
  longlong val_int();
  const char *func_name() const { return "or"; }
1487
  table_map not_null_tables() const { return and_tables_cache; }
1488 1489 1490
  Item* copy_andor_structure(THD *thd)
  {
    Item_cond_or *item;
unknown's avatar
merge  
unknown committed
1491
    if ((item= new Item_cond_or(thd, this)))
1492 1493 1494
      item->copy_andor_arguments(thd, this);
    return item;
  }
1495
  Item *neg_transformer(THD *thd);
unknown's avatar
unknown committed
1496 1497 1498
};


1499
/*
unknown's avatar
unknown committed
1500
  XOR is Item_cond, not an Item_int_func because we could like to
1501 1502
  optimize (a XOR b) later on. It's low prio, though
*/
unknown's avatar
unknown committed
1503

unknown's avatar
unknown committed
1504 1505 1506 1507 1508 1509
class Item_cond_xor :public Item_cond
{
public:
  Item_cond_xor() :Item_cond() {}
  Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2) {}
  enum Functype functype() const { return COND_XOR_FUNC; }
1510 1511
  /* TODO: remove the next line when implementing XOR optimization */
  enum Type type() const { return FUNC_ITEM; }
unknown's avatar
unknown committed
1512 1513
  longlong val_int();
  const char *func_name() const { return "xor"; }
1514
  void top_level_item() {}
unknown's avatar
unknown committed
1515 1516 1517
};


unknown's avatar
unknown committed
1518
/* Some useful inline functions */
unknown's avatar
unknown committed
1519

unknown's avatar
unknown committed
1520
inline Item *and_conds(Item *a, Item *b)
unknown's avatar
unknown committed
1521 1522 1523
{
  if (!b) return a;
  if (!a) return b;
unknown's avatar
unknown committed
1524
  return new Item_cond_and(a, b);
unknown's avatar
unknown committed
1525
}
unknown's avatar
unknown committed
1526

unknown's avatar
unknown committed
1527
Item *and_expressions(Item *a, Item *b, Item **org_item);