~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item_cmpfunc.h

  • Committer: Stewart Smith
  • Date: 2008-10-15 04:21:24 UTC
  • mto: This revision was merged to the branch mainline in revision 516.
  • Revision ID: stewart@flamingspork.com-20081015042124-kdmb74bcbky1k1nz
remove my_pthread_[gs]etspecific

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