~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item_cmpfunc.h

Added autoconf tests for location of cstdint and cinttypes. Use those in C++ programs now, so that we don't have to define _STDC_LIMIT_MACROS, etc by hand. Stop, in fact, defining those by hand.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#ifndef DRIZZLED_ITEM_CMPFUNC_H
21
 
#define DRIZZLED_ITEM_CMPFUNC_H
22
20
 
23
21
/* compare and test functions */
24
22
 
25
 
#include <drizzled/common.h>
26
 
#include <drizzled/comp_creator.h>
27
 
#include <drizzled/function/math/int.h>
28
 
#include <drizzled/function/numhybrid.h>
29
 
#include <drizzled/item/decimal.h>
30
 
#include <drizzled/item/float.h>
31
 
#include <drizzled/item/function/boolean.h>
32
 
#include <drizzled/item/int.h>
33
 
#include <drizzled/item/row.h>
34
 
#include <drizzled/item/string.h>
35
 
#include <drizzled/item/sum.h>
36
 
#include <drizzled/qsort_cmp.h>
37
 
 
38
 
namespace drizzled
39
 
{
 
23
#ifdef USE_PRAGMA_INTERFACE
 
24
#pragma interface                       /* gcc class implementation */
 
25
#endif
40
26
 
41
27
extern Item_result item_cmp_type(Item_result a,Item_result b);
42
 
 
43
28
class Item_bool_func2;
44
29
class Arg_comparator;
45
 
class Item_sum_hybrid;
46
 
class Item_row;
47
 
class Session;
48
30
 
49
31
typedef int (Arg_comparator::*arg_cmp_func)();
50
32
 
51
 
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
52
 
 
53
 
int64_t get_datetime_value(Session *session, 
54
 
                           Item ***item_arg, 
55
 
                           Item **cache_arg,
56
 
                           Item *warn_item, 
57
 
                           bool *is_null);
58
 
 
59
 
class Arg_comparator: public memory::SqlAlloc
 
33
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg); 
 
34
 
 
35
class Arg_comparator: public Sql_alloc
60
36
{
61
37
  Item **a, **b;
62
38
  arg_cmp_func func;
64
40
  Arg_comparator *comparators;   // used only for compare_row()
65
41
  double precision;
66
42
  /* Fields used in DATE/DATETIME comparison. */
67
 
  Session *session;
 
43
  THD *thd;
68
44
  enum_field_types a_type, b_type; // Types of a and b items
69
45
  Item *a_cache, *b_cache;         // Cached values of a and b items
70
46
  bool is_nulls_eq;                // TRUE <=> compare for the EQUAL_FUNC
71
47
  enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
72
48
                            CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
73
 
  int64_t (*get_value_func)(Session *session, Item ***item_arg, Item **cache_arg,
74
 
                            Item *warn_item, bool *is_null);
 
49
  uint64_t (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg,
 
50
                              Item *warn_item, bool *is_null);
75
51
public:
76
52
  DTCollation cmp_collation;
77
53
 
78
 
  Arg_comparator();
79
 
 
80
 
  Arg_comparator(Item **a1, Item **a2);
 
54
  Arg_comparator(): thd(0), a_cache(0), b_cache(0) {};
 
55
  Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), thd(0),
 
56
    a_cache(0), b_cache(0) {};
81
57
 
82
58
  int set_compare_func(Item_bool_func2 *owner, Item_result type);
83
59
  inline int set_compare_func(Item_bool_func2 *owner_arg)
119
95
  int compare_datetime();        // compare args[0] & args[1] as DATETIMEs
120
96
 
121
97
  static enum enum_date_cmp_type can_compare_as_dates(Item *a, Item *b,
122
 
                                                      int64_t *const_val_arg);
 
98
                                                      uint64_t *const_val_arg);
123
99
 
124
100
  void set_datetime_cmp_func(Item **a1, Item **b1);
125
101
  static arg_cmp_func comparator_matrix [5][2];
127
103
  friend class Item_func;
128
104
};
129
105
 
 
106
class Item_bool_func :public Item_int_func
 
107
{
 
108
public:
 
109
  Item_bool_func() :Item_int_func() {}
 
110
  Item_bool_func(Item *a) :Item_int_func(a) {}
 
111
  Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
 
112
  Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {}
 
113
  bool is_bool_func() { return 1; }
 
114
  void fix_length_and_dec() { decimals=0; max_length=1; }
 
115
  uint32_t decimal_precision() const { return 1; }
 
116
};
 
117
 
130
118
 
131
119
/**
132
120
  Abstract Item class, to represent <code>X IS [NOT] (TRUE | FALSE)</code>
133
121
  boolean predicates.
134
122
*/
135
123
 
136
 
class Item_func_truth : public item::function::Boolean
 
