~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.h

  • Committer: Monty Taylor
  • Date: 2009-03-24 17:44:41 UTC
  • mto: (960.5.2 mordred)
  • mto: This revision was merged to the branch mainline in revision 964.
  • Revision ID: mordred@inaugust.com-20090324174441-nmsq0gwjlgf7f0mt
Changed handlerton to StorageEngine.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
20
22
 
21
23
/* compare and test functions */
22
24
 
23
 
#ifdef USE_PRAGMA_INTERFACE
24
 
#pragma interface                       /* gcc class implementation */
25
 
#endif
 
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"
26
34
 
27
35
extern Item_result item_cmp_type(Item_result a,Item_result b);
28
36
class Item_bool_func2;
29
37
class Arg_comparator;
 
38
class Item_sum_hybrid;
 
39
class Item_row;
30
40
 
31
41
typedef int (Arg_comparator::*arg_cmp_func)();
32
42
 
33
 
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg); 
 
43
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
34
44
 
35
45
class Arg_comparator: public Sql_alloc
36
46
{
40
50
  Arg_comparator *comparators;   // used only for compare_row()
41
51
  double precision;
42
52
  /* Fields used in DATE/DATETIME comparison. */
43
 
  THD *thd;
 
53
  Session *session;
44
54
  enum_field_types a_type, b_type; // Types of a and b items
45
55
  Item *a_cache, *b_cache;         // Cached values of a and b items
46
56
  bool is_nulls_eq;                // TRUE <=> compare for the EQUAL_FUNC
47
57
  enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
48
58
                            CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
49
 
  uint64_t (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg,
 
59
  uint64_t (*get_value_func)(Session *session, Item ***item_arg, Item **cache_arg,
50
60
                              Item *warn_item, bool *is_null);
51
61
public:
52
62
  DTCollation cmp_collation;
53
63
 
54
 
  Arg_comparator(): thd(0), a_cache(0), b_cache(0) {};
55
 
  Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), thd(0),
 
64
  Arg_comparator(): session(0), a_cache(0), b_cache(0) {};
 
65
  Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), session(0),
56
66
    a_cache(0), b_cache(0) {};
57
67
 
58
68
  int set_compare_func(Item_bool_func2 *owner, Item_result type);
109
119
  Item_bool_func() :Item_int_func() {}
110
120
  Item_bool_func(Item *a) :Item_int_func(a) {}
111
121
  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) {}
 
122
  Item_bool_func(Session *session, Item_bool_func *item) :Item_int_func(session, item) {}
113
123
  bool is_bool_func() { return 1; }
114
124
  void fix_length_and_dec() { decimals=0; max_length=1; }
115
125
  uint32_t decimal_precision() const { return 1; }
225
235
protected:
226
236
  Item_cache *cache;
227
237
  bool save_cache;
