~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.h

  • Committer: Brian Aker
  • Date: 2009-10-01 22:56:26 UTC
  • mto: (1154.1.1 staging)
  • mto: This revision was merged to the branch mainline in revision 1155.
  • Revision ID: brian@gaz-20091001225626-sb1pdykpxlnkheaj
Remove Factory/make scheduler work like everything else.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000-2003 MySQL AB
2
 
 
3
 
   This program is free software; you can redistribute it and/or modify
4
 
   it under the terms of the GNU General Public License as published by
5
 
   the Free Software Foundation; version 2 of the License.
6
 
 
7
 
   This program is distributed in the hope that it will be useful,
8
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 
   GNU General Public License for more details.
11
 
 
12
 
   You should have received a copy of the GNU General Public License
13
 
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
 
 
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008 Sun Microsystems
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; version 2 of the License.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
 
19
 
 
20
#ifndef DRIZZLED_ITEM_CMPFUNC_H
 
21
#define DRIZZLED_ITEM_CMPFUNC_H
16
22
 
17
23
/* compare and test functions */
18
24
 
19
 
#ifdef USE_PRAGMA_INTERFACE
20
 
#pragma interface                       /* gcc class implementation */
21
 
#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"
22
34
 
23
35
extern Item_result item_cmp_type(Item_result a,Item_result b);
24
36
class Item_bool_func2;
25
37
class Arg_comparator;
 
38
class Item_sum_hybrid;
 
39
class Item_row;
26
40
 
27
41
typedef int (Arg_comparator::*arg_cmp_func)();
28
42
 
29
 
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);
30
44
 
31
45
class Arg_comparator: public Sql_alloc
32
46
{
36
50
  Arg_comparator *comparators;   // used only for compare_row()
37
51
  double precision;
38
52
  /* Fields used in DATE/DATETIME comparison. */
39
 
  THD *thd;
 
53
  Session *session;
40
54
  enum_field_types a_type, b_type; // Types of a and b items
41
55
  Item *a_cache, *b_cache;         // Cached values of a and b items
42
56
  bool is_nulls_eq;                // TRUE <=> compare for the EQUAL_FUNC
43
57
  enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
44
58
                            CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
45
 
  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,
46
60
                              Item *warn_item, bool *is_null);
47
61
public:
48
62
  DTCollation cmp_collation;
49
63
 
50
 
  Arg_comparator(): thd(0), a_cache(0), b_cache(0) {};
51
 
  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),
52
66
    a_cache(0), b_cache(0) {};
53
67
 
54
68
  int set_compare_func(Item_bool_func2 *owner, Item_result type);
105
119
  Item_bool_func() :Item_int_func() {}
106
120
  Item_bool_func(Item *a) :Item_int_func(a) {}
107
121
  Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
108
 
  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) {}
109
123
  bool is_bool_func() { return 1; }
110
124
  void fix_length_and_dec() { decimals=0; max_length=1; }
111
 
  uint decimal_precision() const { return 1; }
 
125
  uint32_t decimal_precision() const { return 1; }
112
126
};
113
127
 
114
128
 
221
235
protected:
222
236
  Item_cache *cache;
223
237
  bool save_cache;
224
 
  /* 
 
238
  /*
225
239
    Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
226
240
      UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
227
241
      FALSE   - result is FALSE
230
244
  bool result_for_null_param;
231
245
public:
232
246
  Item_in_optimizer(Item *a, Item_in_subselect *b):
233
 
    Item_bool_func(a, my_reinterpret_cast(Item *)(b)), cache(0),
 
247
    Item_bool_func(a, reinterpret_cast<Item *>(b)), cache(0),
234
248
    save_cache(0), result_for_null_param(UNKNOWN)
235
249
  { with_subselect= true; }
236
 
  bool fix_fields(THD *, Item **);
237
 
  bool fix_left(THD *thd, Item **ref);
 
250
  bool fix_fields(Session *, Item **);
 
251
  bool fix_left(Session *session, Item **ref);
238
252
  bool is_null();
239
253
  int64_t val_int();
240
254
  void cleanup();
241
255
  const char *func_name() const { return "<in_optimizer>"; }
242
256
  Item_cache **get_cache() { return &cache; }
243
257
  void keep_top_level_cache();
244
 
  Item *transform(Item_transformer transformer, uchar *arg);
245
 
};
246
 
 
247
 
class Comp_creator
248
 
{
249
 
public:
250
 
  Comp_creator() {}                           /* Remove gcc warning */
251
 
  virtual ~Comp_creator() {}                  /* Remove gcc warning */
252
 
  virtual Item_bool_func2* create(Item *a, Item *b) const = 0;
253
 
  virtual const char* symbol(bool invert) const = 0;
254
 
  virtual bool eqne_op() const = 0;
255
 
  virtual bool l_op() const = 0;
 
258
  Item *transform(Item_transformer transformer, unsigned char *arg);
256
259
};
257
260
 
258
261
class Eq_creator :public Comp_creator
264
267
  virtual const char* symbol(bool invert) const { return invert? "<>" : "="; }
265
268
  virtual bool eqne_op() const { return 1; }
266
269
  virtual bool l_op() const { return 0; }
 