124
class Item_func_truth : public Item_bool_func
137
125
{
138
126
public:
139
127
  virtual bool val_bool();
143
131
 
144
132
protected:
145
133
  Item_func_truth(Item *a, bool a_value, bool a_affirmative)
146
 
  : item::function::Boolean(a), value(a_value), affirmative(a_affirmative)
 
134
  : Item_bool_func(a), value(a_value), affirmative(a_affirmative)
147
135
  {}
148
136
 
149
137
  ~Item_func_truth()
232
220
    placed into a separate class called 'Item_in_optimizer'.
233
221
*/
234
222
 
235
 
class Item_in_optimizer: public item::function::Boolean
 
223
class Item_in_optimizer: public Item_bool_func
236
224
{
237
225
protected:
238
226
  Item_cache *cache;
239
227
  bool save_cache;
240
 
  /*
 
228
  /* 
241
229
    Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
242
230
      UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
243
231
      FALSE   - result is FALSE
246
234
  bool result_for_null_param;
247
235
public:
248
236
  Item_in_optimizer(Item *a, Item_in_subselect *b):
249
 
    item::function::Boolean(a, reinterpret_cast<Item *>(b)), cache(0),
 
237
    Item_bool_func(a, reinterpret_cast<Item *>(b)), cache(0),
250
238
    save_cache(0), result_for_null_param(UNKNOWN)
251
239
  { with_subselect= true; }
252
 
  bool fix_fields(Session *, Item **);
253
 
  bool fix_left(Session *session, Item **ref);
 
240
  bool fix_fields(THD *, Item **);
 
241
  bool fix_left(THD *thd, Item **ref);
254
242
  bool is_null();
255
243
  int64_t val_int();
256
244
  void cleanup();
260
248
  Item *transform(Item_transformer transformer, unsigned char *arg);
261
249
};
262
250
 
 
251
class Comp_creator
 
252
{
 
253
public:
 
254
  Comp_creator() {}                           /* Remove gcc warning */
 
255
  virtual ~Comp_creator() {}                  /* Remove gcc warning */
 
256
  virtual Item_bool_func2* create(Item *a, Item *b) const = 0;
 
257
  virtual const char* symbol(bool invert) const = 0;
 
258
  virtual bool eqne_op() const = 0;
 
259
  virtual bool l_op() const = 0;
 
260
};
 
261
 
263
262
class Eq_creator :public Comp_creator
264
263
{
265
264
public:
269
268
  virtual const char* symbol(bool invert) const { return invert? "<>" : "="; }
270
269
  virtual bool eqne_op() const { return 1; }
271
270
  virtual bool l_op() const { return 0; }
272
 
  static const Eq_creator *instance();
273
271
};
274
272
 
275
273
class Ne_creator :public Comp_creator
281
279
  virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; }
282
280
  virtual bool eqne_op() const { return 1; }
283
281
  virtual bool l_op() const { return 0; }
284
 
  static const Ne_creator *instance();
285
282
};
286
283
 
287
284
class Gt_creator :public Comp_creator
293
290
  virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
294
291
  virtual bool eqne_op() const { return 0; }
295
292
  virtual bool l_op() const { return 0; }
296
 
  static const Gt_creator *instance();
297
293
};
298
294
 
299
295
class Lt_creator :public Comp_creator
305
301
  virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
306
302
  virtual bool eqne_op() const { return 0; }
307
303
  virtual bool l_op() const { return 1; }
308
 
  static const Lt_creator *instance();
309
304
};
310
305
 
311
306
class Ge_creator :public Comp_creator
317
312
  virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
318
313
  virtual bool eqne_op() const { return 0; }
319
314
  virtual bool l_op() const { return 0; }
320
 
  static const Ge_creator *instance();
321
315
};
322
316
 
323
317
class Le_creator :public Comp_creator
329
323
  virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
330
324
  virtual bool eqne_op() const { return 0; }
331
325
  virtual bool l_op() const { return 1; }
332
 
  static const Le_creator *instance();
333
326
};
334
327
 
335
328
class Item_bool_func2 :public Item_int_func
372
365
  {
373
366
    allowed_arg_cols= 0;  // Fetch this value from first argument
374
367
  }
375
 
  Item *neg_transformer(Session *session);
 
368
  Item *neg_transformer(THD *thd);
376
369
  virtual Item *negated_item();
377
 
  bool subst_argument_checker(unsigned char **)
 
370
  bool subst_argument_checker(unsigned char **arg __attribute__((unused)))
378
371
  { return true; }
379
372
};
380
373
 
381
 
class Item_func_not :public item::function::Boolean
 
374
class Item_func_not :public Item_bool_func
382
375
{
383
376
public:
384
 
  Item_func_not(Item *a) :item::function::Boolean(a) {}
 
377
  Item_func_not(Item *a) :Item_bool_func(a) {}
385
378
  int64_t val_int();
386
379
  enum Functype functype() const { return NOT_FUNC; }
387
380
  const char *func_name() const { return "not"; }
388
 
  Item *neg_transformer(Session *session);
 
381
  Item *neg_transformer(THD *thd);
389
382
  virtual void print(String *str, enum_query_type query_type);
390
383
};
391
384
 
394
387
/*
395
388
  trigcond<param>(arg) ::= param? arg : TRUE
396
389
 
397
 
  The class Item_func_trig_cond is used for guarded predicates
 
390
  The class Item_func_trig_cond is used for guarded predicates 
398
391
  which are employed only for internal purposes.
399
392
  A guarded predicate is an object consisting of an a regular or
400
 
  a guarded predicate P and a pointer to a boolean guard variable g.
 
393
  a guarded predicate P and a pointer to a boolean guard variable g. 
401
394
  A guarded predicate P/g is evaluated to true if the value of the
402
395
  guard g is false, otherwise it is evaluated to the same value that
403
396
  the predicate P: val(P/g)= g ? val(P):true.
409
402
  the objects consisting of three elements: a predicate P, a pointer
410
403
  to a variable g and a firing value s with following evaluation
411
404
  rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
412
 
  one item for the objects of the form P/g1/g2...
 
405
  one item for the objects of the form P/g1/g2... 
413
406
 
414
407
  Objects of this class are built only for query execution after
415
408
  the execution plan has been already selected. That's why this
416
 
  class needs only val_int out of generic methods.
417
 
 
 
409
  class needs only val_int out of generic methods. 
 
410
 
418
411
  Current uses of Item_func_trig_cond objects:
419
412
   - To wrap selection conditions when executing outer joins
420
413
   - To wrap condition that is pushed down into subquery
421
414
*/
422
415
 
423
 
class Item_func_trig_cond: public item::function::Boolean
 
