~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/item_cmpfunc.h

  • Committer: Stewart Smith
  • Date: 2008-07-13 06:56:15 UTC
  • mto: (210.1.1 drizzle)
  • mto: This revision was merged to the branch mainline in revision 211.
  • Revision ID: stewart@flamingspork.com-20080713065615-vzok75kgnnviokl9
Move MD5() into a UDF

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; version 2 of the License.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
 */
19
 
 
20
 
#ifndef DRIZZLED_ITEM_CMPFUNC_H
21
 
#define DRIZZLED_ITEM_CMPFUNC_H
 
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
 
22
16
 
23
17
/* compare and test functions */
24
18
 
25
 
#include "drizzled/comp_creator.h"
26
 
#include "drizzled/item/row.h"
27
 
#include "drizzled/item/sum.h"
28
 
#include "drizzled/item/int.h"
29
 
#include "drizzled/item/float.h"
30
 
#include "drizzled/item/decimal.h"
31
 
#include "drizzled/function/math/int.h"
32
 
#include "drizzled/function/numhybrid.h"
33
 
#include "drizzled/session.h"
34
 
#include "drizzled/common.h"
35
 
#include "drizzled/qsort_cmp.h"
36
 
 
37
 
namespace drizzled
38
 
{
 
19
#ifdef USE_PRAGMA_INTERFACE
 
20
#pragma interface                       /* gcc class implementation */
 
21
#endif
39
22
 
40
23
extern Item_result item_cmp_type(Item_result a,Item_result b);
41
24
class Item_bool_func2;
42
25
class Arg_comparator;
43
 
class Item_sum_hybrid;
44
 
class Item_row;
45
26
 
46
27
typedef int (Arg_comparator::*arg_cmp_func)();
47
28
 
48
 
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
49
 
 
50
 
uint64_t get_datetime_value(Session *session, 
51
 
                            Item ***item_arg, 
52
 
                            Item **cache_arg,
53
 
                            Item *warn_item, 
54
 
                            bool *is_null);
55
 
 
56
 
class Arg_comparator: public memory::SqlAlloc
 
29
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg); 
 
30
 
 
31
class Arg_comparator: public Sql_alloc
57
32
{
58
33
  Item **a, **b;
59
34
  arg_cmp_func func;
61
36
  Arg_comparator *comparators;   // used only for compare_row()
62
37
  double precision;
63
38
  /* Fields used in DATE/DATETIME comparison. */
64
 
  Session *session;
 
39
  THD *thd;
65
40
  enum_field_types a_type, b_type; // Types of a and b items
66
41
  Item *a_cache, *b_cache;         // Cached values of a and b items
67
42
  bool is_nulls_eq;                // TRUE <=> compare for the EQUAL_FUNC
68
43
  enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
69
44
                            CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
70
 
  uint64_t (*get_value_func)(Session *session, Item ***item_arg, Item **cache_arg,
 
45
  ulonglong (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg,
71
46
                              Item *warn_item, bool *is_null);
72
47
public:
73
48
  DTCollation cmp_collation;
74
49
 
75
 
  Arg_comparator(): session(0), a_cache(0), b_cache(0) {};
76
 
  Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), session(0),
 
50
  Arg_comparator(): thd(0), a_cache(0), b_cache(0) {};
 
51
  Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), thd(0),
77
52
    a_cache(0), b_cache(0) {};
78
53
 
79
54
  int set_compare_func(Item_bool_func2 *owner, Item_result type);
116
91
  int compare_datetime();        // compare args[0] & args[1] as DATETIMEs
117
92
 
118
93
  static enum enum_date_cmp_type can_compare_as_dates(Item *a, Item *b,
119
 
                                                      uint64_t *const_val_arg);
 
94
                                                      ulonglong *const_val_arg);
120
95
 
121
96
  void set_datetime_cmp_func(Item **a1, Item **b1);
122
97
  static arg_cmp_func comparator_matrix [5][2];
130
105
  Item_bool_func() :Item_int_func() {}
131
106
  Item_bool_func(Item *a) :Item_int_func(a) {}
132
107
  Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
133
 
  Item_bool_func(Session *session, Item_bool_func *item) :Item_int_func(session, item) {}
 
108
  Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {}
134
109
  bool is_bool_func() { return 1; }
135
110
  void fix_length_and_dec() { decimals=0; max_length=1; }
136
 
  uint32_t decimal_precision() const { return 1; }
 
111
  uint decimal_precision() const { return 1; }
137
112
};
138
113
 
139
114
 
146
121
{
147
122
public:
148
123
  virtual bool val_bool();
149
 
  virtual int64_t val_int();
 
124
  virtual longlong val_int();
150
125
  virtual void fix_length_and_dec();
151
126
  virtual void print(String *str, enum_query_type query_type);
152
127
 
223
198
 
224
199
 
225
200
class Item_cache;
226
 
#define UNKNOWN ((bool)-1)
 
201
#define UNKNOWN ((my_bool)-1)
227
202
 
228
203
 
229
204
/*
246
221
protected:
247
222
  Item_cache *cache;
248
223
  bool save_cache;
249
 
  /*
 
224
  /* 
250
225
    Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
251
226
      UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
252
227
      FALSE   - result is FALSE
253
228
      TRUE    - result is NULL
254
229
  */
255
 
  bool result_for_null_param;
 
230
  my_bool result_for_null_param;
256
231
public:
257
232
  Item_in_optimizer(Item *a, Item_in_subselect *b):
258
 
    Item_bool_func(a, reinterpret_cast<Item *>(b)), cache(0),
 
233
    Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0),
259
234
    save_cache(0), result_for_null_param(UNKNOWN)
260
235
  { with_subselect= true; }
261
 
  bool fix_fields(Session *, Item **);
262
 
  bool fix_left(Session *session, Item **ref);
 
236
  bool fix_fields(THD *, Item **);
 
237
  bool fix_left(THD *thd, Item **ref);
263
238
  bool is_null();
264
 
  int64_t val_int();
 
239
  longlong val_int();
265
240
  void cleanup();
266
241
  const char *func_name() const { return "<in_optimizer>"; }
267
242
  Item_cache **get_cache() { return &cache; }
268
243
  void keep_top_level_cache();
269
 
  Item *transform(Item_transformer transformer, unsigned char *arg);
 
244
  Item *transform(Item_transformer transformer, uchar *arg);
 
245
};
 
246
 
 
247
class Comp_creator
 
248
{
 
249
public:
 
250
  Comp_creator() {}                           /* Remove gcc warning */
 
251
  virtual ~Comp_creator() {}                  /* Remove gcc warning */
 
252
  virtual Item_bool_func2* create(Item *a, Item *b) const = 0;
 
253
  virtual const char* symbol(bool invert) const = 0;
 
254
  virtual bool eqne_op() const = 0;
 
255
  virtual bool l_op() const = 0;
270
256
};
271
257
 
272
258
class Eq_creator :public Comp_creator
278
264
  virtual const char* symbol(bool invert) const { return invert? "<>" : "="; }
279
265
  virtual bool eqne_op() const { return 1; }
280
266
  virtual bool l_op() const { return 0; }