270
  static const Eq_creator *instance();
267
271
};
268
272
 
269
273
class Ne_creator :public Comp_creator
275
279
  virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; }
276
280
  virtual bool eqne_op() const { return 1; }
277
281
  virtual bool l_op() const { return 0; }
 
282
  static const Ne_creator *instance();
278
283
};
279
284
 
280
285
class Gt_creator :public Comp_creator
286
291
  virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
287
292
  virtual bool eqne_op() const { return 0; }
288
293
  virtual bool l_op() const { return 0; }
 
294
  static const Gt_creator *instance();
289
295
};
290
296
 
291
297
class Lt_creator :public Comp_creator
297
303
  virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
298
304
  virtual bool eqne_op() const { return 0; }
299
305
  virtual bool l_op() const { return 1; }
 
306
  static const Lt_creator *instance();
300
307
};
301
308
 
302
309
class Ge_creator :public Comp_creator
308
315
  virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
309
316
  virtual bool eqne_op() const { return 0; }
310
317
  virtual bool l_op() const { return 0; }
 
318
  static const Ge_creator *instance();
311
319
};
312
320
 
313
321
class Le_creator :public Comp_creator
319
327
  virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
320
328
  virtual bool eqne_op() const { return 0; }
321
329
  virtual bool l_op() const { return 1; }
 
330
  static const Le_creator *instance();
322
331
};
323
332
 
324
333
class Item_bool_func2 :public Item_int_func
348
357
  bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
349
358
  bool is_bool_func() { return 1; }
350
359
  const CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; }
351
 
  uint decimal_precision() const { return 1; }
 
360
  uint32_t decimal_precision() const { return 1; }
352
361
  void top_level_item() { abort_on_null= true; }
353
362
 
354
363
  friend class  Arg_comparator;
361
370
  {
362
371
    allowed_arg_cols= 0;  // Fetch this value from first argument
363
372
  }
364
 
  Item *neg_transformer(THD *thd);
 
373
  Item *neg_transformer(Session *session);
365
374
  virtual Item *negated_item();
366
 
  bool subst_argument_checker(uchar **arg __attribute__((unused)))
 
375
  bool subst_argument_checker(unsigned char **)
367
376
  { return true; }
368
377
};
369
378
 
374
383
  int64_t val_int();
375
384
  enum Functype functype() const { return NOT_FUNC; }
376
385
  const char *func_name() const { return "not"; }
377
 
  Item *neg_transformer(THD *thd);
 
386
  Item *neg_transformer(Session *session);
378
387
  virtual void print(String *str, enum_query_type query_type);
379
388
};
380
389
 