416
class Item_func_trig_cond: public Item_bool_func
424
417
{
425
418
  bool *trig_var;
426
419
public:
427
 
  Item_func_trig_cond(Item *a, bool *f) : item::function::Boolean(a) { trig_var= f; }
 
420
  Item_func_trig_cond(Item *a, bool *f) : Item_bool_func(a) { trig_var= f; }
428
421
  int64_t val_int() { return *trig_var ? args[0]->val_int() : 1; }
429
422
  enum Functype functype() const { return TRIG_COND_FUNC; };
430
423
  const char *func_name() const { return "trigcond"; };
457
450
  void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
458
451
  void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
459
452
  bool empty_underlying_subquery();
460
 
  Item *neg_transformer(Session *session);
 
453
  Item *neg_transformer(THD *thd);
461
454
};
462
455
 
463
456
 
468
461
  Item_func_nop_all(Item *a) :Item_func_not_all(a) {}
469
462
  int64_t val_int();
470
463
  const char *func_name() const { return "<nop>"; }
471
 
  Item *neg_transformer(Session *session);
 
464
  Item *neg_transformer(THD *thd);
472
465
};
473
466
 
474
467
 
495
488
  enum Functype rev_functype() const { return EQUAL_FUNC; }
496
489
  cond_result eq_cmp_result() const { return COND_TRUE; }
497
490
  const char *func_name() const { return "<=>"; }
498
 
  Item *neg_transformer(Session *) { return 0; }
 
491
  Item *neg_transformer(THD *thd __attribute__((unused))) { return 0; }
499
492
};
500
493
 
501
494
 
558
551
  int64_t val_int();
559
552
  enum Functype functype() const { return NE_FUNC; }
560
553
  cond_result eq_cmp_result() const { return COND_FALSE; }
561
 
  optimize_type select_optimize() const { return OPTIMIZE_KEY; }
 
554
  optimize_type select_optimize() const { return OPTIMIZE_KEY; } 
562
555
  const char *func_name() const { return "<>"; }
563
556
  Item *negated_item();
564
557
};
586
579
public:
587
580
  inline void negate() { negated= !negated; }
588
581
  inline void top_level_item() { pred_level= 1; }
589
 
  Item *neg_transformer(Session *)
 
582
  Item *neg_transformer(THD *thd __attribute__((unused)))
590
583
  {
591
584
    negated= !negated;
592
585
    return this;
593
586
  }
594
587
  bool eq(const Item *item, bool binary_cmp) const;
595
 
  bool subst_argument_checker(unsigned char **)
 
588
  bool subst_argument_checker(unsigned char **arg __attribute__((unused)))
596
589
  { return true; }
597
590
};
598
591
 
613
606
  optimize_type select_optimize() const { return OPTIMIZE_KEY; }
614
607
  enum Functype functype() const   { return BETWEEN; }
615
608
  const char *func_name() const { return "between"; }
616
 
  bool fix_fields(Session *, Item **);
 
609
  bool fix_fields(THD *, Item **);
617
610
  void fix_length_and_dec();
618
611
  virtual void print(String *str, enum_query_type query_type);
619
612
  bool is_bool_func() { return 1; }
641
634
{
642
635
  Item_result type;
643
636
  double dbl;
644
 
  type::Decimal dec;
 
637
  my_decimal dec;
645
638
};
646
639
 
647
640
class Item_func_interval :public Item_int_func
672
665
  double real_op();
673
666
  int64_t int_op();
674
667
  String *str_op(String *);
675
 
  type::Decimal *decimal_op(type::Decimal *);
 
668
  my_decimal *decimal_op(my_decimal *);
676
669
  void fix_length_and_dec();
677
670
  void find_num_type() {}
678
671
  enum Item_result result_type () const { return hybrid_type; }
691
684
  double real_op();
692
685
  int64_t int_op();
693
686
  String *str_op(String *str);
694
 
  type::Decimal *decimal_op(type::Decimal *);
 
687
  my_decimal *decimal_op(my_decimal *);
695
688
  enum_field_types field_type() const;
696
689
  void fix_length_and_dec();
697
690
  const char *func_name() const { return "ifnull"; }
698
 
  Field *tmp_table_field()
699
 
  {
700
 
    return Item_func::tmp_table_field();
701
 
  }
702
691
  Field *tmp_table_field(Table *table);
703
692
  uint32_t decimal_precision() const;
704
693
};
715
704
  double val_real();
716
705
  int64_t val_int();
717
706
  String *val_str(String *str);
718
 
  type::Decimal *val_decimal(type::Decimal *);
 
707
  my_decimal *val_decimal(my_decimal *);
719
708
  enum Item_result result_type () const { return cached_result_type; }
720
709
  enum_field_types field_type() const { return cached_field_type; }
721
 
  bool fix_fields(Session *, Item **);
 
710
  bool fix_fields(THD *, Item **);
722
711
  void fix_length_and_dec();
723
712
  uint32_t decimal_precision() const;
724
713
  const char *func_name() const { return "if"; }
735
724
  double val_real();
736
725
  int64_t val_int();
737
726
  String *val_str(String *str);
738
 
  type::Decimal *val_decimal(type::Decimal *);
 
727
  my_decimal *val_decimal(my_decimal *);
739
728
  enum Item_result result_type () const { return cached_result_type; }
740
729
  void fix_length_and_dec();
741
730
  uint32_t decimal_precision() const { return args[0]->decimal_precision(); }
756
745
 
757
746
/* A vector of values of some type  */
758
747
 
759
 
class in_vector :public memory::SqlAlloc
 