281
 
  static const Eq_creator *instance();
282
267
};
283
268
 
284
269
class Ne_creator :public Comp_creator
290
275
  virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; }
291
276
  virtual bool eqne_op() const { return 1; }
292
277
  virtual bool l_op() const { return 0; }
293
 
  static const Ne_creator *instance();
294
278
};
295
279
 
296
280
class Gt_creator :public Comp_creator
302
286
  virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
303
287
  virtual bool eqne_op() const { return 0; }
304
288
  virtual bool l_op() const { return 0; }
305
 
  static const Gt_creator *instance();
306
289
};
307
290
 
308
291
class Lt_creator :public Comp_creator
314
297
  virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
315
298
  virtual bool eqne_op() const { return 0; }
316
299
  virtual bool l_op() const { return 1; }
317
 
  static const Lt_creator *instance();
318
300
};
319
301
 
320
302
class Ge_creator :public Comp_creator
326
308
  virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
327
309
  virtual bool eqne_op() const { return 0; }
328
310
  virtual bool l_op() const { return 0; }
329
 
  static const Ge_creator *instance();
330
311
};
331
312
 
332
313
class Le_creator :public Comp_creator
338
319
  virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
339
320
  virtual bool eqne_op() const { return 0; }
340
321
  virtual bool l_op() const { return 1; }
341
 
  static const Le_creator *instance();
342
322
};
343
323
 
344
324
class Item_bool_func2 :public Item_int_func
367
347
 
368
348
  bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
369
349
  bool is_bool_func() { return 1; }
370
 
  const CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
371
 
  uint32_t decimal_precision() const { return 1; }
 
350
  CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
 
351
  uint decimal_precision() const { return 1; }
372
352
  void top_level_item() { abort_on_null= true; }
373
353
 
374
354
  friend class  Arg_comparator;
381
361
  {
382
362
    allowed_arg_cols= 0;  // Fetch this value from first argument
383
363
  }
384
 
  Item *neg_transformer(Session *session);
 
364
  Item *neg_transformer(THD *thd);
385
365
  virtual Item *negated_item();
386
 
  bool subst_argument_checker(unsigned char **)
 
366
  bool subst_argument_checker(uchar **arg __attribute__((__unused__)))
387
367
  { return true; }
388
368
};
389
369
 
391
371
{
392
372
public:
393
373
  Item_func_not(Item *a) :Item_bool_func(a) {}
394
 
  int64_t val_int();
 
374
  longlong val_int();
395
375
  enum Functype functype() const { return NOT_FUNC; }
396
376
  const char *func_name() const { return "not"; }
397
 
  Item *neg_transformer(Session *session);
 
377
  Item *neg_transformer(THD *thd);
398
378
  virtual void print(String *str, enum_query_type query_type);
399
379
};
400
380
 