383
392
/*
384
393
  trigcond<param>(arg) ::= param? arg : TRUE
385
394
 
386
 
  The class Item_func_trig_cond is used for guarded predicates 
 
395
  The class Item_func_trig_cond is used for guarded predicates
387
396
  which are employed only for internal purposes.
388
397
  A guarded predicate is an object consisting of an a regular or
389
 
  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.
390
399
  A guarded predicate P/g is evaluated to true if the value of the
391
400
  guard g is false, otherwise it is evaluated to the same value that
392
401
  the predicate P: val(P/g)= g ? val(P):true.
398
407
  the objects consisting of three elements: a predicate P, a pointer
399
408
  to a variable g and a firing value s with following evaluation
400
409
  rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
401
 
  one item for the objects of the form P/g1/g2... 
 
410
  one item for the objects of the form P/g1/g2...
402
411
 
403
412
  Objects of this class are built only for query execution after
404
413
  the execution plan has been already selected. That's why this
405
 
  class needs only val_int out of generic methods. 
406
 
 
 
414
  class needs only val_int out of generic methods.
 
415
 
407
416
  Current uses of Item_func_trig_cond objects:
408
417
   - To wrap selection conditions when executing outer joins
409
418
   - To wrap condition that is pushed down into subquery
446
455
  void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
447
456
  void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
448
457
  bool empty_underlying_subquery();
449
 
  Item *neg_transformer(THD *thd);
 
458
  Item *neg_transformer(Session *session);
450
459
};
451
460
 
452
461
 
457
466
  Item_func_nop_all(Item *a) :Item_func_not_all(a) {}
458
467
  int64_t val_int();
459
468
  const char *func_name() const { return "<nop>"; }
460
 
  Item *neg_transformer(THD *thd);
 
469
  Item *neg_transformer(Session *session);
461
470
};
462
471
 
463
472
 
484
493
  enum Functype rev_functype() const { return EQUAL_FUNC; }
485
494
  cond_result eq_cmp_result() const { return COND_TRUE; }
486
495
  const char *func_name() const { return "<=>"; }
487
 
  Item *neg_transformer(THD *thd __attribute__((unused))) { return 0; }
 
496
  Item *neg_transformer(Session *) { return 0; }
488
497
};
489
498
 
490
499
 
547
556
  int64_t val_int();
548
557
  enum Functype functype() const { return NE_FUNC; }
549
558
  cond_result eq_cmp_result() const { return COND_FALSE; }
550
 
  optimize_type select_optimize() const { return OPTIMIZE_KEY; } 
 
559
  optimize_type select_optimize() const { return OPTIMIZE_KEY; }
551
560
  const char *func_name() const { return "<>"; }
552
561
  Item *negated_item();
553
562
};
575
584
public:
576
585
  inline void negate() { negated= !negated; }
577
586
  inline void top_level_item() { pred_level= 1; }
578
 
  Item *neg_transformer(THD *thd __attribute__((unused)))
 
587
  Item *neg_transformer(Session *)
579
588
  {
580
589
    negated= !negated;
581
590
    return this;
582
591
  }
583
592
  bool eq(const Item *item, bool binary_cmp) const;
584
 
  bool subst_argument_checker(uchar **arg __attribute__((unused)))
 
593
  bool subst_argument_checker(unsigned char **)
585
594
  { return true; }
586
595
};
587
596
 
602
611
  optimize_type select_optimize() const { return OPTIMIZE_KEY; }
603
612
  enum Functype functype() const   { return BETWEEN; }
604
613
  const char *func_name() const { return "between"; }
605
 
  bool fix_fields(THD *, Item **);
 
614
  bool fix_fields(Session *, Item **);
606
615
  void fix_length_and_dec();
607
616
  virtual void print(String *str, enum_query_type query_type);
608
617
  bool is_bool_func() { return 1; }
609
618
  const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
610
 
  uint decimal_precision() const { return 1; }
 
619
  uint32_t decimal_precision() const { return 1; }
611
620
};
612
621
 
613
622
 
647
656
  int64_t val_int();
648
657
  void fix_length_and_dec();
649
658
  const char *func_name() const { return "interval"; }
650
 
  uint decimal_precision() const { return 2; }
 
659
  uint32_t decimal_precision() const { return 2; }
651
660
};
652
661
 
653
662
 
684
693
  enum_field_types field_type() const;
685
694
  void fix_length_and_dec();
686
695
  const char *func_name() const { return "ifnull"; }
687
 
  Field *tmp_table_field(TABLE *table);
688
 
  uint decimal_precision() const;
 
696
  Field *tmp_table_field()
 
697
  {
 
698
    return Item_func::tmp_table_field();
 
699
  }
 
700
  Field *tmp_table_field(Table *table);
 
701
  uint32_t decimal_precision() const;
689
702
};
690
703
 
691
704
 
703
716
  my_decimal *val_decimal(my_decimal *);
704
717
  enum Item_result result_type () const { return cached_result_type; }
705
718
  enum_field_types field_type() const { return cached_field_type; }
706
 
  bool fix_fields(THD *, Item **);
 
719
  bool fix_fields(Session *, Item **);
707
720
  void fix_length_and_dec();
708
 
  uint decimal_precision() const;
 
721
  uint32_t decimal_precision() const;
709
722
  const char *func_name() const { return "if"; }
710
723
};
711
724
 
723
736
  my_decimal *val_decimal(my_decimal *);
724
737
  enum Item_result result_type () const { return cached_result_type; }
725
738
  void fix_length_and_dec();
726
 
  uint decimal_precision() const { return args[0]->decimal_precision(); }
 
739
  uint32_t decimal_precision() const { return args[0]->decimal_precision(); }
727
740
  const char *func_name() const { return "nullif"; }
728
741
 
729
742
  virtual inline void print(String *str, enum_query_type query_type)
745
758
{
746
759
public:
747
760
  char *base;
748
 
  uint size;
 
761
  uint32_t size;
749
762
  qsort2_cmp compare;
750
763
  const CHARSET_INFO *collation;
751
 
  uint count;
752
 
  uint used_count;
 
764
  uint32_t count;
 
765
  uint32_t used_count;
753
766
  in_vector() {}
754
 
  in_vector(uint elements,uint element_length,qsort2_cmp cmp_func, 
 
767
  in_vector(uint32_t elements,uint32_t element_length,qsort2_cmp cmp_func,
755
768
            const CHARSET_INFO * const cmp_coll)
756
769
    :base((char*) sql_calloc(elements*element_length)),
757
770
     size(element_length), compare(cmp_func), collation(cmp_coll),
758
771
     count(elements), used_count(elements) {}
759
772
  virtual ~in_vector() {}
760
 
  virtual void set(uint pos,Item *item)=0;
761
 
  virtual uchar *get_value(Item *item)=0;
 
773
  virtual void set(uint32_t pos,Item *item)=0;
 
774
  virtual unsigned char *get_value(Item *item)=0;
762
775
  void sort()
763
776
  {
764
777
    my_qsort2(base,used_count,size,compare, (void *) collation);
765
778
  }
766
779
  int find(Item *item);
767
 
  
768
 
  /* 
 
780
 
 
781
  /*
769
782
    Create an instance of Item_{type} (e.g. Item_decimal) constant object
770
783
    which type allows it to hold an element of this vector without any
771
784
    conversions.
774
787
    for every array element you get (i.e. this implements "FlyWeight" pattern)
775
788
  */
776
789
  virtual Item* create_item() { return NULL; }
777
 
  
 
790
 