748
class in_vector :public Sql_alloc
760
749
{
761
750
public:
762
751
  char *base;
766
755
  uint32_t count;
767
756
  uint32_t used_count;
768
757
  in_vector() {}
769
 
  in_vector(uint32_t elements,uint32_t element_length,qsort2_cmp cmp_func,
 
758
  in_vector(uint32_t elements,uint32_t element_length,qsort2_cmp cmp_func, 
770
759
            const CHARSET_INFO * const cmp_coll)
771
 
    :base((char*) memory::sql_calloc(elements*element_length)),
 
760
    :base((char*) sql_calloc(elements*element_length)),
772
761
     size(element_length), compare(cmp_func), collation(cmp_coll),
773
762
     count(elements), used_count(elements) {}
774
763
  virtual ~in_vector() {}
775
764
  virtual void set(uint32_t pos,Item *item)=0;
776
765
  virtual unsigned char *get_value(Item *item)=0;
777
 
  void sort();
 
766
  void sort()
 
767
  {
 
768
    my_qsort2(base,used_count,size,compare, (void *) collation);
 
769
  }
778
770
  int find(Item *item);
779
 
 
780
 
  /*
 
771
  
 
772
  /* 
781
773
    Create an instance of Item_{type} (e.g. Item_decimal) constant object
782
774
    which type allows it to hold an element of this vector without any
783
775
    conversions.
786
778
    for every array element you get (i.e. this implements "FlyWeight" pattern)
787
779
  */
788
780
  virtual Item* create_item() { return NULL; }
789
 
 
 
781
  
790
782
  /*
791
783
    Store the value at position #pos into provided item object
792
784
    SYNOPSIS
795
787
        item  Constant item to store value into. The item must be of the same
796
788
              type that create_item() returns.
797
789
  */
798
 
  virtual void value_to_item(uint32_t, Item *) { }
799
 
 
 
790
  virtual void value_to_item(uint32_t pos __attribute__((unused)),
 
791
                             Item *item __attribute__((unused))) { }
 
792
  
800
793
  /* Compare values number pos1 and pos2 for equality */
801
794
  bool compare_elems(uint32_t pos1, uint32_t pos2)
802
795
  {
815
808
  void set(uint32_t pos,Item *item);
816
809
  unsigned char *get_value(Item *item);
817
810
  Item* create_item()
818
 
  {
 
811
  { 
819
812
    return new Item_string(collation);
820
813
  }
821
814
  void value_to_item(uint32_t pos, Item *item)
822
 
  {
 
815
  {    
823
816
    String *str=((String*) base)+pos;
824
817
    Item_string *to= (Item_string*)item;
825
818
    to->str_value= *str;
832
825
protected:
833
826
  /*
834
827
    Here we declare a temporary variable (tmp) of the same type as the
835
 
    elements of this vector. tmp is used in finding if a given value is in
836
 
    the list.
 
828
    elements of this vector. tmp is used in finding if a given value is in 
 
829
    the list. 
837
830
  */
838
 
  struct packed_int64_t
 
831
  struct packed_int64_t 
839
832
  {
840
833
    int64_t val;
841
834
    int64_t unsigned_flag;  // Use int64_t, not bool, to preserve alignment
844
837
  in_int64_t(uint32_t elements);
845
838
  void set(uint32_t pos,Item *item);
846
839
  unsigned char *get_value(Item *item);
847
 
 
 
840
  
848
841
  Item* create_item()
849
 
  {
850
 
    /*
851
 
      We're created a signed INT, this may not be correct in
 
842
  { 
 
843
    /* 
 
844
      We're created a signed INT, this may not be correct in 
852
845
      general case (see BUG#19342).
853
846
    */
854
847
    return new Item_int((int64_t)0);
874
867
class in_datetime :public in_int64_t
875
868
{
876
869
public:
877
 
  Session *session;
 
870
  THD *thd;
878
871
  /* An item used to issue warnings. */
879
872
  Item *warn_item;
880
873
  /* Cache for the left item. */
881
874
  Item *lval_cache;
882
875
 
883
 
  in_datetime(Item *warn_item_arg, uint32_t elements);
884
 
 
 
876
  in_datetime(Item *warn_item_arg, uint32_t elements)
 
877
    :in_int64_t(elements), thd(current_thd), warn_item(warn_item_arg),
 
878
     lval_cache(0) {};
885
879
  void set(uint32_t pos,Item *item);
886
880
  unsigned char *get_value(Item *item);
887
881
  friend int cmp_int64_t(void *cmp_arg, packed_int64_t *a,packed_int64_t *b);
896
890
  void set(uint32_t pos,Item *item);
897
891
  unsigned char *get_value(Item *item);
898
892
  Item *create_item()
899
 
  {
 
893
  { 
900
894
    return new Item_float(0.0, 0);
901
895
  }
902
896
  void value_to_item(uint32_t pos, Item *item)
909
903
 
910
904
class in_decimal :public in_vector
911
905
{
912
 
  type::Decimal val;
 
906
  my_decimal val;
913
907
public:
914
908
  in_decimal(uint32_t elements);
915
909
  void set(uint32_t pos, Item *item);
916
910
  unsigned char *get_value(Item *item);
917
911
  Item *create_item()
918
 
  {
 
912
  { 
919
913
    return new Item_decimal(0, false);
920
914
  }
921
915
  void value_to_item(uint32_t pos, Item *item)
922
916
  {
923
 
    type::Decimal *dec= ((type::Decimal *)base) + pos;
 
917
    my_decimal *dec= ((my_decimal *)base) + pos;
924
918
    Item_decimal *item_dec= (Item_decimal*)item;
925
919
    item_dec->set_decimal_value(dec);
926
920
  }
933
927
** Classes for easy comparing of non const items
934
928
*/
935
929
 
936
 
class cmp_item :public memory::SqlAlloc
 
930
class cmp_item :public Sql_alloc
937
931
{
938
932
public:
939
933
  const CHARSET_INFO *cmp_charset;
940
 
 
941
 
  cmp_item()
942
 
  {
943
 
    cmp_charset= &my_charset_bin;
944
 
  }
945
 
 
 
934
  cmp_item() { cmp_charset= &my_charset_bin; }
946
935
  virtual ~cmp_item() {}
947
936
  virtual void store_value(Item *item)= 0;
948
937
  virtual int cmp(Item *item)= 0;
950
939
  virtual int compare(cmp_item *item)= 0;
951
940
  static cmp_item* get_comparator(Item_result type, const CHARSET_INFO * const cs);
952
941
  virtual cmp_item *make_same()= 0;
953
 
  virtual void store_value_by_template(cmp_item *, Item *item)
 
942
  virtual void store_value_by_template(cmp_item *tmpl  __attribute__((unused)),
 
943
                                       Item *item)
954
944
  {
955
945
    store_value(item);
956
946
  }
957
947
};
958
948
 
959
 
class cmp_item_string :public cmp_item
 
949
class cmp_item_string :public cmp_item 
960
950
{
961
951
protected:
962
952
  String *value_res;
995
985
  {
996
986
    cmp_item_string *l_cmp= (cmp_item_string *) ci;
997
987
    return sortcmp(value_res, l_cmp->value_res, cmp_charset);
998
 
  }
 
988
  } 
999
989
  cmp_item *make_same();
1000
990
  void set_charset(const CHARSET_INFO * const cs)
1001
991
  {
1033
1023
*/
1034
1024
class cmp_item_datetime :public cmp_item
1035
1025
{
1036
 
  int64_t value;
1037
 
 
 
1026
  uint64_t value;
1038
1027
public:
1039
 
  Session *session;
 
1028
  THD *thd;
1040
1029
  /* Item used for issuing warnings. */
1041
1030
  Item *warn_item;
1042
1031
  /* Cache for the left item. */
1043
1032
  Item *lval_cache;
1044
1033
 
1045
 
  cmp_item_datetime(Item *warn_item_arg);
1046
 
 
 
1034
  cmp_item_datetime(Item *warn_item_arg)
 
1035
    :thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
1047
1036
  void store_value(Item *item);
1048
1037
  int cmp(Item *arg);
1049
1038
  int compare(cmp_item *ci);
1074
1063
 
1075
1064
class cmp_item_decimal :public cmp_item
1076
1065
{
1077
 
  type::Decimal value;
 
1066
  my_decimal value;
1078
1067
public:
1079
1068
  cmp_item_decimal() {}                       /* Remove gcc warning */
1080
1069
  void store_value(Item *item);
1084
1073
};
1085
1074
 
1086
1075
 
1087
 
/*
 
1076
/* 
1088
1077
   cmp_item for optimized IN with row (right part string, which never
1089
1078
   be changed)
1090
1079
*/
1100
1089
  {
1101
1090
    value_res= item->val_str(&value);
1102
1091
  }
1103
 
  int cmp(Item *)
 
1092
  int cmp(Item *item __attribute__((unused)))
1104
1093
  {
1105
1094
    // Should never be called
1106
1095
    assert(0);
1122
1111
  The class Item_func_case is the CASE ... WHEN ... THEN ... END function
1123
1112
  implementation.
1124
1113
 
1125
 
  When there is no expression between CASE and the first WHEN
 
1114
  When there is no expression between CASE and the first WHEN 
1126
1115
  (the CASE expression) then this function simple checks all WHEN expressions
1127
1116
  one after another. When some WHEN expression evaluated to TRUE then the
1128
1117
  value of the corresponding THEN expression is returned.
1145
1134
  Item_result cmp_type;
1146
1135
  DTCollation cmp_collation;
1147
1136
  enum_field_types cached_field_type;
1148
 
  cmp_item *cmp_items[DECIMAL_RESULT+1]; /* For all result types */
 
1137
  cmp_item *cmp_items[5]; /* For all result types */
1149
1138
  cmp_item *case_item;
1150
1139
public:
1151
1140
  Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
1169
1158
  double val_real();
1170
1159
  int64_t val_int();
1171
1160
  String *val_str(String *);
1172
 
  type::Decimal *val_decimal(type::Decimal *);
1173
 
  bool fix_fields(Session *session, Item **ref);
 
1161
  my_decimal *val_decimal(my_decimal *);
 
1162
  bool fix_fields(THD *thd, Item **ref);
1174
1163
  void fix_length_and_dec();
1175
1164
  uint32_t decimal_precision() const;
1176
1165
  table_map not_null_tables() const { return 0; }
1202
1191
class Item_func_in :public Item_func_opt_neg
1203
1192
{
1204
1193
public:
1205
 
  /*
 
1194
  /* 
1206
1195
    an array of values when the right hand arguments of IN
1207
 
    are all SQL constant and there are no nulls
 
1196
    are all SQL constant and there are no nulls 
1208
1197
  */
1209
1198
  in_vector *array;
1210
1199
  bool have_null;
1211
 
  /*
 
1200
  /* 
1212
1201
    true when all arguments of the IN clause are of compatible types
1213
1202
    and can be used safely as comparisons for key conditions
1214
1203
  */
1225
1214
    allowed_arg_cols= 0;  // Fetch this value from first argument
1226
1215
  }
1227
1216
  int64_t val_int();
1228
 
  bool fix_fields(Session *, Item **);
 
1217
  bool fix_fields(THD *, Item **);
1229
1218
  void fix_length_and_dec();
1230
1219
  uint32_t decimal_precision() const { return 1; }
1231
1220
  void cleanup()
1232
1221
  {
 
1222
    uint32_t i;
1233
1223
    Item_int_func::cleanup();
1234
1224
    delete array;
1235
1225
    array= 0;
1236
 
    for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
1226
    for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
1237
1227
    {
1238
1228
      delete cmp_items[i];
1239
1229
      cmp_items[i]= 0;
1281
1271
 
1282
1272
/* Functions used by where clause */
1283
1273
 
1284
 
class Item_func_isnull :public item::function::Boolean
 
1274
class Item_func_isnull :public Item_bool_func
1285
1275
{
1286
1276
protected:
1287
1277
  int64_t cached_value;
1288
1278
public:
1289
 
  Item_func_isnull(Item *a) :item::function::Boolean(a) {}
 
1279
  Item_func_isnull(Item *a) :Item_bool_func(a) {}
1290
1280
  int64_t val_int();
1291
1281
  enum Functype functype() const { return ISNULL_FUNC; }
1292
1282
  void fix_length_and_dec()
1317
1307
  }
1318
1308
  table_map not_null_tables() const { return 0; }
1319
1309
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1320
 
  Item *neg_transformer(Session *session);
 
1310
  Item *neg_transformer(THD *thd);
1321
1311
  const CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1322
1312
};
1323
1313
 
1325
1315
 
1326
1316
class Item_in_subselect;
1327
1317
 
1328
 
/*
 
1318
/* 
1329
1319
  This is like IS NOT NULL but it also remembers if it ever has
1330
1320
  encountered a NULL.
1331
1321
*/
1348
1338
};
1349
1339
 
1350
1340
 
1351
 
class Item_func_isnotnull :public item::function::Boolean
 
1341
class Item_func_isnotnull :public Item_bool_func
1352
1342
{
1353
1343
  bool abort_on_null;
1354
1344
public:
1355
 
  Item_func_isnotnull(Item *a) :item::function::Boolean(a), abort_on_null(0) {}
 
1345
  Item_func_isnotnull(Item *a) :Item_bool_func(a), abort_on_null(0) {}
1356
1346
  int64_t val_int();
1357
1347
  enum Functype functype() const { return ISNOTNULL_FUNC; }
1358
1348
  void fix_length_and_dec()
1363
1353
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1364
1354
  table_map not_null_tables() const
1365
1355
  { return abort_on_null ? not_null_tables_cache : 0; }
1366
 
  Item *neg_transformer(Session *session);
 
1356
  Item *neg_transformer(THD *thd);
1367
1357
  virtual void print(String *str, enum_query_type query_type);
1368
1358
  const CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1369
1359
  void top_level_item() { abort_on_null=1; }
1388
1378
  enum { alphabet_size = 256 };
1389
1379
 
1390
1380
  Item *escape_item;
1391
 
 
 
1381
  
1392
1382
  bool escape_used_in_parsing;
1393
1383
 
1394
 
 
1395
1384
public:
1396
 
 
1397
 
  char *escape;
 
1385
  int escape;
1398
1386
 
1399
1387
  Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
1400
 
    :Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0),
 
1388
    :Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0), 
1401
1389
     bmGs(0), bmBc(0), escape_item(escape_arg),
1402
 
     escape_used_in_parsing(escape_used), escape(NULL) {}
 
1390
     escape_used_in_parsing(escape_used) {}
1403
1391
  int64_t val_int();
1404
1392
  enum Functype functype() const { return LIKE_FUNC; }
1405
1393
  optimize_type select_optimize() const;
1406
1394
  cond_result eq_cmp_result() const { return COND_TRUE; }
1407
1395
  const char *func_name() const { return "like"; }
1408
 
  bool fix_fields(Session *session, Item **ref);
 
1396
  bool fix_fields(THD *thd, Item **ref);
1409
1397
  void cleanup();
1410
1398
};
1411
1399
 
1412
1400
 
1413
1401
typedef class Item COND;
1414
1402
 
1415
 
class Item_cond :public item::function::Boolean
 
1403
class Item_cond :public Item_bool_func
1416
1404
{
1417
1405
protected:
1418
1406
  List<Item> list;
1420
1408
  table_map and_tables_cache;
1421
1409
 
1422
1410
public:
1423
 
 
1424
 
  using Item::split_sum_func;
1425
 
 
1426
1411
  /* Item_cond() is only used to create top level items */
1427
 
  Item_cond(): item::function::Boolean(), abort_on_null(1)
 
1412
  Item_cond(): Item_bool_func(), abort_on_null(1)
1428
1413
  { const_item_cache=0; }
1429
1414
  Item_cond(Item *i1,Item *i2)
1430
 
    :item::function::Boolean(), abort_on_null(0)
 
1415
    :Item_bool_func(), abort_on_null(0)
1431
1416
  {
1432
1417
    list.push_back(i1);
1433
1418
    list.push_back(i2);
1434
1419
  }
1435
 
  Item_cond(Session *session, Item_cond *item);
 
1420
  Item_cond(THD *thd, Item_cond *item);
1436
1421
  Item_cond(List<Item> &nlist)
1437
 
    :item::function::Boolean(), list(nlist), abort_on_null(0) {}
 
1422
    :Item_bool_func(), list(nlist), abort_on_null(0) {}
1438
1423
  bool add(Item *item) { return list.push_back(item); }
1439
1424
  bool add_at_head(Item *item) { return list.push_front(item); }
1440
1425
  void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
1441
 
  bool fix_fields(Session *, Item **ref);
1442
 
  void fix_after_pullout(Select_Lex *new_parent, Item **ref);
 
1426
  bool fix_fields(THD *, Item **ref);
 
1427
  void fix_after_pullout(st_select_lex *new_parent, Item **ref);
1443
1428
 
1444
1429
  enum Type type() const { return COND_ITEM; }
1445
1430
  List<Item>* argument_list() { return &list; }
1446
1431
  table_map used_tables() const;
1447
1432
  void update_used_tables();
1448
1433
  virtual void print(String *str, enum_query_type query_type);
1449
 
  void split_sum_func(Session *session, Item **ref_pointer_array, List<Item> &fields);
1450
 
  friend int setup_conds(Session *session, TableList *tables, TableList *leaves,
 
1434
  void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
 
1435
  friend int setup_conds(THD *thd, TableList *tables, TableList *leaves,
1451
1436
                         COND **conds);
1452
1437
  void top_level_item() { abort_on_null=1; }
1453
 
  void copy_andor_arguments(Session *session, Item_cond *item);
 
1438
  void copy_andor_arguments(THD *thd, Item_cond *item);
1454
1439
  bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1455
1440
  Item *transform(Item_transformer transformer, unsigned char *arg);
1456
1441
  void traverse_cond(Cond_traverser, void *arg, traverse_order order);
1457
 
  void neg_arguments(Session *session);
 
1442
  void neg_arguments(THD *thd);
1458
1443
  enum_field_types field_type() const { return DRIZZLE_TYPE_LONGLONG; }
1459
 
  bool subst_argument_checker(unsigned char **)
 
1444
  bool subst_argument_checker(unsigned char **arg __attribute__((unused)))
1460
1445
  { return true; }
1461
1446
  Item *compile(Item_analyzer analyzer, unsigned char **arg_p,
1462
1447
                Item_transformer transformer, unsigned char *arg_t);
1480
1465
  A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
1481
1466
  substituted for the item representing the same multiple equality
1482
1467
  f1=f2=f3.
1483
 
  An item Item_equal(f1,f2) can appear instead of a conjunction of
 
1468
  An item Item_equal(f1,f2) can appear instead of a conjunction of 
1484
1469
  f2=f1 and f1=f2, or instead of just the predicate f1=f2.
1485
1470
 
1486
 
  An item of the class Item_equal inherits equalities from outer
 
1471
  An item of the class Item_equal inherits equalities from outer 
1487
1472
  conjunctive levels.
1488
1473
 
1489
1474
  Suppose we have a where condition of the following form:
1494
1479
    f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
1495
1480
 
1496
1481
  An object of the class Item_equal can contain an optional constant
1497
 
  item c. Then it represents a multiple equality of the form
 
1482
  item c. Then it represents a multiple equality of the form 
1498
1483
  c=f1=...=fk.
1499
1484
 
1500
1485
  Objects of the class Item_equal are used for the following:
1509
1494
  It also can give us additional index scans and can allow us to
1510
1495
  improve selectivity estimates.
1511
1496
 
1512
 
  3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
1513
 
  selected execution plan for the query: if table ti is accessed
 
1497
  3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the 
 
1498
  selected execution plan for the query: if table ti is accessed 
1514
1499
  before the table tj then in any predicate P in the where condition
1515
1500
  the occurrence of tj.fj is substituted for ti.fi. This can allow
1516
1501
  an evaluation of the predicate at an earlier step.
1517
1502
 
1518
 
  When feature 1 is supported they say that join transitive closure
 
1503
  When feature 1 is supported they say that join transitive closure 
1519
1504
  is employed.
1520
1505
  When feature 2 is supported they say that search argument transitive
1521
1506
  closure is employed.
1524
1509
  We do not just add predicates, we rather dynamically replace some
1525
1510
  predicates that can not be used to access tables in the investigated
1526
1511
  plan for those, obtained by substitution of some fields for equal fields,
1527
 
  that can be used.
 
1512
  that can be used.     
1528
1513
 
1529
1514
  Prepared Statements/Stored Procedures note: instances of class
1530
1515
  Item_equal are created only at the time a PS/SP is executed and
1538
1523
  object represents f1=f2= ...=fn to the projection of known fields fi1=...=fik.
1539
1524
*/
1540
1525
 
1541
 
class Item_equal: public item::function::Boolean
 
1526
class Item_equal: public Item_bool_func
1542
1527
{
 
1528
  List<Item_field> fields; /* list of equal field items                    */
 
1529
  Item *const_item;        /* optional constant item equal to fields items */
 
1530
  cmp_item *eval_item;
 
1531
  bool cond_false;
1543
1532
public:
1544
 
  typedef List<Item_field> fields_t;
1545
 
 
1546
 
  Item_equal() :
1547
 
    const_item(0),
1548
 
    eval_item(0),
1549
 
    cond_false(0)
1550
 
  {
1551
 
    const_item_cache=0;
1552
 
  }
1553
 
 
1554
 
  fields_t::iterator begin()
1555
 
  {
1556
 
    return fields.begin();
1557
 
  }
1558
 
 
 
1533
  inline Item_equal()
 
1534
    : Item_bool_func(), const_item(0), eval_item(0), cond_false(0)
 
1535
  { const_item_cache=0 ;}
1559
1536
  Item_equal(Item_field *f1, Item_field *f2);
1560
1537
  Item_equal(Item *c, Item_field *f);
1561
1538
  Item_equal(Item_equal *item_equal);
1568
1545
  void merge(Item_equal *item);
1569
1546
  void update_const();
1570
1547
  enum Functype functype() const { return MULT_EQUAL_FUNC; }
1571
 
  int64_t val_int();
 
1548
  int64_t val_int(); 
1572
1549
  const char *func_name() const { return "multiple equal"; }
1573
1550
  optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
1574
1551
  void sort(Item_field_cmpfunc cmp, void *arg);
1575
1552
  friend class Item_equal_iterator;
1576
1553
  void fix_length_and_dec();
1577
 
  bool fix_fields(Session *session, Item **ref);
 
1554
  bool fix_fields(THD *thd, Item **ref);
1578
1555
  void update_used_tables();
1579
1556
  bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1580
1557
  Item *transform(Item_transformer transformer, unsigned char *arg);
1581
1558
  virtual void print(String *str, enum_query_type query_type);
1582
 
  const CHARSET_INFO *compare_collation()
 
1559
  const CHARSET_INFO *compare_collation() 
1583
1560
  { return fields.head()->collation.collation; }
1584
 
private:
1585
 
  fields_t fields; /* list of equal field items                    */
1586
 
  Item *const_item;        /* optional constant item equal to fields items */
1587
 
  cmp_item *eval_item;
1588
 
  bool cond_false;
1589
 
 
1590
 
};
1591
 
 
1592
 
class COND_EQUAL: public memory::SqlAlloc
 
1561
}; 
 
1562
 
 
1563
class COND_EQUAL: public Sql_alloc
1593
1564
{
1594
1565
public:
1595
1566
  uint32_t max_members;               /* max number of members the current level
1596
 
                                     list and all lower level lists */
 
1567
                                     list and all lower level lists */ 
1597
1568
  COND_EQUAL *upper_levels;       /* multiple equalities of upper and levels */
1598
 
  List<Item_equal> current_level; /* list of multiple equalities of
 
1569
  List<Item_equal> current_level; /* list of multiple equalities of 
1599
1570
                                     the current and level           */
1600
1571
  COND_EQUAL()
1601
 
  {
 
1572
  { 
1602
1573
    upper_levels= 0;
1603
1574
  }
1604
1575
};
1605
1576
 
1606
1577
 
1607
 
class Item_equal_iterator : public List<Item_field>::iterator
 
1578
class Item_equal_iterator : public List_iterator_fast<Item_field>
1608
1579
{
1609
1580
public:
1610
 
  inline Item_equal_iterator(Item_equal &item_equal)
1611
 
    :List<Item_field>::iterator (item_equal.fields.begin() )
 
1581
  inline Item_equal_iterator(Item_equal &item_equal) 
 
1582
    :List_iterator_fast<Item_field> (item_equal.fields)
1612
1583
  {}
1613
1584
  inline Item_field* operator++(int)
1614
 
  {
1615
 
    Item_field *item= (*(List<Item_field>::iterator *) this)++;
 
1585
  { 
 
1586
    Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
1616
1587
    return  item;
1617
1588
  }
 
1589
  inline void rewind(void) 
 
1590
  { 
 
1591
    List_iterator_fast<Item_field>::rewind();
 
1592
  }
1618
1593
};
1619
1594
 
1620
1595
class Item_cond_and :public Item_cond
1621
1596
{
1622
1597
public:
1623
 
  COND_EQUAL cond_equal;  /* contains list of Item_equal objects for
 
1598
  COND_EQUAL cond_equal;  /* contains list of Item_equal objects for 
1624
1599
                             the current and level and reference
1625
 
                             to multiple equalities of upper and levels */
 
1600
                             to multiple equalities of upper and levels */  
1626
1601
  Item_cond_and() :Item_cond() {}
1627
1602
  Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1628
 
  Item_cond_and(Session *session, Item_cond_and *item) :Item_cond(session, item) {}
 
1603
  Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
1629
1604
  Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
1630
1605
  enum Functype functype() const { return COND_AND_FUNC; }
1631
1606
  int64_t val_int();
1632
1607
  const char *func_name() const { return "and"; }
1633
1608
  table_map not_null_tables() const
1634
1609
  { return abort_on_null ? not_null_tables_cache: and_tables_cache; }
1635
 
  Item* copy_andor_structure(Session *session)
 
1610
  Item* copy_andor_structure(THD *thd)
1636
1611
  {
1637
1612
    Item_cond_and *item;
1638
 
    if ((item= new Item_cond_and(session, this)))
1639
 
       item->copy_andor_arguments(session, this);
 
1613
    if ((item= new Item_cond_and(thd, this)))
 
1614
       item->copy_andor_arguments(thd, this);
1640
1615
    return item;
1641
1616
  }
1642
 
  Item *neg_transformer(Session *session);
 
1617
  Item *neg_transformer(THD *thd);
1643
1618
};
1644
1619
 
1645
1620
inline bool is_cond_and(Item *item)
1656
1631
public:
1657
1632
  Item_cond_or() :Item_cond() {}
1658
1633
  Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1659
 
  Item_cond_or(Session *session, Item_cond_or *item) :Item_cond(session, item) {}
 
1634
  Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
1660
1635
  Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
1661
1636
  enum Functype functype() const { return COND_OR_FUNC; }
1662
1637
  int64_t val_int();
1663
1638
  const char *func_name() const { return "or"; }
1664
1639
  table_map not_null_tables() const { return and_tables_cache; }
1665
 
  Item* copy_andor_structure(Session *session)
 
1640
  Item* copy_andor_structure(THD *thd)
1666
1641
  {
1667
1642
    Item_cond_or *item;
1668
 
    if ((item= new Item_cond_or(session, this)))
1669
 
      item->copy_andor_arguments(session, this);
 
1643
    if ((item= new Item_cond_or(thd, this)))
 
1644
      item->copy_andor_arguments(thd, this);
1670
1645
    return item;
1671
1646
  }
1672
 
  Item *neg_transformer(Session *session);
 
1647
  Item *neg_transformer(THD *thd);
1673
1648
};
1674
1649
 
1675
1650
inline bool is_cond_or(Item *item)
1699
1674
  void top_level_item() {}
1700
1675
};
1701
1676
 
1702
 
enum_field_types agg_field_type(Item **items, uint32_t nitems);
1703
 
 
1704
1677
 
1705
1678
/* Some useful inline functions */
1706
1679
 
1712
1685
}
1713
1686
 
1714
1687
Item *and_expressions(Item *a, Item *b, Item **org_item);
1715
 
 
1716
 
} /* namespace drizzled */
1717
 
 
1718
 
#endif /* DRIZZLED_ITEM_CMPFUNC_H */