403
383
/*
404
384
  trigcond<param>(arg) ::= param? arg : TRUE
405
385
 
406
 
  The class Item_func_trig_cond is used for guarded predicates
 
386
  The class Item_func_trig_cond is used for guarded predicates 
407
387
  which are employed only for internal purposes.
408
388
  A guarded predicate is an object consisting of an a regular or
409
 
  a guarded predicate P and a pointer to a boolean guard variable g.
 
389
  a guarded predicate P and a pointer to a boolean guard variable g. 
410
390
  A guarded predicate P/g is evaluated to true if the value of the
411
391
  guard g is false, otherwise it is evaluated to the same value that
412
392
  the predicate P: val(P/g)= g ? val(P):true.
418
398
  the objects consisting of three elements: a predicate P, a pointer
419
399
  to a variable g and a firing value s with following evaluation
420
400
  rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
421
 
  one item for the objects of the form P/g1/g2...
 
401
  one item for the objects of the form P/g1/g2... 
422
402
 
423
403
  Objects of this class are built only for query execution after
424
404
  the execution plan has been already selected. That's why this
425
 
  class needs only val_int out of generic methods.
426
 
 
 
405
  class needs only val_int out of generic methods. 
 
406
 
427
407
  Current uses of Item_func_trig_cond objects:
428
408
   - To wrap selection conditions when executing outer joins
429
409
   - To wrap condition that is pushed down into subquery
434
414
  bool *trig_var;
435
415
public:
436
416
  Item_func_trig_cond(Item *a, bool *f) : Item_bool_func(a) { trig_var= f; }
437
 
  int64_t val_int() { return *trig_var ? args[0]->val_int() : 1; }
 
417
  longlong val_int() { return *trig_var ? args[0]->val_int() : 1; }
438
418
  enum Functype functype() const { return TRIG_COND_FUNC; };
439
419
  const char *func_name() const { return "trigcond"; };
440
420
  bool const_item() const { return false; }
459
439
    {}
460
440
  virtual void top_level_item() { abort_on_null= 1; }
461
441
  bool top_level() { return abort_on_null; }
462
 
  int64_t val_int();
 
442
  longlong val_int();
463
443
  enum Functype functype() const { return NOT_ALL_FUNC; }
464
444
  const char *func_name() const { return "<not>"; }
465
445
  virtual void print(String *str, enum_query_type query_type);
466
446
  void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
467
447
  void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
468
448
  bool empty_underlying_subquery();
469
 
  Item *neg_transformer(Session *session);
 
449
  Item *neg_transformer(THD *thd);
470
450
};
471
451
 
472
452
 
475
455
public:
476
456
 
477
457
  Item_func_nop_all(Item *a) :Item_func_not_all(a) {}
478
 
  int64_t val_int();
 
458
  longlong val_int();
479
459
  const char *func_name() const { return "<nop>"; }
480
 
  Item *neg_transformer(Session *session);
 
460
  Item *neg_transformer(THD *thd);
481
461
};
482
462
 
483
463
 
485
465
{
486
466
public:
487
467
  Item_func_eq(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
488
 
  int64_t val_int();
 
468
  longlong val_int();
489
469
  enum Functype functype() const { return EQ_FUNC; }
490
470
  enum Functype rev_functype() const { return EQ_FUNC; }
491
471
  cond_result eq_cmp_result() const { return COND_TRUE; }
497
477
{
498
478
public:
499
479
  Item_func_equal(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
500
 
  int64_t val_int();
 
480
  longlong val_int();
501
481
  void fix_length_and_dec();
502
482
  table_map not_null_tables() const { return 0; }
503
483
  enum Functype functype() const { return EQUAL_FUNC; }
504
484
  enum Functype rev_functype() const { return EQUAL_FUNC; }
505
485
  cond_result eq_cmp_result() const { return COND_TRUE; }
506
486
  const char *func_name() const { return "<=>"; }
507
 
  Item *neg_transformer(Session *) { return 0; }
 
487
  Item *neg_transformer(THD *thd __attribute__((__unused__))) { return 0; }
508
488
};
509
489
 
510
490
 
512
492
{
513
493
public:
514
494
  Item_func_ge(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
515
 
  int64_t val_int();
 
495
  longlong val_int();
516
496
  enum Functype functype() const { return GE_FUNC; }
517
497
  enum Functype rev_functype() const { return LE_FUNC; }
518
498
  cond_result eq_cmp_result() const { return COND_TRUE; }
525
505
{
526
506
public:
527
507
  Item_func_gt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
528
 
  int64_t val_int();
 
508
  longlong val_int();
529
509
  enum Functype functype() const { return GT_FUNC; }
530
510
  enum Functype rev_functype() const { return LT_FUNC; }
531
511
  cond_result eq_cmp_result() const { return COND_FALSE; }
538
518
{
539
519
public:
540
520
  Item_func_le(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
541
 
  int64_t val_int();
 
521
  longlong val_int();
542
522
  enum Functype functype() const { return LE_FUNC; }
543
523
  enum Functype rev_functype() const { return GE_FUNC; }
544
524
  cond_result eq_cmp_result() const { return COND_TRUE; }
551
531
{
552
532
public:
553
533
  Item_func_lt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
554
 
  int64_t val_int();
 
534
  longlong val_int();
555
535
  enum Functype functype() const { return LT_FUNC; }
556
536
  enum Functype rev_functype() const { return GT_FUNC; }
557
537
  cond_result eq_cmp_result() const { return COND_FALSE; }
564
544
{
565
545
public:
566
546
  Item_func_ne(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
567
 
  int64_t val_int();
 
547
  longlong val_int();
568
548
  enum Functype functype() const { return NE_FUNC; }
569
549
  cond_result eq_cmp_result() const { return COND_FALSE; }
570
 
  optimize_type select_optimize() const { return OPTIMIZE_KEY; }
 
550
  optimize_type select_optimize() const { return OPTIMIZE_KEY; } 
571
551
  const char *func_name() const { return "<>"; }
572
552
  Item *negated_item();
573
553
};
595
575
public:
596
576
  inline void negate() { negated= !negated; }
597
577
  inline void top_level_item() { pred_level= 1; }
598
 
  Item *neg_transformer(Session *)
 
578
  Item *neg_transformer(THD *thd __attribute__((__unused__)))
599
579
  {
600
580
    negated= !negated;
601
581
    return this;
602
582
  }
603
583
  bool eq(const Item *item, bool binary_cmp) const;
604
 
  bool subst_argument_checker(unsigned char **)
 
584
  bool subst_argument_checker(uchar **arg __attribute__((__unused__)))
605
585
  { return true; }
606
586
};
607
587
 
618
598
  Arg_comparator ge_cmp, le_cmp;
619
599
  Item_func_between(Item *a, Item *b, Item *c)
620
600
    :Item_func_opt_neg(a, b, c), compare_as_dates(false) {}
621
 
  int64_t val_int();
 
601
  longlong val_int();
622
602
  optimize_type select_optimize() const { return OPTIMIZE_KEY; }
623
603
  enum Functype functype() const   { return BETWEEN; }
624
604
  const char *func_name() const { return "between"; }
625
 
  bool fix_fields(Session *, Item **);
 
605
  bool fix_fields(THD *, Item **);
626
606
  void fix_length_and_dec();
627
607
  virtual void print(String *str, enum_query_type query_type);
628
608
  bool is_bool_func() { return 1; }
629
 
  const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
630
 
  uint32_t decimal_precision() const { return 1; }
 
609
  CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
 
610
  uint decimal_precision() const { return 1; }
631
611
};
632
612
 
633
613
 
635
615
{
636
616
public:
637
617
  Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {}
638
 
  int64_t val_int();
 
618
  longlong val_int();
639
619
  optimize_type select_optimize() const { return OPTIMIZE_NONE; }
640
620
  const char *func_name() const { return "strcmp"; }
641
621
 
656
636
class Item_func_interval :public Item_int_func
657
637
{
658
638
  Item_row *row;
659
 
  bool use_decimal_comparison;
 
639
  my_bool use_decimal_comparison;
660
640
  interval_range *intervals;
661
641
public:
662
642
  Item_func_interval(Item_row *a)
664
644
  {
665
645
    allowed_arg_cols= 0;    // Fetch this value from first argument
666
646
  }
667
 
  int64_t val_int();
 
647
  longlong val_int();
668
648
  void fix_length_and_dec();
669
649
  const char *func_name() const { return "interval"; }
670
 
  uint32_t decimal_precision() const { return 2; }
 
650
  uint decimal_precision() const { return 2; }
671
651
};
672
652
 
673
653
 
679
659
public:
680
660
  Item_func_coalesce(List<Item> &list) :Item_func_numhybrid(list) {}
681
661
  double real_op();
682
 
  int64_t int_op();
 
662
  longlong int_op();
683
663
  String *str_op(String *);
684
664
  my_decimal *decimal_op(my_decimal *);
685
665
  void fix_length_and_dec();
698
678
public:
699
679
  Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
700
680
  double real_op();
701
 
  int64_t int_op();
 
681
  longlong int_op();
702
682
  String *str_op(String *str);
703
683
  my_decimal *decimal_op(my_decimal *);
704
684
  enum_field_types field_type() const;
705
685
  void fix_length_and_dec();
706
686
  const char *func_name() const { return "ifnull"; }
707
 
  Field *tmp_table_field()
708
 
  {
709
 
    return Item_func::tmp_table_field();
710
 
  }
711
 
  Field *tmp_table_field(Table *table);
712
 
  uint32_t decimal_precision() const;
 
687
  Field *tmp_table_field(TABLE *table);
 
688
  uint decimal_precision() const;
713
689
};
714
690
 
715
691
 
722
698
    :Item_func(a,b,c), cached_result_type(INT_RESULT)
723
699
  {}
724
700
  double val_real();
725
 
  int64_t val_int();
 
701
  longlong val_int();
726
702
  String *val_str(String *str);
727
703
  my_decimal *val_decimal(my_decimal *);
728
704
  enum Item_result result_type () const { return cached_result_type; }
729
705
  enum_field_types field_type() const { return cached_field_type; }
730
 
  bool fix_fields(Session *, Item **);
 
706
  bool fix_fields(THD *, Item **);
731
707
  void fix_length_and_dec();
732
 
  uint32_t decimal_precision() const;
 
708
  uint decimal_precision() const;
733
709
  const char *func_name() const { return "if"; }
734
710
};
735
711
 
742
718
    :Item_bool_func2(a,b), cached_result_type(INT_RESULT)
743
719
  {}
744
720
  double val_real();
745
 
  int64_t val_int();
 
721
  longlong val_int();
746
722
  String *val_str(String *str);
747
723
  my_decimal *val_decimal(my_decimal *);
748
724
  enum Item_result result_type () const { return cached_result_type; }
749
725
  void fix_length_and_dec();
750
 
  uint32_t decimal_precision() const { return args[0]->decimal_precision(); }
 
726
  uint decimal_precision() const { return args[0]->decimal_precision(); }
751
727
  const char *func_name() const { return "nullif"; }
752
728
 
753
729
  virtual inline void print(String *str, enum_query_type query_type)
765
741
 
766
742
/* A vector of values of some type  */
767
743
 
768
 
class in_vector :public memory::SqlAlloc
 