778
791
  /*
779
792
    Store the value at position #pos into provided item object
780
793
    SYNOPSIS
783
796
        item  Constant item to store value into. The item must be of the same
784
797
              type that create_item() returns.
785
798
  */
786
 
  virtual void value_to_item(uint pos __attribute__((unused)),
787
 
                             Item *item __attribute__((unused))) { }
788
 
  
 
799
  virtual void value_to_item(uint32_t, Item *) { }
 
800
 
789
801
  /* Compare values number pos1 and pos2 for equality */
790
 
  bool compare_elems(uint pos1, uint pos2)
 
802
  bool compare_elems(uint32_t pos1, uint32_t pos2)
791
803
  {
792
804
    return test(compare(collation, base + pos1*size, base + pos2*size));
793
805
  }
799
811
  char buff[STRING_BUFFER_USUAL_SIZE];
800
812
  String tmp;
801
813
public:
802
 
  in_string(uint elements,qsort2_cmp cmp_func, const CHARSET_INFO * const cs);
 
814
  in_string(uint32_t elements,qsort2_cmp cmp_func, const CHARSET_INFO * const cs);
803
815
  ~in_string();
804
 
  void set(uint pos,Item *item);
805
 
  uchar *get_value(Item *item);
 
816
  void set(uint32_t pos,Item *item);
 
817
  unsigned char *get_value(Item *item);
806
818
  Item* create_item()