228
 
  /* 
 
238
  /*
229
239
    Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
230
240
      UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
231
241
      FALSE   - result is FALSE
237
247
    Item_bool_func(a, reinterpret_cast<Item *>(b)), cache(0),
238
248
    save_cache(0), result_for_null_param(UNKNOWN)
239
249
  { with_subselect= true; }
240
 
  bool fix_fields(THD *, Item **);
241
 
  bool fix_left(THD *thd, Item **ref);
 
250
  bool fix_fields(Session *, Item **);
 
251
  bool fix_left(Session *session, Item **ref);
242
252
  bool is_null();
243
253
  int64_t val_int();
244
254
  void cleanup();
248
258
  Item *transform(Item_transformer transformer, unsigned char *arg);
249
259
};
250
260
 
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
 
 
262
261
class Eq_creator :public Comp_creator
263
262
{
264
263
public:
268
267
  virtual const char* symbol(bool invert) const { return invert? "<>" : "="; }
269
268
  virtual bool eqne_op() const { return 1; }
270
269
  virtual bool l_op() const { return 0; }
 
270
  static const Eq_creator *instance();
271
271
};
272
272
 
273
273
class Ne_creator :public Comp_creator
279
279
  virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; }
280
280
  virtual bool eqne_op() const { return 1; }
281
281
  virtual bool l_op() const { return 0; }
 
282
  static const Ne_creator *instance();
282
283
};
283
284
 
284
285
class Gt_creator :public Comp_creator
290
291
  virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
291
292
  virtual bool eqne_op() const { return 0; }
292
293
  virtual bool l_op() const { return 0; }
 
294
  static const Gt_creator *instance();
293
295
};
294
296
 
295
297
class Lt_creator :public Comp_creator
301
303
  virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
302
304
  virtual bool eqne_op() const { return 0; }
303
305
  virtual bool l_op() const { return 1; }
 
306
  static const Lt_creator *instance();
304
307
};
305
308
 
306
309
class Ge_creator :public Comp_creator
312
315
  virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
313
316
  virtual bool eqne_op() const { return 0; }
314
317
  virtual bool l_op() const { return 0; }
 
318
  static const Ge_creator *instance();
315
319
};
316
320
 
317
321
class Le_creator :public Comp_creator
323
327
  virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
324
328
  virtual bool eqne_op() const { return 0; }
325
329
  virtual bool l_op() const { return 1; }
 
330
  static const Le_creator *instance();
326
331
};
327
332
 
328
333
class Item_bool_func2 :public Item_int_func
365
370
  {
366
371
    allowed_arg_cols= 0;  // Fetch this value from first argument
367
372
  }
368
 
  Item *neg_transformer(THD *thd);
 
373
  Item *neg_transformer(Session *session);
369
374
  virtual Item *negated_item();
370
 
  bool subst_argument_checker(unsigned char **arg __attribute__((unused)))
 
375
  bool subst_argument_checker(unsigned char **)
371
376
  { return true; }
372
377
};
373
378
 
378
383
  int64_t val_int();
379
384
  enum Functype functype() const { return NOT_FUNC; }
380
385
  const char *func_name() const { return "not"; }
381
 
  Item *neg_transformer(THD *thd);
 
386
  Item *neg_transformer(Session *session);
382
387
  virtual void print(String *str, enum_query_type query_type);
383
388
};
384
389
 
387
392
/*
388
393
  trigcond<param>(arg) ::= param? arg : TRUE
389
394
 
390
 
  The class Item_func_trig_cond is used for guarded predicates 
 
395
  The class Item_func_trig_cond is used for guarded predicates
391
396
  which are employed only for internal purposes.
392
397
  A guarded predicate is an object consisting of an a regular or
393
 
  a guarded predicate P and a pointer to a boolean guard variable g. 
 
398
  a guarded predicate P and a pointer to a boolean guard variable g.
394
399
  A guarded predicate P/g is evaluated to true if the value of the
395
400
  guard g is false, otherwise it is evaluated to the same value that
396
401
  the predicate P: val(P/g)= g ? val(P):true.
402
407
  the objects consisting of three elements: a predicate P, a pointer
403
408
  to a variable g and a firing value s with following evaluation
404
409
  rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
405
 
  one item for the objects of the form P/g1/g2... 
 
410
  one item for the objects of the form P/g1/g2...
406
411
 
407
412
  Objects of this class are built only for query execution after
408
413
  the execution plan has been already selected. That's why this
409
 
  class needs only val_int out of generic methods. 
410
 
 
 
414
  class needs only val_int out of generic methods.
 
415
 
411
416
  Current uses of Item_func_trig_cond objects:
412
417
   - To wrap selection conditions when executing outer joins
413
418
   - To wrap condition that is pushed down into subquery
450
455
  void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
451
456
  void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
452
457
  bool empty_underlying_subquery();
453
 
  Item *neg_transformer(THD *thd);
 
458
  Item *neg_transformer(Session *session);
454
459
};
455
460
 
456
461
 
461
466
  Item_func_nop_all(Item *a) :Item_func_not_all(a) {}
462
467
  int64_t val_int();
463
468
  const char *func_name() const { return "<nop>"; }
464
 
  Item *neg_transformer(THD *thd);
 
469
  Item *neg_transformer(Session *session);
465
470
};
466
471
 
467
472
 
488
493
  enum Functype rev_functype() const { return EQUAL_FUNC; }
489
494
  cond_result eq_cmp_result() const { return COND_TRUE; }
490
495
  const char *func_name() const { return "<=>"; }
491
 
  Item *neg_transformer(THD *thd __attribute__((unused))) { return 0; }
 
496
  Item *neg_transformer(Session *) { return 0; }
492
497
};
493
498
 
494
499
 
551
556
  int64_t val_int();
552
557
  enum Functype functype() const { return NE_FUNC; }
553
558
  cond_result eq_cmp_result() const { return COND_FALSE; }
554
 
  optimize_type select_optimize() const { return OPTIMIZE_KEY; } 
 
559
  optimize_type select_optimize() const { return OPTIMIZE_KEY; }
555
560
  const char *func_name() const { return "<>"; }
556
561
  Item *negated_item();
557
562
};
579
584
public:
580
585
  inline void negate() { negated= !negated; }
581
586
  inline void top_level_item() { pred_level= 1; }
582
 
  Item *neg_transformer(THD *thd __attribute__((unused)))
 
587
  Item *neg_transformer(Session *)
583
588
  {
584
589
    negated= !negated;
585
590
    return this;
586
591
  }
587
592
  bool eq(const Item *item, bool binary_cmp) const;
588
 
  bool subst_argument_checker(unsigned char **arg __attribute__((unused)))
 
593
  bool subst_argument_checker(unsigned char **)
589
594
  { return true; }
590
595
};
591
596
 
606
611
  optimize_type select_optimize() const { return OPTIMIZE_KEY; }
607
612
  enum Functype functype() const   { return BETWEEN; }
608
613
  const char *func_name() const { return "between"; }
609
 
  bool fix_fields(THD *, Item **);
 
614
  bool fix_fields(Session *, Item **);
610
615
  void fix_length_and_dec();
611
616
  virtual void print(String *str, enum_query_type query_type);
612
617
  bool is_bool_func() { return 1; }
688
693
  enum_field_types field_type() const;
689
694
  void fix_length_and_dec();
690
695
  const char *func_name() const { return "ifnull"; }
 
696
  Field *tmp_table_field()
 
697
  {
 
698
    return Item_func::tmp_table_field();
 
699
  }
691
700
  Field *tmp_table_field(Table *table);
692
701
  uint32_t decimal_precision() const;
693
702
};
707
716
  my_decimal *val_decimal(my_decimal *);
708
717
  enum Item_result result_type () const { return cached_result_type; }
709
718
  enum_field_types field_type() const { return cached_field_type; }
710
 
  bool fix_fields(THD *, Item **);
 
719
  bool fix_fields(Session *, Item **);
711
720
  void fix_length_and_dec();
712
721
  uint32_t decimal_precision() const;
713
722
  const char *func_name() const { return "if"; }
755
764
  uint32_t count;
756
765
  uint32_t used_count;
757
766
  in_vector() {}
758
 
  in_vector(uint32_t elements,uint32_t element_length,qsort2_cmp cmp_func, 
 
767
  in_vector(uint32_t elements,uint32_t element_length,qsort2_cmp cmp_func,
759
768
            const CHARSET_INFO * const cmp_coll)
760
769
    :base((char*) sql_calloc(elements*element_length)),
761
770
     size(element_length), compare(cmp_func), collation(cmp_coll),
768
777
    my_qsort2(base,used_count,size,compare, (void *) collation);
769
778
  }
770
779
  int find(Item *item);
771
 
  
772
 
  /* 
 
780
 
 
781
  /*
773
782
    Create an instance of Item_{type} (e.g. Item_decimal) constant object
774
783
    which type allows it to hold an element of this vector without any
775
784
    conversions.
778
787
    for every array element you get (i.e. this implements "FlyWeight" pattern)
779
788
  */