744
class in_vector :public Sql_alloc
769
745
{
770
746
public:
771
747
  char *base;
772
 
  uint32_t size;
 
748
  uint size;
773
749
  qsort2_cmp compare;
774
 
  const CHARSET_INFO *collation;
775
 
  uint32_t count;
776
 
  uint32_t used_count;
 
750
  CHARSET_INFO *collation;
 
751
  uint count;
 
752
  uint used_count;
777
753
  in_vector() {}
778
 
  in_vector(uint32_t elements,uint32_t element_length,qsort2_cmp cmp_func,
779
 
            const CHARSET_INFO * const cmp_coll)
780
 
    :base((char*) memory::sql_calloc(elements*element_length)),
 
754
  in_vector(uint elements,uint element_length,qsort2_cmp cmp_func, 
 
755
            CHARSET_INFO *cmp_coll)
 
756
    :base((char*) sql_calloc(elements*element_length)),
781
757
     size(element_length), compare(cmp_func), collation(cmp_coll),
782
758
     count(elements), used_count(elements) {}
783
759
  virtual ~in_vector() {}
784
 
  virtual void set(uint32_t pos,Item *item)=0;
785
 
  virtual unsigned char *get_value(Item *item)=0;
786
 
  void sort();
 
760
  virtual void set(uint pos,Item *item)=0;
 
761
  virtual uchar *get_value(Item *item)=0;
 
762
  void sort()
 
763
  {
 
764
    my_qsort2(base,used_count,size,compare,collation);
 
765
  }
787
766
  int find(Item *item);
788
 
 
789
 
  /*
 
767
  
 
768
  /* 
790
769
    Create an instance of Item_{type} (e.g. Item_decimal) constant object
791
770
    which type allows it to hold an element of this vector without any
792
771
    conversions.
795
774
    for every array element you get (i.e. this implements "FlyWeight" pattern)
796
775
  */
797
776
  virtual Item* create_item() { return NULL; }
798
 
 
 
777
  
799
778
  /*
800
779
    Store the value at position #pos into provided item object
801
780
    SYNOPSIS
804
783
        item  Constant item to store value into. The item must be of the same
805
784
              type that create_item() returns.
806
785
  */
807
 
  virtual void value_to_item(uint32_t, Item *) { }
808
 
 
 
786
  virtual void value_to_item(uint pos __attribute__((__unused__)),
 
787
                             Item *item __attribute__((__unused__))) { }
 
788
  
809
789
  /* Compare values number pos1 and pos2 for equality */
810
 
  bool compare_elems(uint32_t pos1, uint32_t pos2)
 
790
  bool compare_elems(uint pos1, uint pos2)
811
791
  {
812
792
    return test(compare(collation, base + pos1*size, base + pos2*size));
813
793
  }
819
799
  char buff[STRING_BUFFER_USUAL_SIZE];
820
800
  String tmp;
821
801
public:
822
 
  in_string(uint32_t elements,qsort2_cmp cmp_func, const CHARSET_INFO * const cs);
 
802
  in_string(uint elements,qsort2_cmp cmp_func, CHARSET_INFO *cs);
823
803
  ~in_string();
824
 
  void set(uint32_t pos,Item *item);
825
 
  unsigned char *get_value(Item *item);
 
804
  void set(uint pos,Item *item);
 
805
  uchar *get_value(Item *item);
826
806
  Item* create_item()
827
 
  {
 
807
  { 
828
808
    return new Item_string(collation);
829
809
  }
830
 
  void value_to_item(uint32_t pos, Item *item)
831
 
  {
 
810
  void value_to_item(uint pos, Item *item)
 
811
  {    
832
812
    String *str=((String*) base)+pos;
833
813
    Item_string *to= (Item_string*)item;
834
814
    to->str_value= *str;
836
816
  Item_result result_type() { return STRING_RESULT; }
837
817
};
838
818
 
839
 
class in_int64_t :public in_vector
 
819
class in_longlong :public in_vector
840
820
{
841
821
protected:
842
822
  /*
843
823
    Here we declare a temporary variable (tmp) of the same type as the
844
 
    elements of this vector. tmp is used in finding if a given value is in
845
 
    the list.
 
824
    elements of this vector. tmp is used in finding if a given value is in 
 
825
    the list. 
846
826
  */
847
 
  struct packed_int64_t
 
827
  struct packed_longlong 
848
828
  {
849
 
    int64_t val;
850
 
    int64_t unsigned_flag;  // Use int64_t, not bool, to preserve alignment
 
829
    longlong val;
 
830
    longlong unsigned_flag;  // Use longlong, not bool, to preserve alignment
851
831
  } tmp;
852
832
public:
853
 
  in_int64_t(uint32_t elements);
854
 
  void set(uint32_t pos,Item *item);
855
 
  unsigned char *get_value(Item *item);
856
 
 
 
833
  in_longlong(uint elements);
 
834
  void set(uint pos,Item *item);
 
835
  uchar *get_value(Item *item);
 
836
  
857
837
  Item* create_item()
858
 
  {
859
 
    /*
860
 
      We're created a signed INT, this may not be correct in
 
838
  { 
 
839
    /* 
 
840
      We're created a signed INT, this may not be correct in 
861
841
      general case (see BUG#19342).
862
842
    */
863
 
    return new Item_int((int64_t)0);
 
843
    return new Item_int((longlong)0);
864
844
  }
865
 
  void value_to_item(uint32_t pos, Item *item)
 
845
  void value_to_item(uint pos, Item *item)
866
846
  {
867
 
    ((Item_int*) item)->value= ((packed_int64_t*) base)[pos].val;
868
 
    ((Item_int*) item)->unsigned_flag= (bool)
869
 
      ((packed_int64_t*) base)[pos].unsigned_flag;
 
847
    ((Item_int*) item)->value= ((packed_longlong*) base)[pos].val;
 
848
    ((Item_int*) item)->unsigned_flag= (my_bool)
 
849
      ((packed_longlong*) base)[pos].unsigned_flag;
870
850
  }
871
851
  Item_result result_type() { return INT_RESULT; }
872
852
 
873
 
  friend int cmp_int64_t(void *cmp_arg, packed_int64_t *a,packed_int64_t *b);
 
853
  friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
874
854
};
875
855
 
876
856
 
880
860
  If the left item is a constant one then its value is cached in the
881
861
  lval_cache variable.
882
862
*/
883
 
class in_datetime :public in_int64_t
 
863
class in_datetime :public in_longlong
884
864
{
885
865
public:
886
 
  Session *session;
 
866
  THD *thd;
887
867
  /* An item used to issue warnings. */
888
868
  Item *warn_item;
889
869
  /* Cache for the left item. */
890
870
  Item *lval_cache;
891
871
 
892
 
  in_datetime(Item *warn_item_arg, uint32_t elements)
893
 
    :in_int64_t(elements), session(current_session), warn_item(warn_item_arg),
 
872
  in_datetime(Item *warn_item_arg, uint elements)
 
873
    :in_longlong(elements), thd(current_thd), warn_item(warn_item_arg),
894
874
     lval_cache(0) {};
895
 
  void set(uint32_t pos,Item *item);
896
 
  unsigned char *get_value(Item *item);
897
 
  friend int cmp_int64_t(void *cmp_arg, packed_int64_t *a,packed_int64_t *b);
 
875
  void set(uint pos,Item *item);
 
876
  uchar *get_value(Item *item);
 
877
  friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
898
878
};
899
879
 
900
880
 
902
882
{
903
883
  double tmp;
904
884
public:
905
 
  in_double(uint32_t elements);
906
 
  void set(uint32_t pos,Item *item);
907
 
  unsigned char *get_value(Item *item);
 
885
  in_double(uint elements);
 
886
  void set(uint pos,Item *item);
 
887
  uchar *get_value(Item *item);
908
888
  Item *create_item()
909
 
  {
 
889
  { 
910
890
    return new Item_float(0.0, 0);
911
891
  }
912
 
  void value_to_item(uint32_t pos, Item *item)
 
892
  void value_to_item(uint pos, Item *item)
913
893
  {
914
894
    ((Item_float*)item)->value= ((double*) base)[pos];
915
895
  }
921
901
{
922
902
  my_decimal val;
923
903
public:
924
 
  in_decimal(uint32_t elements);
925
 
  void set(uint32_t pos, Item *item);
926
 
  unsigned char *get_value(Item *item);
 
904
  in_decimal(uint elements);
 
905
  void set(uint pos, Item *item);
 
906
  uchar *get_value(Item *item);
927
907
  Item *create_item()
928
 
  {
 
908
  { 
929
909
    return new Item_decimal(0, false);
930
910
  }
931
 
  void value_to_item(uint32_t pos, Item *item)
 
911
  void value_to_item(uint pos, Item *item)
932
912
  {
933
913
    my_decimal *dec= ((my_decimal *)base) + pos;
934
914
    Item_decimal *item_dec= (Item_decimal*)item;
943
923
** Classes for easy comparing of non const items
944
924
*/
945
925
 
946
 
class cmp_item :public memory::SqlAlloc
 
926
class cmp_item :public Sql_alloc
947
927
{
948
928
public:
949
 
  const CHARSET_INFO *cmp_charset;
 
929
  CHARSET_INFO *cmp_charset;
950
930
  cmp_item() { cmp_charset= &my_charset_bin; }
951
931
  virtual ~cmp_item() {}
952
932
  virtual void store_value(Item *item)= 0;
953
933
  virtual int cmp(Item *item)= 0;
954
934
  // for optimized IN with row
955
935
  virtual int compare(cmp_item *item)= 0;
956
 
  static cmp_item* get_comparator(Item_result type, const CHARSET_INFO * const cs);
 
936
  static cmp_item* get_comparator(Item_result type, CHARSET_INFO *cs);
957
937
  virtual cmp_item *make_same()= 0;
958
 
  virtual void store_value_by_template(cmp_item *, Item *item)
 
938
  virtual void store_value_by_template(cmp_item *tmpl  __attribute__((__unused__)),
 
939
                                       Item *item)
959
940
  {
960
941
    store_value(item);
961
942
  }
962
943
};
963
944
 
964
 
class cmp_item_string :public cmp_item
 
945
class cmp_item_string :public cmp_item 
965
946
{
966
947
protected:
967
948
  String *value_res;
968
949
public:
969
950
  cmp_item_string () {}
970
 
  cmp_item_string (const CHARSET_INFO * const cs) { cmp_charset= cs; }
971
 
  void set_charset(const CHARSET_INFO * const cs) { cmp_charset= cs; }
 
951
  cmp_item_string (CHARSET_INFO *cs) { cmp_charset= cs; }
 
952
  void set_charset(CHARSET_INFO *cs) { cmp_charset= cs; }
972
953
  friend class cmp_item_sort_string;
973
954
  friend class cmp_item_sort_string_in_static;
974
955
};
981
962
public:
982
963
  cmp_item_sort_string():
983
964
    cmp_item_string() {}
984
 
  cmp_item_sort_string(const CHARSET_INFO * const cs):
 
965
  cmp_item_sort_string(CHARSET_INFO *cs):
985
966
    cmp_item_string(cs),
986
967
    value(value_buff, sizeof(value_buff), cs) {}
987
968
  void store_value(Item *item)
1000
981
  {
1001
982
    cmp_item_string *l_cmp= (cmp_item_string *) ci;
1002
983
    return sortcmp(value_res, l_cmp->value_res, cmp_charset);
1003
 
  }
 
984
  } 
1004
985
  cmp_item *make_same();
1005
 
  void set_charset(const CHARSET_INFO * const cs)
 
986
  void set_charset(CHARSET_INFO *cs)
1006
987
  {
1007
988
    cmp_charset= cs;
1008
989
    value.set_quick(value_buff, sizeof(value_buff), cs);
1011
992
 
1012
993
class cmp_item_int :public cmp_item
1013
994
{
1014
 
  int64_t value;
 
995
  longlong value;
1015
996
public:
1016
997
  cmp_item_int() {}                           /* Remove gcc warning */
1017
998
  void store_value(Item *item)
1038
1019
*/
1039
1020
class cmp_item_datetime :public cmp_item
1040
1021
{
1041
 
  uint64_t value;
 
1022
  ulonglong value;
1042
1023
public:
1043
 
  Session *session;
 
1024
  THD *thd;
1044
1025
  /* Item used for issuing warnings. */
1045
1026
  Item *warn_item;
1046
1027
  /* Cache for the left item. */
1047
1028
  Item *lval_cache;
1048
1029
 
1049
1030
  cmp_item_datetime(Item *warn_item_arg)
1050
 
    :session(current_session), warn_item(warn_item_arg), lval_cache(0) {}
 
1031
    :thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
1051
1032
  void store_value(Item *item);
1052
1033
  int cmp(Item *arg);
1053
1034
  int compare(cmp_item *ci);
1088
1069
};
1089
1070
 
1090
1071
 
1091
 
/*
 
1072
/* 
1092
1073
   cmp_item for optimized IN with row (right part string, which never
1093
1074
   be changed)
1094
1075
*/
1098
1079
 protected:
1099
1080
  String value;
1100
1081
public:
1101
 
  cmp_item_sort_string_in_static(const CHARSET_INFO * const cs):
 
1082
  cmp_item_sort_string_in_static(CHARSET_INFO *cs):
1102
1083
    cmp_item_string(cs) {}
1103
1084
  void store_value(Item *item)
1104
1085
  {
1105
1086
    value_res= item->val_str(&value);
1106
1087
  }
1107
 
  int cmp(Item *)
 
1088
  int cmp(Item *item __attribute__((__unused__)))
1108
1089
  {
1109
1090
    // Should never be called
1110
1091
    assert(0);
1126
1107
  The class Item_func_case is the CASE ... WHEN ... THEN ... END function
1127
1108
  implementation.
1128
1109
 
1129
 
  When there is no expression between CASE and the first WHEN
 
1110
  When there is no expression between CASE and the first WHEN 
1130
1111
  (the CASE expression) then this function simple checks all WHEN expressions
1131
1112
  one after another. When some WHEN expression evaluated to TRUE then the
1132
1113
  value of the corresponding THEN expression is returned.
1145
1126
  int first_expr_num, else_expr_num;
1146
1127
  enum Item_result cached_result_type, left_result_type;
1147
1128
  String tmp_value;
1148
 
  uint32_t ncases;
 
1129
  uint ncases;
1149
1130
  Item_result cmp_type;
1150
1131
  DTCollation cmp_collation;
1151
1132
  enum_field_types cached_field_type;
1168
1149
      list.push_back(else_expr_arg);
1169
1150
    }
1170
1151
    set_arguments(list);
1171
 
    memset(&cmp_items, 0, sizeof(cmp_items));
 
1152
    bzero(&cmp_items, sizeof(cmp_items));
1172
1153
  }
1173
1154
  double val_real();
1174
 
  int64_t val_int();
 
1155
  longlong val_int();
1175
1156
  String *val_str(String *);
1176
1157
  my_decimal *val_decimal(my_decimal *);
1177
 
  bool fix_fields(Session *session, Item **ref);
 
1158
  bool fix_fields(THD *thd, Item **ref);
1178
1159
  void fix_length_and_dec();
1179
 
  uint32_t decimal_precision() const;
 
1160
  uint decimal_precision() const;
1180
1161
  table_map not_null_tables() const { return 0; }
1181
1162
  enum Item_result result_type () const { return cached_result_type; }
1182
1163
  enum_field_types field_type() const { return cached_field_type; }
1183
1164
  const char *func_name() const { return "case"; }
1184
1165
  virtual void print(String *str, enum_query_type query_type);
1185
1166
  Item *find_item(String *str);
1186
 
  const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
 
1167
  CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1187
1168
  void cleanup();
1188
1169
  void agg_str_lengths(Item *arg);
1189
1170
  void agg_num_lengths(Item *arg);
1206
1187
class Item_func_in :public Item_func_opt_neg
1207
1188
{
1208
1189
public:
1209
 
  /*
 
1190
  /* 
1210
1191
    an array of values when the right hand arguments of IN
1211
 
    are all SQL constant and there are no nulls
 
1192
    are all SQL constant and there are no nulls 
1212
1193
  */
1213
1194
  in_vector *array;
1214
1195
  bool have_null;
1215
 
  /*
 
1196
  /* 
1216
1197
    true when all arguments of the IN clause are of compatible types
1217
1198
    and can be used safely as comparisons for key conditions
1218
1199
  */
1225
1206
    :Item_func_opt_neg(list), array(0), have_null(0),
1226
1207
    arg_types_compatible(false)
1227
1208
  {
1228
 
    memset(&cmp_items, 0, sizeof(cmp_items));
 
1209
    bzero(&cmp_items, sizeof(cmp_items));
1229
1210
    allowed_arg_cols= 0;  // Fetch this value from first argument
1230
1211
  }
1231
 
  int64_t val_int();
1232
 
  bool fix_fields(Session *, Item **);
 
1212
  longlong val_int();
 
1213
  bool fix_fields(THD *, Item **);
1233
1214
  void fix_length_and_dec();
1234
 
  uint32_t decimal_precision() const { return 1; }
 
1215
  uint decimal_precision() const { return 1; }
1235
1216
  void cleanup()
1236
1217
  {
1237
 
    uint32_t i;
 
1218
    uint i;
1238
1219
    Item_int_func::cleanup();
1239
1220
    delete array;
1240
1221
    array= 0;
1241
 
    for (i= 0; i <= (uint32_t)DECIMAL_RESULT + 1; i++)
 
1222
    for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
1242
1223
    {
1243
1224
      delete cmp_items[i];
1244
1225
      cmp_items[i]= 0;
1252
1233
  const char *func_name() const { return " IN "; }
1253
1234
  bool nulls_in_row();
1254
1235
  bool is_bool_func() { return 1; }
1255
 
  const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
 
1236
  CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1256
1237
};
1257
1238
 
1258
1239
class cmp_item_row :public cmp_item
1259
1240
{
1260
1241
  cmp_item **comparators;
1261
 
  uint32_t n;
 
1242
  uint n;
1262
1243
public:
1263
1244
  cmp_item_row(): comparators(0), n(0) {}
1264
1245
  ~cmp_item_row();
1276
1257
{
1277
1258
  cmp_item_row tmp;
1278
1259
public:
1279
 
  in_row(uint32_t elements, Item *);
 
1260
  in_row(uint elements, Item *);
1280
1261
  ~in_row();
1281
 
  void set(uint32_t pos,Item *item);
1282
 
  unsigned char *get_value(Item *item);
 
1262
  void set(uint pos,Item *item);
 
1263
  uchar *get_value(Item *item);
1283
1264
  friend void Item_func_in::fix_length_and_dec();
1284
1265
  Item_result result_type() { return ROW_RESULT; }
1285
1266
};
1289
1270
class Item_func_isnull :public Item_bool_func
1290
1271
{
1291
1272
protected:
1292
 
  int64_t cached_value;
 
1273
  longlong cached_value;
1293
1274
public:
1294
1275
  Item_func_isnull(Item *a) :Item_bool_func(a) {}
1295
 
  int64_t val_int();
 
1276
  longlong val_int();
1296
1277
  enum Functype functype() const { return ISNULL_FUNC; }
1297
1278
  void fix_length_and_dec()
1298
1279
  {
1307
1288
    {
1308
1289
      used_tables_cache= 0;                     /* is always false */
1309
1290
      const_item_cache= 1;
1310
 
      cached_value= (int64_t) 0;
 
1291
      cached_value= (longlong) 0;
1311
1292
    }
1312
1293
    else
1313
1294
    {
1316
1297
          !with_subselect)
1317
1298
      {
1318
1299
        /* Remember if the value is always NULL or never NULL */
1319
 
        cached_value= (int64_t) args[0]->is_null();
 
1300
        cached_value= (longlong) args[0]->is_null();
1320
1301
      }
1321
1302
    }
1322
1303
  }
1323
1304
  table_map not_null_tables() const { return 0; }
1324
1305
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1325
 
  Item *neg_transformer(Session *session);
1326
 
  const CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
 
1306
  Item *neg_transformer(THD *thd);
 
1307
  CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1327
1308
};
1328
1309
 
1329
1310
/* Functions used by HAVING for rewriting IN subquery */
1330
1311
 
1331
1312
class Item_in_subselect;
1332
1313
 
1333
 
/*
 
1314
/* 
1334
1315
  This is like IS NOT NULL but it also remembers if it ever has
1335
1316
  encountered a NULL.
1336
1317
*/
1342
1323
    :Item_func_isnull(a), owner(ow)
1343
1324
  {}
1344
1325
  enum Functype functype() const { return ISNOTNULLTEST_FUNC; }
1345
 
  int64_t val_int();
 
1326
  longlong val_int();
1346
1327
  const char *func_name() const { return "<is_not_null_test>"; }
1347
1328
  void update_used_tables();
1348
1329
  /*
1358
1339
  bool abort_on_null;
1359
1340
public:
1360
1341
  Item_func_isnotnull(Item *a) :Item_bool_func(a), abort_on_null(0) {}
1361
 
  int64_t val_int();
 
1342
  longlong val_int();
1362
1343
  enum Functype functype() const { return ISNOTNULL_FUNC; }
1363
1344
  void fix_length_and_dec()
1364
1345
  {
1368
1349
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1369
1350
  table_map not_null_tables() const
1370
1351
  { return abort_on_null ? not_null_tables_cache : 0; }
1371
 
  Item *neg_transformer(Session *session);
 
1352
  Item *neg_transformer(THD *thd);
1372
1353
  virtual void print(String *str, enum_query_type query_type);
1373
 
  const CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
 
1354
  CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1374
1355
  void top_level_item() { abort_on_null=1; }
1375
1356
};
1376
1357
 
1393
1374
  enum { alphabet_size = 256 };
1394
1375
 
1395
1376
  Item *escape_item;
1396
 
 
 
1377
  
1397
1378
  bool escape_used_in_parsing;
1398
1379
 
1399
 
 
1400
1380
public:
1401
 
 
1402
 
  char *escape;
 
1381
  int escape;
1403
1382
 
1404
1383
  Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
1405
 
    :Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0),
 
1384
    :Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0), 
1406
1385
     bmGs(0), bmBc(0), escape_item(escape_arg),
1407
 
     escape_used_in_parsing(escape_used), escape(NULL) {}
1408
 
  int64_t val_int();
 
1386
     escape_used_in_parsing(escape_used) {}
 
1387
  longlong val_int();
1409
1388
  enum Functype functype() const { return LIKE_FUNC; }
1410
1389
  optimize_type select_optimize() const;
1411
1390
  cond_result eq_cmp_result() const { return COND_TRUE; }
1412
1391
  const char *func_name() const { return "like"; }
1413
 
  bool fix_fields(Session *session, Item **ref);
 
1392
  bool fix_fields(THD *thd, Item **ref);
1414
1393
  void cleanup();
1415
1394
};
1416
1395
 
1425
1404
  table_map and_tables_cache;
1426
1405
 
1427
1406
public:
1428
 
 
1429
 
  using Item::split_sum_func;
1430
 
 
1431
1407
  /* Item_cond() is only used to create top level items */
1432
1408
  Item_cond(): Item_bool_func(), abort_on_null(1)
1433
1409
  { const_item_cache=0; }
1437
1413
    list.push_back(i1);
1438
1414
    list.push_back(i2);
1439
1415
  }
1440
 
  Item_cond(Session *session, Item_cond *item);
 
1416
  Item_cond(THD *thd, Item_cond *item);
1441
1417
  Item_cond(List<Item> &nlist)
1442
1418
    :Item_bool_func(), list(nlist), abort_on_null(0) {}
1443
1419
  bool add(Item *item) { return list.push_back(item); }
1444
1420
  bool add_at_head(Item *item) { return list.push_front(item); }
1445
1421
  void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
1446
 
  bool fix_fields(Session *, Item **ref);
1447
 
  void fix_after_pullout(Select_Lex *new_parent, Item **ref);
 
1422
  bool fix_fields(THD *, Item **ref);
 
1423
  void fix_after_pullout(st_select_lex *new_parent, Item **ref);
1448
1424
 
1449
1425
  enum Type type() const { return COND_ITEM; }
1450
1426
  List<Item>* argument_list() { return &list; }
1451
1427
  table_map used_tables() const;
1452
1428
  void update_used_tables();
1453
1429
  virtual void print(String *str, enum_query_type query_type);
1454
 
  void split_sum_func(Session *session, Item **ref_pointer_array, List<Item> &fields);
1455
 
  friend int setup_conds(Session *session, TableList *tables, TableList *leaves,
 
1430
  void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
 
1431
  friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
1456
1432
                         COND **conds);
1457
1433
  void top_level_item() { abort_on_null=1; }
1458
 
  void copy_andor_arguments(Session *session, Item_cond *item);
1459
 
  bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1460
 
  Item *transform(Item_transformer transformer, unsigned char *arg);
 
1434
  void copy_andor_arguments(THD *thd, Item_cond *item);
 
1435
  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
 
1436
  Item *transform(Item_transformer transformer, uchar *arg);
1461
1437
  void traverse_cond(Cond_traverser, void *arg, traverse_order order);
1462
 
  void neg_arguments(Session *session);
1463
 
  enum_field_types field_type() const { return DRIZZLE_TYPE_LONGLONG; }
1464
 
  bool subst_argument_checker(unsigned char **)
 
1438
  void neg_arguments(THD *thd);
 
1439
  enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
 
1440
  bool subst_argument_checker(uchar **arg __attribute__((__unused__)))
1465
1441
  { return true; }
1466
 
  Item *compile(Item_analyzer analyzer, unsigned char **arg_p,
1467
 
                Item_transformer transformer, unsigned char *arg_t);
 
1442
  Item *compile(Item_analyzer analyzer, uchar **arg_p,
 
1443
                Item_transformer transformer, uchar *arg_t);
1468
1444
};
1469
1445
 
1470
1446
 
1485
1461
  A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
1486
1462
  substituted for the item representing the same multiple equality
1487
1463
  f1=f2=f3.
1488
 
  An item Item_equal(f1,f2) can appear instead of a conjunction of
 
1464
  An item Item_equal(f1,f2) can appear instead of a conjunction of 
1489
1465
  f2=f1 and f1=f2, or instead of just the predicate f1=f2.
1490
1466
 
1491
 
  An item of the class Item_equal inherits equalities from outer
 
1467
  An item of the class Item_equal inherits equalities from outer 
1492
1468
  conjunctive levels.
1493
1469
 
1494
1470
  Suppose we have a where condition of the following form:
1499
1475
    f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
1500
1476
 
1501
1477
  An object of the class Item_equal can contain an optional constant
1502
 
  item c. Then it represents a multiple equality of the form
 
1478
  item c. Then it represents a multiple equality of the form 
1503
1479
  c=f1=...=fk.
1504
1480
 
1505
1481
  Objects of the class Item_equal are used for the following:
1514
1490
  It also can give us additional index scans and can allow us to
1515
1491
  improve selectivity estimates.
1516
1492
 
1517
 
  3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
1518
 
  selected execution plan for the query: if table ti is accessed
 
1493
  3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the 
 
1494
  selected execution plan for the query: if table ti is accessed 
1519
1495
  before the table tj then in any predicate P in the where condition
1520
1496
  the occurrence of tj.fj is substituted for ti.fi. This can allow
1521
1497
  an evaluation of the predicate at an earlier step.
1522
1498
 
1523
 
  When feature 1 is supported they say that join transitive closure
 
1499
  When feature 1 is supported they say that join transitive closure 
1524
1500
  is employed.
1525
1501
  When feature 2 is supported they say that search argument transitive
1526
1502
  closure is employed.
1529
1505
  We do not just add predicates, we rather dynamically replace some
1530
1506
  predicates that can not be used to access tables in the investigated
1531
1507
  plan for those, obtained by substitution of some fields for equal fields,
1532
 
  that can be used.
 
1508
  that can be used.     
1533
1509
 
1534
1510
  Prepared Statements/Stored Procedures note: instances of class
1535
1511
  Item_equal are created only at the time a PS/SP is executed and
1559
1535
  inline Item* get_const() { return const_item; }
1560
1536
  void add(Item *c);
1561
1537
  void add(Item_field *f);
1562
 
  uint32_t members();
 
1538
  uint members();
1563
1539
  bool contains(Field *field);
1564
1540
  Item_field* get_first() { return fields.head(); }
1565
1541
  void merge(Item_equal *item);
1566
1542
  void update_const();
1567
1543
  enum Functype functype() const { return MULT_EQUAL_FUNC; }
1568
 
  int64_t val_int();
 
1544
  longlong val_int(); 
1569
1545
  const char *func_name() const { return "multiple equal"; }
1570
1546
  optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
1571
1547
  void sort(Item_field_cmpfunc cmp, void *arg);
1572
1548
  friend class Item_equal_iterator;
1573
1549
  void fix_length_and_dec();
1574
 
  bool fix_fields(Session *session, Item **ref);
 
1550
  bool fix_fields(THD *thd, Item **ref);
1575
1551
  void update_used_tables();
1576
 
  bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1577
 
  Item *transform(Item_transformer transformer, unsigned char *arg);
 
1552
  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
 
1553
  Item *transform(Item_transformer transformer, uchar *arg);
1578
1554
  virtual void print(String *str, enum_query_type query_type);
1579
 
  const CHARSET_INFO *compare_collation()
 
1555
  CHARSET_INFO *compare_collation() 
1580
1556
  { return fields.head()->collation.collation; }
1581
 
};
 
1557
}; 
1582
1558
 
1583
 
class COND_EQUAL: public memory::SqlAlloc
 
1559
class COND_EQUAL: public Sql_alloc
1584
1560
{
1585
1561
public:
1586
 
  uint32_t max_members;               /* max number of members the current level
1587
 
                                     list and all lower level lists */
 
1562
  uint max_members;               /* max number of members the current level
 
1563
                                     list and all lower level lists */ 
1588
1564
  COND_EQUAL *upper_levels;       /* multiple equalities of upper and levels */
1589
 
  List<Item_equal> current_level; /* list of multiple equalities of
 
1565
  List<Item_equal> current_level; /* list of multiple equalities of 
1590
1566
                                     the current and level           */
1591
1567
  COND_EQUAL()
1592
 
  {
 
1568
  { 
1593
1569
    upper_levels= 0;
1594
1570
  }
1595
1571
};
1598
1574
class Item_equal_iterator : public List_iterator_fast<Item_field>
1599
1575
{
1600
1576
public:
1601
 
  inline Item_equal_iterator(Item_equal &item_equal)
 
1577
  inline Item_equal_iterator(Item_equal &item_equal) 
1602
1578
    :List_iterator_fast<Item_field> (item_equal.fields)
1603
1579
  {}
1604
1580
  inline Item_field* operator++(int)
1605
 
  {
 
1581
  { 
1606
1582
    Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
1607
1583
    return  item;
1608
1584
  }
1609
 
  inline void rewind(void)
1610
 
  {
 
1585
  inline void rewind(void) 
 
1586
  { 
1611
1587
    List_iterator_fast<Item_field>::rewind();
1612
1588
  }
1613
1589
};
1615
1591
class Item_cond_and :public Item_cond
1616
1592
{
1617
1593
public:
1618
 
  COND_EQUAL cond_equal;  /* contains list of Item_equal objects for
 
1594
  COND_EQUAL cond_equal;  /* contains list of Item_equal objects for 
1619
1595
                             the current and level and reference
1620
 
                             to multiple equalities of upper and levels */
 
1596
                             to multiple equalities of upper and levels */  
1621
1597
  Item_cond_and() :Item_cond() {}
1622
1598
  Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1623
 
  Item_cond_and(Session *session, Item_cond_and *item) :Item_cond(session, item) {}
 
1599
  Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
1624
1600
  Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
1625
1601
  enum Functype functype() const { return COND_AND_FUNC; }
1626
 
  int64_t val_int();
 
1602
  longlong val_int();
1627
1603
  const char *func_name() const { return "and"; }
1628
1604
  table_map not_null_tables() const
1629
1605
  { return abort_on_null ? not_null_tables_cache: and_tables_cache; }
1630
 
  Item* copy_andor_structure(Session *session)
 
1606
  Item* copy_andor_structure(THD *thd)
1631
1607
  {
1632
1608
    Item_cond_and *item;
1633
 
    if ((item= new Item_cond_and(session, this)))
1634
 
       item->copy_andor_arguments(session, this);
 
1609
    if ((item= new Item_cond_and(thd, this)))
 
1610
       item->copy_andor_arguments(thd, this);
1635
1611
    return item;
1636
1612
  }
1637
 
  Item *neg_transformer(Session *session);
 
1613
  Item *neg_transformer(THD *thd);
1638
1614
};
1639
1615
 
1640
1616
inline bool is_cond_and(Item *item)
1651
1627
public:
1652
1628
  Item_cond_or() :Item_cond() {}
1653
1629
  Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1654
 
  Item_cond_or(Session *session, Item_cond_or *item) :Item_cond(session, item) {}
 
1630
  Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
1655
1631
  Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
1656
1632
  enum Functype functype() const { return COND_OR_FUNC; }
1657
 
  int64_t val_int();
 
1633
  longlong val_int();
1658
1634
  const char *func_name() const { return "or"; }
1659
1635
  table_map not_null_tables() const { return and_tables_cache; }
1660
 
  Item* copy_andor_structure(Session *session)
 
1636
  Item* copy_andor_structure(THD *thd)
1661
1637
  {
1662
1638
    Item_cond_or *item;
1663
 
    if ((item= new Item_cond_or(session, this)))
1664
 
      item->copy_andor_arguments(session, this);
 
1639
    if ((item= new Item_cond_or(thd, this)))
 
1640
      item->copy_andor_arguments(thd, this);
1665
1641
    return item;
1666
1642
  }
1667
 
  Item *neg_transformer(Session *session);
 
1643
  Item *neg_transformer(THD *thd);
1668
1644
};
1669
1645
 
1670
1646
inline bool is_cond_or(Item *item)
1689
1665
  enum Functype functype() const { return COND_XOR_FUNC; }
1690
1666
  /* TODO: remove the next line when implementing XOR optimization */
1691
1667
  enum Type type() const { return FUNC_ITEM; }
1692
 
  int64_t val_int();
 
1668
  longlong val_int();
1693
1669
  const char *func_name() const { return "xor"; }
1694
1670
  void top_level_item() {}
1695
1671
};
1696
1672
 
1697
 
enum_field_types agg_field_type(Item **items, uint32_t nitems);
1698
 
 
1699
1673
 
1700
1674
/* Some useful inline functions */
1701
1675
 
1707
1681
}
1708
1682
 
1709
1683
Item *and_expressions(Item *a, Item *b, Item **org_item);
1710
 
 
1711
 
} /* namespace drizzled */
1712
 
 
1713
 
#endif /* DRIZZLED_ITEM_CMPFUNC_H */