~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/item_cmpfunc.h

  • Committer: Monty Taylor
  • Date: 2008-07-26 16:22:28 UTC
  • mto: (236.1.42 codestyle)
  • mto: This revision was merged to the branch mainline in revision 261.
  • Revision ID: monty@inaugust.com-20080726162228-atatk41l6w4np70m
Added gettext calls in to my_getopt.c and drizzle.c

Show diffs side-by-side

added added

removed removed

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