780
789
  virtual Item* create_item() { return NULL; }
781
 
  
 
790
 
782
791
  /*
783
792
    Store the value at position #pos into provided item object
784
793
    SYNOPSIS
787
796
        item  Constant item to store value into. The item must be of the same
788
797
              type that create_item() returns.
789
798
  */
790
 
  virtual void value_to_item(uint32_t pos __attribute__((unused)),
791
 
                             Item *item __attribute__((unused))) { }
792
 
  
 
799
  virtual void value_to_item(uint32_t, Item *) { }
 
800
 
793
801
  /* Compare values number pos1 and pos2 for equality */
794
802
  bool compare_elems(uint32_t pos1, uint32_t pos2)
795
803
  {
808
816
  void set(uint32_t pos,Item *item);
809
817
  unsigned char *get_value(Item *item);
810
818
  Item* create_item()
811
 
  { 
 
819
  {
812
820
    return new Item_string(collation);
813
821
  }
814
822
  void value_to_item(uint32_t pos, Item *item)
815
 
  {    
 
823
  {
816
824
    String *str=((String*) base)+pos;
817
825
    Item_string *to= (Item_string*)item;
818
826
    to->str_value= *str;
825
833
protected:
826
834
  /*
827
835
    Here we declare a temporary variable (tmp) of the same type as the
828
 
    elements of this vector. tmp is used in finding if a given value is in 
829
 
    the list. 
 
836
    elements of this vector. tmp is used in finding if a given value is in
 
837
    the list.
830
838
  */
831
 
  struct packed_int64_t 
 
839
  struct packed_int64_t
832
840
  {
833
841
    int64_t val;
834
842
    int64_t unsigned_flag;  // Use int64_t, not bool, to preserve alignment
837
845
  in_int64_t(uint32_t elements);
838
846
  void set(uint32_t pos,Item *item);
839
847
  unsigned char *get_value(Item *item);
840
 
  
 
848
 
841
849
  Item* create_item()
842
 
  { 
843
 
    /* 
844
 
      We're created a signed INT, this may not be correct in 
 
850
  {
 
851
    /*
 
852
      We're created a signed INT, this may not be correct in
845
853
      general case (see BUG#19342).
846
854
    */
847
855
    return new Item_int((int64_t)0);
867
875
class in_datetime :public in_int64_t
868
876
{
869
877
public:
870
 
  THD *thd;
 
878
  Session *session;
871
879
  /* An item used to issue warnings. */
872
880
  Item *warn_item;
873
881
  /* Cache for the left item. */
874
882
  Item *lval_cache;
875
883
 
876
884
  in_datetime(Item *warn_item_arg, uint32_t elements)
877
 
    :in_int64_t(elements), thd(current_thd), warn_item(warn_item_arg),
 
885
    :in_int64_t(elements), session(current_session), warn_item(warn_item_arg),
878
886
     lval_cache(0) {};
879
887
  void set(uint32_t pos,Item *item);
880
888
  unsigned char *get_value(Item *item);
890
898
  void set(uint32_t pos,Item *item);
891
899
  unsigned char *get_value(Item *item);
892
900
  Item *create_item()
893
 
  { 
 
901
  {
894
902
    return new Item_float(0.0, 0);
895
903
  }
896
904
  void value_to_item(uint32_t pos, Item *item)
909
917
  void set(uint32_t pos, Item *item);
910
918
  unsigned char *get_value(Item *item);
911
919
  Item *create_item()
912
 
  { 
 
920
  {
913
921
    return new Item_decimal(0, false);
914
922
  }
915
923
  void value_to_item(uint32_t pos, Item *item)
939
947
  virtual int compare(cmp_item *item)= 0;
940
948
  static cmp_item* get_comparator(Item_result type, const CHARSET_INFO * const cs);
941
949
  virtual cmp_item *make_same()= 0;
942
 
  virtual void store_value_by_template(cmp_item *tmpl  __attribute__((unused)),
943
 
                                       Item *item)
 
950
  virtual void store_value_by_template(cmp_item *, Item *item)
944
951
  {
945
952
    store_value(item);
946
953
  }
947
954
};
948
955
 
949
 
class cmp_item_string :public cmp_item 
 
956
class cmp_item_string :public cmp_item
950
957
{
951
958
protected:
952
959
  String *value_res;
985
992
  {
986
993
    cmp_item_string *l_cmp= (cmp_item_string *) ci;
987
994
    return sortcmp(value_res, l_cmp->value_res, cmp_charset);
988
 
  } 
 
995
  }
989
996
  cmp_item *make_same();
990
997
  void set_charset(const CHARSET_INFO * const cs)
991
998
  {
1025
1032
{
1026
1033
  uint64_t value;
1027
1034
public:
1028
 
  THD *thd;
 
1035
  Session *session;
1029
1036
  /* Item used for issuing warnings. */
1030
1037
  Item *warn_item;
1031
1038
  /* Cache for the left item. */
1032
1039
  Item *lval_cache;
1033
1040
 
1034
1041
  cmp_item_datetime(Item *warn_item_arg)
1035
 
    :thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
 
1042
    :session(current_session), warn_item(warn_item_arg), lval_cache(0) {}
1036
1043
  void store_value(Item *item);
1037
1044
  int cmp(Item *arg);
1038
1045
  int compare(cmp_item *ci);
1073
1080
};
1074
1081
 
1075
1082
 
1076
 
/* 
 
1083
/*
1077
1084
   cmp_item for optimized IN with row (right part string, which never
1078
1085
   be changed)
1079
1086
*/
1089
1096
  {
1090
1097
    value_res= item->val_str(&value);
1091
1098
  }
1092
 
  int cmp(Item *item __attribute__((unused)))
 
1099
  int cmp(Item *)
1093
1100
  {
1094
1101
    // Should never be called
1095
1102
    assert(0);
1111
1118
  The class Item_func_case is the CASE ... WHEN ... THEN ... END function
1112
1119
  implementation.
1113
1120
 
1114
 
  When there is no expression between CASE and the first WHEN 
 
1121
  When there is no expression between CASE and the first WHEN
1115
1122
  (the CASE expression) then this function simple checks all WHEN expressions
1116
1123
  one after another. When some WHEN expression evaluated to TRUE then the
1117
1124
  value of the corresponding THEN expression is returned.
1159
1166
  int64_t val_int();
1160
1167
  String *val_str(String *);
1161
1168
  my_decimal *val_decimal(my_decimal *);
1162
 
  bool fix_fields(THD *thd, Item **ref);
 
1169
  bool fix_fields(Session *session, Item **ref);
1163
1170
  void fix_length_and_dec();
1164
1171
  uint32_t decimal_precision() const;
1165
1172
  table_map not_null_tables() const { return 0; }
1191
1198
class Item_func_in :public Item_func_opt_neg
1192
1199
{
1193
1200
public:
1194
 
  /* 
 
1201
  /*
1195
1202
    an array of values when the right hand arguments of IN
1196
 
    are all SQL constant and there are no nulls 
 
1203
    are all SQL constant and there are no nulls
1197
1204
  */
1198
1205
  in_vector *array;
1199
1206
  bool have_null;
1200
 
  /* 
 
1207
  /*
1201
1208
    true when all arguments of the IN clause are of compatible types
1202
1209
    and can be used safely as comparisons for key conditions
1203
1210
  */
1214
1221
    allowed_arg_cols= 0;  // Fetch this value from first argument
1215
1222
  }
1216
1223
  int64_t val_int();
1217
 
  bool fix_fields(THD *, Item **);
 
1224
  bool fix_fields(Session *, Item **);
1218
1225
  void fix_length_and_dec();
1219
1226
  uint32_t decimal_precision() const { return 1; }
1220
1227
  void cleanup()
1223
1230
    Item_int_func::cleanup();
1224
1231
    delete array;
1225
1232
    array= 0;
1226
 
    for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
 
1233
    for (i= 0; i <= (uint32_t)DECIMAL_RESULT + 1; i++)
1227
1234
    {
1228
1235
      delete cmp_items[i];
1229
1236
      cmp_items[i]= 0;
1307
1314
  }
1308
1315
  table_map not_null_tables() const { return 0; }
1309
1316
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1310
 
  Item *neg_transformer(THD *thd);
 
1317
  Item *neg_transformer(Session *session);
1311
1318
  const CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1312
1319
};
1313
1320
 
1315
1322
 
1316
1323
class Item_in_subselect;
1317
1324
 
1318
 
/* 
 
1325
/*
1319
1326
  This is like IS NOT NULL but it also remembers if it ever has
1320
1327
  encountered a NULL.
1321
1328
*/
1353
1360
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1354
1361
  table_map not_null_tables() const
1355
1362
  { return abort_on_null ? not_null_tables_cache : 0; }
1356
 
  Item *neg_transformer(THD *thd);
 
1363
  Item *neg_transformer(Session *session);
1357
1364
  virtual void print(String *str, enum_query_type query_type);
1358
1365
  const CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1359
1366
  void top_level_item() { abort_on_null=1; }
1378
1385
  enum { alphabet_size = 256 };
1379
1386
 
1380
1387
  Item *escape_item;
1381
 
  
 
1388
 
1382
1389
  bool escape_used_in_parsing;
1383
1390
 
1384
1391
public:
1385
1392
  int escape;
1386
1393
 
1387
1394
  Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
1388
 
    :Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0), 
 
1395
    :Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0),
1389
1396
     bmGs(0), bmBc(0), escape_item(escape_arg),
1390
1397
     escape_used_in_parsing(escape_used) {}
1391
1398
  int64_t val_int();
1393
1400
  optimize_type select_optimize() const;
1394
1401
  cond_result eq_cmp_result() const { return COND_TRUE; }
1395
1402
  const char *func_name() const { return "like"; }
1396
 
  bool fix_fields(THD *thd, Item **ref);
 
1403
  bool fix_fields(Session *session, Item **ref);
1397
1404
  void cleanup();
1398
1405
};
1399
1406
 
1408
1415
  table_map and_tables_cache;
1409
1416
 
1410
1417
public:
 
1418
 
 
1419
  using Item::split_sum_func;
 
1420
 
1411
1421
  /* Item_cond() is only used to create top level items */
1412
1422
  Item_cond(): Item_bool_func(), abort_on_null(1)
1413
1423
  { const_item_cache=0; }
1417
1427
    list.push_back(i1);
1418
1428
    list.push_back(i2);
1419
1429
  }
1420
 
  Item_cond(THD *thd, Item_cond *item);
 
1430
  Item_cond(Session *session, Item_cond *item);
1421
1431
  Item_cond(List<Item> &nlist)
1422
1432
    :Item_bool_func(), list(nlist), abort_on_null(0) {}
1423
1433
  bool add(Item *item) { return list.push_back(item); }
1424
1434
  bool add_at_head(Item *item) { return list.push_front(item); }
1425
1435
  void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
1426
 
  bool fix_fields(THD *, Item **ref);
1427
 
  void fix_after_pullout(st_select_lex *new_parent, Item **ref);
 
1436
  bool fix_fields(Session *, Item **ref);
 
1437
  void fix_after_pullout(Select_Lex *new_parent, Item **ref);
1428
1438
 
1429
1439
  enum Type type() const { return COND_ITEM; }
1430
1440
  List<Item>* argument_list() { return &list; }
1431
1441
  table_map used_tables() const;
1432
1442
  void update_used_tables();
1433
1443
  virtual void print(String *str, enum_query_type query_type);
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,
 
1444
  void split_sum_func(Session *session, Item **ref_pointer_array, List<Item> &fields);
 
1445
  friend int setup_conds(Session *session, TableList *tables, TableList *leaves,
1436
1446
                         COND **conds);
1437
1447
  void top_level_item() { abort_on_null=1; }
1438
 
  void copy_andor_arguments(THD *thd, Item_cond *item);
 
1448
  void copy_andor_arguments(Session *session, Item_cond *item);
1439
1449
  bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1440
1450
  Item *transform(Item_transformer transformer, unsigned char *arg);
1441
1451
  void traverse_cond(Cond_traverser, void *arg, traverse_order order);
1442
 
  void neg_arguments(THD *thd);
 
1452
  void neg_arguments(Session *session);
1443
1453
  enum_field_types field_type() const { return DRIZZLE_TYPE_LONGLONG; }
1444
 
  bool subst_argument_checker(unsigned char **arg __attribute__((unused)))
 
1454
  bool subst_argument_checker(unsigned char **)
1445
1455
  { return true; }
1446
1456
  Item *compile(Item_analyzer analyzer, unsigned char **arg_p,
1447
1457
                Item_transformer transformer, unsigned char *arg_t);
1465
1475
  A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
1466
1476
  substituted for the item representing the same multiple equality
1467
1477
  f1=f2=f3.
1468
 
  An item Item_equal(f1,f2) can appear instead of a conjunction of 
 
1478
  An item Item_equal(f1,f2) can appear instead of a conjunction of
1469
1479
  f2=f1 and f1=f2, or instead of just the predicate f1=f2.
1470
1480
 
1471
 
  An item of the class Item_equal inherits equalities from outer 
 
1481
  An item of the class Item_equal inherits equalities from outer
1472
1482
  conjunctive levels.
1473
1483
 
1474
1484
  Suppose we have a where condition of the following form:
1479
1489
    f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
1480
1490
 
1481
1491
  An object of the class Item_equal can contain an optional constant
1482
 
  item c. Then it represents a multiple equality of the form 
 
1492
  item c. Then it represents a multiple equality of the form
1483
1493
  c=f1=...=fk.
1484
1494
 
1485
1495
  Objects of the class Item_equal are used for the following:
1494
1504
  It also can give us additional index scans and can allow us to
1495
1505
  improve selectivity estimates.
1496
1506
 
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 
 
1507
  3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
 
1508
  selected execution plan for the query: if table ti is accessed
1499
1509
  before the table tj then in any predicate P in the where condition
1500
1510
  the occurrence of tj.fj is substituted for ti.fi. This can allow
1501
1511
  an evaluation of the predicate at an earlier step.
1502
1512
 
1503
 
  When feature 1 is supported they say that join transitive closure 
 
1513
  When feature 1 is supported they say that join transitive closure
1504
1514
  is employed.
1505
1515
  When feature 2 is supported they say that search argument transitive
1506
1516
  closure is employed.
1509
1519
  We do not just add predicates, we rather dynamically replace some
1510
1520
  predicates that can not be used to access tables in the investigated
1511
1521
  plan for those, obtained by substitution of some fields for equal fields,
1512
 
  that can be used.     
 
1522
  that can be used.
1513
1523
 
1514
1524
  Prepared Statements/Stored Procedures note: instances of class
1515
1525
  Item_equal are created only at the time a PS/SP is executed and
1545
1555
  void merge(Item_equal *item);
1546
1556
  void update_const();
1547
1557
  enum Functype functype() const { return MULT_EQUAL_FUNC; }
1548
 
  int64_t val_int(); 
 
1558
  int64_t val_int();
1549
1559
  const char *func_name() const { return "multiple equal"; }
1550
1560
  optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
1551
1561
  void sort(Item_field_cmpfunc cmp, void *arg);
1552
1562
  friend class Item_equal_iterator;
1553
1563
  void fix_length_and_dec();
1554
 
  bool fix_fields(THD *thd, Item **ref);
 
1564
  bool fix_fields(Session *session, Item **ref);
1555
1565
  void update_used_tables();
1556
1566
  bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1557
1567
  Item *transform(Item_transformer transformer, unsigned char *arg);
1558
1568
  virtual void print(String *str, enum_query_type query_type);
1559
 
  const CHARSET_INFO *compare_collation() 
 
1569
  const CHARSET_INFO *compare_collation()
1560
1570
  { return fields.head()->collation.collation; }
1561
 
}; 
 
1571
};
1562
1572
 
1563
1573
class COND_EQUAL: public Sql_alloc
1564
1574
{
1565
1575
public:
1566
1576
  uint32_t max_members;               /* max number of members the current level
1567
 
                                     list and all lower level lists */ 
 
1577
                                     list and all lower level lists */
1568
1578
  COND_EQUAL *upper_levels;       /* multiple equalities of upper and levels */
1569
 
  List<Item_equal> current_level; /* list of multiple equalities of 
 
1579
  List<Item_equal> current_level; /* list of multiple equalities of
1570
1580
                                     the current and level           */
1571
1581
  COND_EQUAL()
1572
 
  { 
 
1582
  {
1573
1583
    upper_levels= 0;
1574
1584
  }
1575
1585
};
1578
1588
class Item_equal_iterator : public List_iterator_fast<Item_field>
1579
1589
{
1580
1590
public:
1581
 
  inline Item_equal_iterator(Item_equal &item_equal) 
 
1591
  inline Item_equal_iterator(Item_equal &item_equal)
1582
1592
    :List_iterator_fast<Item_field> (item_equal.fields)
1583
1593
  {}
1584
1594
  inline Item_field* operator++(int)
1585
 
  { 
 
1595
  {
1586
1596
    Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
1587
1597
    return  item;
1588
1598
  }
1589
 
  inline void rewind(void) 
1590
 
  { 
 
1599
  inline void rewind(void)
 
1600
  {
1591
1601
    List_iterator_fast<Item_field>::rewind();
1592
1602
  }
1593
1603
};
1595
1605
class Item_cond_and :public Item_cond
1596
1606
{
1597
1607
public:
1598
 
  COND_EQUAL cond_equal;  /* contains list of Item_equal objects for 
 
1608
  COND_EQUAL cond_equal;  /* contains list of Item_equal objects for
1599
1609
                             the current and level and reference
1600
 
                             to multiple equalities of upper and levels */  
 
1610
                             to multiple equalities of upper and levels */
1601
1611
  Item_cond_and() :Item_cond() {}
1602
1612
  Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1603
 
  Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
 
1613
  Item_cond_and(Session *session, Item_cond_and *item) :Item_cond(session, item) {}
1604
1614
  Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
1605
1615
  enum Functype functype() const { return COND_AND_FUNC; }
1606
1616
  int64_t val_int();
1607
1617
  const char *func_name() const { return "and"; }
1608
1618
  table_map not_null_tables() const
1609
1619
  { return abort_on_null ? not_null_tables_cache: and_tables_cache; }
1610
 
  Item* copy_andor_structure(THD *thd)
 
1620
  Item* copy_andor_structure(Session *session)
1611
1621
  {
1612
1622
    Item_cond_and *item;
1613
 
    if ((item= new Item_cond_and(thd, this)))
1614
 
       item->copy_andor_arguments(thd, this);
 
1623
    if ((item= new Item_cond_and(session, this)))
 
1624
       item->copy_andor_arguments(session, this);
1615
1625
    return item;
1616
1626
  }
1617
 
  Item *neg_transformer(THD *thd);
 
1627
  Item *neg_transformer(Session *session);
1618
1628
};
1619
1629
 
1620
1630
inline bool is_cond_and(Item *item)
1631
1641
public:
1632
1642
  Item_cond_or() :Item_cond() {}
1633
1643
  Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1634
 
  Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
 
1644
  Item_cond_or(Session *session, Item_cond_or *item) :Item_cond(session, item) {}
1635
1645
  Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
1636
1646
  enum Functype functype() const { return COND_OR_FUNC; }
1637
1647
  int64_t val_int();
1638
1648
  const char *func_name() const { return "or"; }
1639
1649
  table_map not_null_tables() const { return and_tables_cache; }
1640
 
  Item* copy_andor_structure(THD *thd)
 
1650
  Item* copy_andor_structure(Session *session)
1641
1651
  {
1642
1652
    Item_cond_or *item;
1643
 
    if ((item= new Item_cond_or(thd, this)))
1644
 
      item->copy_andor_arguments(thd, this);
 
1653
    if ((item= new Item_cond_or(session, this)))
 
1654
      item->copy_andor_arguments(session, this);
1645
1655
    return item;
1646
1656
  }
1647
 
  Item *neg_transformer(THD *thd);
 
1657
  Item *neg_transformer(Session *session);
1648
1658
};
1649
1659
 
1650
1660
inline bool is_cond_or(Item *item)
1685
1695
}
1686
1696
 
1687
1697
Item *and_expressions(Item *a, Item *b, Item **org_item);
 
1698
 
 
1699
#endif /* DRIZZLED_ITEM_CMPFUNC_H */