807
 
  { 
 
819
  {
808
820
    return new Item_string(collation);
809
821
  }
810
 
  void value_to_item(uint pos, Item *item)
811
 
  {    
 
822
  void value_to_item(uint32_t pos, Item *item)
 
823
  {
812
824
    String *str=((String*) base)+pos;
813
825
    Item_string *to= (Item_string*)item;
814
826
    to->str_value= *str;
821
833
protected:
822
834
  /*
823
835
    Here we declare a temporary variable (tmp) of the same type as the
824
 
    elements of this vector. tmp is used in finding if a given value is in 
825
 
    the list. 
 
836
    elements of this vector. tmp is used in finding if a given value is in
 
837
    the list.
826
838
  */
827
 
  struct packed_int64_t 
 
839
  struct packed_int64_t
828
840
  {
829
841
    int64_t val;
830
842
    int64_t unsigned_flag;  // Use int64_t, not bool, to preserve alignment
831
843
  } tmp;
832
844
public:
833
 
  in_int64_t(uint elements);
834
 
  void set(uint pos,Item *item);
835
 
  uchar *get_value(Item *item);
836
 
  
 
845
  in_int64_t(uint32_t elements);
 
846
  void set(uint32_t pos,Item *item);
 
847
  unsigned char *get_value(Item *item);
 
848
 
837
849
  Item* create_item()
838
 
  { 
839
 
    /* 
840
 
      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
841
853
      general case (see BUG#19342).
842
854
    */
843
855
    return new Item_int((int64_t)0);
844
856
  }
845
 
  void value_to_item(uint pos, Item *item)
 
857
  void value_to_item(uint32_t pos, Item *item)
846
858
  {
847
859
    ((Item_int*) item)->value= ((packed_int64_t*) base)[pos].val;
848
860
    ((Item_int*) item)->unsigned_flag= (bool)
863
875
class in_datetime :public in_int64_t
864
876
{
865
877
public:
866
 
  THD *thd;
 
878
  Session *session;
867
879
  /* An item used to issue warnings. */
868
880
  Item *warn_item;
869
881
  /* Cache for the left item. */
870
882
  Item *lval_cache;
871
883
 
872
 
  in_datetime(Item *warn_item_arg, uint elements)
873
 
    :in_int64_t(elements), thd(current_thd), warn_item(warn_item_arg),
 
884
  in_datetime(Item *warn_item_arg, uint32_t elements)
 
885
    :in_int64_t(elements), session(current_session), warn_item(warn_item_arg),
874
886
     lval_cache(0) {};
875
 
  void set(uint pos,Item *item);
876
 
  uchar *get_value(Item *item);
 
887
  void set(uint32_t pos,Item *item);
 
888
  unsigned char *get_value(Item *item);
877
889
  friend int cmp_int64_t(void *cmp_arg, packed_int64_t *a,packed_int64_t *b);
878
890
};
879
891
 
882
894
{
883
895
  double tmp;
884
896
public:
885
 
  in_double(uint elements);
886
 
  void set(uint pos,Item *item);
887
 
  uchar *get_value(Item *item);
 
897
  in_double(uint32_t elements);
 
898
  void set(uint32_t pos,Item *item);
 
899
  unsigned char *get_value(Item *item);
888
900
  Item *create_item()
889
 
  { 
 
901
  {
890
902
    return new Item_float(0.0, 0);
891
903
  }
892
 
  void value_to_item(uint pos, Item *item)
 
904
  void value_to_item(uint32_t pos, Item *item)
893
905
  {
894
906
    ((Item_float*)item)->value= ((double*) base)[pos];
895
907
  }
901
913
{
902
914
  my_decimal val;
903
915
public:
904
 
  in_decimal(uint elements);
905
 
  void set(uint pos, Item *item);
906
 
  uchar *get_value(Item *item);
 
916
  in_decimal(uint32_t elements);
 
917
  void set(uint32_t pos, Item *item);
 
918
  unsigned char *get_value(Item *item);
907
919
  Item *create_item()
908
 
  { 
 
920
  {
909
921
    return new Item_decimal(0, false);
910
922
  }
911
 
  void value_to_item(uint pos, Item *item)
 
923
  void value_to_item(uint32_t pos, Item *item)
912
924
  {
913
925
    my_decimal *dec= ((my_decimal *)base) + pos;
914
926
    Item_decimal *item_dec= (Item_decimal*)item;
935
947
  virtual int compare(cmp_item *item)= 0;
936
948
  static cmp_item* get_comparator(Item_result type, const CHARSET_INFO * const cs);
937
949
  virtual cmp_item *make_same()= 0;
938
 
  virtual void store_value_by_template(cmp_item *tmpl  __attribute__((unused)),
939
 
                                       Item *item)
 
950
  virtual void store_value_by_template(cmp_item *, Item *item)
940
951
  {
941
952
    store_value(item);
942
953
  }
943
954
};
944
955
 
945
 
class cmp_item_string :public cmp_item 
 
956
class cmp_item_string :public cmp_item
946
957
{
947
958
protected:
948
959
  String *value_res;
981
992
  {
982
993
    cmp_item_string *l_cmp= (cmp_item_string *) ci;
983
994
    return sortcmp(value_res, l_cmp->value_res, cmp_charset);
984
 
  } 
 
995
  }
985
996
  cmp_item *make_same();
986
997
  void set_charset(const CHARSET_INFO * const cs)
987
998
  {
1021
1032
{
1022
1033
  uint64_t value;
1023
1034
public:
1024
 
  THD *thd;
 
1035
  Session *session;
1025
1036
  /* Item used for issuing warnings. */
1026
1037
  Item *warn_item;
1027
1038
  /* Cache for the left item. */
1028
1039
  Item *lval_cache;
1029
1040
 
1030
1041
  cmp_item_datetime(Item *warn_item_arg)
1031
 
    :thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
 
1042
    :session(current_session), warn_item(warn_item_arg), lval_cache(0) {}
1032
1043
  void store_value(Item *item);
1033
1044
  int cmp(Item *arg);
1034
1045
  int compare(cmp_item *ci);
1069
1080
};
1070
1081
 
1071
1082
 
1072
 
/* 
 
1083
/*
1073
1084
   cmp_item for optimized IN with row (right part string, which never
1074
1085
   be changed)
1075
1086
*/
1085
1096
  {
1086
1097
    value_res= item->val_str(&value);
1087
1098
  }
1088
 
  int cmp(Item *item __attribute__((unused)))
 
1099
  int cmp(Item *)
1089
1100
  {
1090
1101
    // Should never be called
1091
1102
    assert(0);
1107
1118
  The class Item_func_case is the CASE ... WHEN ... THEN ... END function
1108
1119
  implementation.
1109
1120
 
1110
 
  When there is no expression between CASE and the first WHEN 
 
1121
  When there is no expression between CASE and the first WHEN
1111
1122
  (the CASE expression) then this function simple checks all WHEN expressions
1112
1123
  one after another. When some WHEN expression evaluated to TRUE then the
1113
1124
  value of the corresponding THEN expression is returned.
1126
1137
  int first_expr_num, else_expr_num;
1127
1138
  enum Item_result cached_result_type, left_result_type;
1128
1139
  String tmp_value;
1129
 
  uint ncases;
 
1140
  uint32_t ncases;
1130
1141
  Item_result cmp_type;
1131
1142
  DTCollation cmp_collation;
1132
1143
  enum_field_types cached_field_type;
1155
1166
  int64_t val_int();
1156
1167
  String *val_str(String *);
1157
1168
  my_decimal *val_decimal(my_decimal *);
1158
 
  bool fix_fields(THD *thd, Item **ref);
 
1169
  bool fix_fields(Session *session, Item **ref);
1159
1170
  void fix_length_and_dec();
1160
 
  uint decimal_precision() const;
 
1171
  uint32_t decimal_precision() const;
1161
1172
  table_map not_null_tables() const { return 0; }
1162
1173
  enum Item_result result_type () const { return cached_result_type; }
1163
1174
  enum_field_types field_type() const { return cached_field_type; }
1187
1198
class Item_func_in :public Item_func_opt_neg
1188
1199
{
1189
1200
public:
1190
 
  /* 
 
1201
  /*
1191
1202
    an array of values when the right hand arguments of IN
1192
 
    are all SQL constant and there are no nulls 
 
1203
    are all SQL constant and there are no nulls
1193
1204
  */
1194
1205
  in_vector *array;
1195
1206
  bool have_null;
1196
 
  /* 
 
1207
  /*
1197
1208
    true when all arguments of the IN clause are of compatible types
1198
1209
    and can be used safely as comparisons for key conditions
1199
1210
  */
1210
1221
    allowed_arg_cols= 0;  // Fetch this value from first argument
1211
1222
  }
1212
1223
  int64_t val_int();
1213
 
  bool fix_fields(THD *, Item **);
 
1224
  bool fix_fields(Session *, Item **);
1214
1225
  void fix_length_and_dec();
1215
 
  uint decimal_precision() const { return 1; }
 
1226
  uint32_t decimal_precision() const { return 1; }
1216
1227
  void cleanup()
1217
1228
  {
1218
 
    uint i;
 
1229
    uint32_t i;
1219
1230
    Item_int_func::cleanup();
1220
1231
    delete array;
1221
1232
    array= 0;
1222
 
    for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
 
1233
    for (i= 0; i <= (uint32_t)DECIMAL_RESULT + 1; i++)
1223
1234
    {
1224
1235
      delete cmp_items[i];
1225
1236
      cmp_items[i]= 0;
1239
1250
class cmp_item_row :public cmp_item
1240
1251
{
1241
1252
  cmp_item **comparators;
1242
 
  uint n;
 
1253
  uint32_t n;
1243
1254
public:
1244
1255
  cmp_item_row(): comparators(0), n(0) {}
1245
1256
  ~cmp_item_row();
1257
1268
{
1258
1269
  cmp_item_row tmp;
1259
1270
public:
1260
 
  in_row(uint elements, Item *);
 
1271
  in_row(uint32_t elements, Item *);
1261
1272
  ~in_row();
1262
 
  void set(uint pos,Item *item);
1263
 
  uchar *get_value(Item *item);
 
1273
  void set(uint32_t pos,Item *item);
 
1274
  unsigned char *get_value(Item *item);
1264
1275
  friend void Item_func_in::fix_length_and_dec();
1265
1276
  Item_result result_type() { return ROW_RESULT; }
1266
1277
};
1303
1314
  }
1304
1315
  table_map not_null_tables() const { return 0; }
1305
1316
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1306
 
  Item *neg_transformer(THD *thd);
 
1317
  Item *neg_transformer(Session *session);
1307
1318
  const CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1308
1319
};
1309
1320
 
1311
1322
 
1312
1323
class Item_in_subselect;
1313
1324
 
1314
 
/* 
 
1325
/*
1315
1326
  This is like IS NOT NULL but it also remembers if it ever has
1316
1327
  encountered a NULL.
1317
1328
*/
1349
1360
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1350
1361
  table_map not_null_tables() const
1351
1362
  { return abort_on_null ? not_null_tables_cache : 0; }
1352
 
  Item *neg_transformer(THD *thd);
 
1363
  Item *neg_transformer(Session *session);
1353
1364
  virtual void print(String *str, enum_query_type query_type);
1354
1365
  const CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1355
1366
  void top_level_item() { abort_on_null=1; }
1374
1385
  enum { alphabet_size = 256 };
1375
1386
 
1376
1387
  Item *escape_item;
1377
 
  
 
1388
 
1378
1389
  bool escape_used_in_parsing;
1379
1390
 
 
1391
 
1380
1392
public:
1381
 
  int escape;
 
1393
 
 
1394
  char *escape;
1382
1395
 
1383
1396
  Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
1384
 
    :Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0), 
 
1397
    :Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0),
1385
1398
     bmGs(0), bmBc(0), escape_item(escape_arg),
1386
 
     escape_used_in_parsing(escape_used) {}
 
1399
     escape_used_in_parsing(escape_used), escape(NULL) {}
1387
1400
  int64_t val_int();
1388
1401
  enum Functype functype() const { return LIKE_FUNC; }
1389
1402
  optimize_type select_optimize() const;
1390
1403
  cond_result eq_cmp_result() const { return COND_TRUE; }
1391
1404
  const char *func_name() const { return "like"; }
1392
 
  bool fix_fields(THD *thd, Item **ref);
 
1405
  bool fix_fields(Session *session, Item **ref);
1393
1406
  void cleanup();
1394
1407
};
1395
1408
 
1404
1417
  table_map and_tables_cache;
1405
1418
 
1406
1419
public:
 
1420
 
 
1421
  using Item::split_sum_func;
 
1422
 
1407
1423
  /* Item_cond() is only used to create top level items */
1408
1424
  Item_cond(): Item_bool_func(), abort_on_null(1)
1409
1425
  { const_item_cache=0; }
1413
1429
    list.push_back(i1);
1414
1430
    list.push_back(i2);
1415
1431
  }
1416
 
  Item_cond(THD *thd, Item_cond *item);
 
1432
  Item_cond(Session *session, Item_cond *item);
1417
1433
  Item_cond(List<Item> &nlist)
1418
1434
    :Item_bool_func(), list(nlist), abort_on_null(0) {}
1419
1435
  bool add(Item *item) { return list.push_back(item); }
1420
1436
  bool add_at_head(Item *item) { return list.push_front(item); }
1421
1437
  void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
1422
 
  bool fix_fields(THD *, Item **ref);
1423
 
  void fix_after_pullout(st_select_lex *new_parent, Item **ref);
 
1438
  bool fix_fields(Session *, Item **ref);
 
1439
  void fix_after_pullout(Select_Lex *new_parent, Item **ref);
1424
1440
 
1425
1441
  enum Type type() const { return COND_ITEM; }
1426
1442
  List<Item>* argument_list() { return &list; }
1427
1443
  table_map used_tables() const;
1428
1444
  void update_used_tables();
1429
1445
  virtual void print(String *str, enum_query_type query_type);
1430
 
  void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
1431
 
  friend int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
 
1446
  void split_sum_func(Session *session, Item **ref_pointer_array, List<Item> &fields);
 
1447
  friend int setup_conds(Session *session, TableList *tables, TableList *leaves,
1432
1448
                         COND **conds);
1433
1449
  void top_level_item() { abort_on_null=1; }
1434
 
  void copy_andor_arguments(THD *thd, Item_cond *item);
1435
 
  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
1436
 
  Item *transform(Item_transformer transformer, uchar *arg);
 
1450
  void copy_andor_arguments(Session *session, Item_cond *item);
 
1451
  bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
 
1452
  Item *transform(Item_transformer transformer, unsigned char *arg);
1437
1453
  void traverse_cond(Cond_traverser, void *arg, traverse_order order);
1438
 
  void neg_arguments(THD *thd);
 
1454
  void neg_arguments(Session *session);
1439
1455
  enum_field_types field_type() const { return DRIZZLE_TYPE_LONGLONG; }
1440
 
  bool subst_argument_checker(uchar **arg __attribute__((unused)))
 
1456
  bool subst_argument_checker(unsigned char **)
1441
1457
  { return true; }
1442
 
  Item *compile(Item_analyzer analyzer, uchar **arg_p,
1443
 
                Item_transformer transformer, uchar *arg_t);
 
1458
  Item *compile(Item_analyzer analyzer, unsigned char **arg_p,
 
1459
                Item_transformer transformer, unsigned char *arg_t);
1444
1460
};
1445
1461
 
1446
1462
 
1461
1477
  A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
1462
1478
  substituted for the item representing the same multiple equality
1463
1479
  f1=f2=f3.
1464
 
  An item Item_equal(f1,f2) can appear instead of a conjunction of 
 
1480
  An item Item_equal(f1,f2) can appear instead of a conjunction of
1465
1481
  f2=f1 and f1=f2, or instead of just the predicate f1=f2.
1466
1482
 
1467
 
  An item of the class Item_equal inherits equalities from outer 
 
1483
  An item of the class Item_equal inherits equalities from outer
1468
1484
  conjunctive levels.
1469
1485
 
1470
1486
  Suppose we have a where condition of the following form:
1475
1491
    f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
1476
1492
 
1477
1493
  An object of the class Item_equal can contain an optional constant
1478
 
  item c. Then it represents a multiple equality of the form 
 
1494
  item c. Then it represents a multiple equality of the form
1479
1495
  c=f1=...=fk.
1480
1496
 
1481
1497
  Objects of the class Item_equal are used for the following:
1490
1506
  It also can give us additional index scans and can allow us to
1491
1507
  improve selectivity estimates.
1492
1508
 
1493
 
  3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the 
1494
 
  selected execution plan for the query: if table ti is accessed 
 
1509
  3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
 
1510
  selected execution plan for the query: if table ti is accessed
1495
1511
  before the table tj then in any predicate P in the where condition
1496
1512
  the occurrence of tj.fj is substituted for ti.fi. This can allow
1497
1513
  an evaluation of the predicate at an earlier step.
1498
1514
 
1499
 
  When feature 1 is supported they say that join transitive closure 
 
1515
  When feature 1 is supported they say that join transitive closure
1500
1516
  is employed.
1501
1517
  When feature 2 is supported they say that search argument transitive
1502
1518
  closure is employed.
1505
1521
  We do not just add predicates, we rather dynamically replace some
1506
1522
  predicates that can not be used to access tables in the investigated
1507
1523
  plan for those, obtained by substitution of some fields for equal fields,
1508
 
  that can be used.     
 
1524
  that can be used.
1509
1525
 
1510
1526
  Prepared Statements/Stored Procedures note: instances of class
1511
1527
  Item_equal are created only at the time a PS/SP is executed and
1535
1551
  inline Item* get_const() { return const_item; }
1536
1552
  void add(Item *c);
1537
1553
  void add(Item_field *f);
1538
 
  uint members();
 
1554
  uint32_t members();
1539
1555
  bool contains(Field *field);
1540
1556
  Item_field* get_first() { return fields.head(); }
1541
1557
  void merge(Item_equal *item);
1542
1558
  void update_const();
1543
1559
  enum Functype functype() const { return MULT_EQUAL_FUNC; }
1544
 
  int64_t val_int(); 
 
1560
  int64_t val_int();
1545
1561
  const char *func_name() const { return "multiple equal"; }
1546
1562
  optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
1547
1563
  void sort(Item_field_cmpfunc cmp, void *arg);
1548
1564
  friend class Item_equal_iterator;
1549
1565
  void fix_length_and_dec();
1550
 
  bool fix_fields(THD *thd, Item **ref);
 
1566
  bool fix_fields(Session *session, Item **ref);
1551
1567
  void update_used_tables();
1552
 
  bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
1553
 
  Item *transform(Item_transformer transformer, uchar *arg);
 
1568
  bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
 
1569
  Item *transform(Item_transformer transformer, unsigned char *arg);
1554
1570
  virtual void print(String *str, enum_query_type query_type);
1555
 
  const CHARSET_INFO *compare_collation() 
 
1571
  const CHARSET_INFO *compare_collation()
1556
1572
  { return fields.head()->collation.collation; }
1557
 
}; 
 
1573
};
1558
1574
 
1559
1575
class COND_EQUAL: public Sql_alloc
1560
1576
{
1561
1577
public:
1562
 
  uint max_members;               /* max number of members the current level
1563
 
                                     list and all lower level lists */ 
 
1578
  uint32_t max_members;               /* max number of members the current level
 
1579
                                     list and all lower level lists */
1564
1580
  COND_EQUAL *upper_levels;       /* multiple equalities of upper and levels */
1565
 
  List<Item_equal> current_level; /* list of multiple equalities of 
 
1581
  List<Item_equal> current_level; /* list of multiple equalities of
1566
1582
                                     the current and level           */
1567
1583
  COND_EQUAL()
1568
 
  { 
 
1584
  {
1569
1585
    upper_levels= 0;
1570
1586
  }
1571
1587
};
1574
1590
class Item_equal_iterator : public List_iterator_fast<Item_field>
1575
1591
{
1576
1592
public:
1577
 
  inline Item_equal_iterator(Item_equal &item_equal) 
 
1593
  inline Item_equal_iterator(Item_equal &item_equal)
1578
1594
    :List_iterator_fast<Item_field> (item_equal.fields)
1579
1595
  {}
1580
1596
  inline Item_field* operator++(int)
1581
 
  { 
 
1597
  {
1582
1598
    Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
1583
1599
    return  item;
1584
1600
  }
1585
 
  inline void rewind(void) 
1586
 
  { 
 
1601
  inline void rewind(void)
 
1602
  {
1587
1603
    List_iterator_fast<Item_field>::rewind();
1588
1604
  }
1589
1605
};
1591
1607
class Item_cond_and :public Item_cond
1592
1608
{
1593
1609
public:
1594
 
  COND_EQUAL cond_equal;  /* contains list of Item_equal objects for 
 
1610
  COND_EQUAL cond_equal;  /* contains list of Item_equal objects for
1595
1611
                             the current and level and reference
1596
 
                             to multiple equalities of upper and levels */  
 
1612
                             to multiple equalities of upper and levels */
1597
1613
  Item_cond_and() :Item_cond() {}
1598
1614
  Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1599
 
  Item_cond_and(THD *thd, Item_cond_and *item) :Item_cond(thd, item) {}
 
1615
  Item_cond_and(Session *session, Item_cond_and *item) :Item_cond(session, item) {}
1600
1616
  Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
1601
1617
  enum Functype functype() const { return COND_AND_FUNC; }
1602
1618
  int64_t val_int();
1603
1619
  const char *func_name() const { return "and"; }
1604
1620
  table_map not_null_tables() const
1605
1621
  { return abort_on_null ? not_null_tables_cache: and_tables_cache; }
1606
 
  Item* copy_andor_structure(THD *thd)
 
1622
  Item* copy_andor_structure(Session *session)
1607
1623
  {
1608
1624
    Item_cond_and *item;
1609
 
    if ((item= new Item_cond_and(thd, this)))
1610
 
       item->copy_andor_arguments(thd, this);
 
1625
    if ((item= new Item_cond_and(session, this)))
 
1626
       item->copy_andor_arguments(session, this);
1611
1627
    return item;
1612
1628
  }
1613
 
  Item *neg_transformer(THD *thd);
 
1629
  Item *neg_transformer(Session *session);
1614
1630
};
1615
1631
 
1616
1632
inline bool is_cond_and(Item *item)
1627
1643
public:
1628
1644
  Item_cond_or() :Item_cond() {}
1629
1645
  Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1630
 
  Item_cond_or(THD *thd, Item_cond_or *item) :Item_cond(thd, item) {}
 
1646
  Item_cond_or(Session *session, Item_cond_or *item) :Item_cond(session, item) {}
1631
1647
  Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
1632
1648
  enum Functype functype() const { return COND_OR_FUNC; }
1633
1649
  int64_t val_int();
1634
1650
  const char *func_name() const { return "or"; }
1635
1651
  table_map not_null_tables() const { return and_tables_cache; }
1636
 
  Item* copy_andor_structure(THD *thd)
 
1652
  Item* copy_andor_structure(Session *session)
1637
1653
  {
1638
1654
    Item_cond_or *item;
1639
 
    if ((item= new Item_cond_or(thd, this)))
1640
 
      item->copy_andor_arguments(thd, this);
 
1655
    if ((item= new Item_cond_or(session, this)))
 
1656
      item->copy_andor_arguments(session, this);
1641
1657
    return item;
1642
1658
  }
1643
 
  Item *neg_transformer(THD *thd);
 
1659
  Item *neg_transformer(Session *session);
1644
1660
};
1645
1661
 
1646
1662
inline bool is_cond_or(Item *item)
1681
1697
}
1682
1698
 
1683
1699
Item *and_expressions(Item *a, Item *b, Item **org_item);
 
1700
 
 
1701
#endif /* DRIZZLED_ITEM_CMPFUNC_H */