~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/item_cmpfunc.h

  • Committer: Mark Atwood
  • Date: 2008-07-12 11:37:59 UTC
  • mto: This revision was merged to the branch mainline in revision 139.
  • Revision ID: me@mark.atwood.name-20080712113759-nrjn1bq1e0shuory
Add hello_world() UDF

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
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/session.h"
35
 
#include "drizzled/common.h"
36
 
#include "drizzled/qsort_cmp.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
24
class Item_bool_func2;
43
25
class Arg_comparator;
44
 
class Item_sum_hybrid;
45
 
class Item_row;
46
26
 
47
27
typedef int (Arg_comparator::*arg_cmp_func)();
48
28
 
49
 
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
50
 
 
51
 
uint64_t get_datetime_value(Session *session, 
52
 
                            Item ***item_arg, 
53
 
                            Item **cache_arg,
54
 
                            Item *warn_item, 
55
 
                            bool *is_null);
56
 
 
57
 
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
58
32
{
59
33
  Item **a, **b;
60
34
  arg_cmp_func func;
62
36
  Arg_comparator *comparators;   // used only for compare_row()
63
37
  double precision;
64
38
  /* Fields used in DATE/DATETIME comparison. */
65
 
  Session *session;
 
39
  THD *thd;
66
40
  enum_field_types a_type, b_type; // Types of a and b items
67
41
  Item *a_cache, *b_cache;         // Cached values of a and b items
68
42
  bool is_nulls_eq;                // TRUE <=> compare for the EQUAL_FUNC
69
43
  enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE,
70
44
                            CMP_DATE_WITH_STR, CMP_STR_WITH_DATE };
71
 
  uint64_t (*get_value_func)(Session *session, Item ***item_arg, Item **cache_arg,
 
45
  ulonglong (*get_value_func)(THD *thd, Item ***item_arg, Item **cache_arg,
72
46
                              Item *warn_item, bool *is_null);
73
47
public:
74
48
  DTCollation cmp_collation;
75
49
 
76
 
  Arg_comparator(): session(0), a_cache(0), b_cache(0) {};
77
 
  Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), session(0),
 
50
  Arg_comparator(): thd(0), a_cache(0), b_cache(0) {};
 
51
  Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), thd(0),
78
52
    a_cache(0), b_cache(0) {};
79
53
 
80
54
  int set_compare_func(Item_bool_func2 *owner, Item_result type);
117
91
  int compare_datetime();        // compare args[0] & args[1] as DATETIMEs
118
92
 
119
93
  static enum enum_date_cmp_type can_compare_as_dates(Item *a, Item *b,
120
 
                                                      uint64_t *const_val_arg);
 
94
                                                      ulonglong *const_val_arg);
121
95
 
122
96
  void set_datetime_cmp_func(Item **a1, Item **b1);
123
97
  static arg_cmp_func comparator_matrix [5][2];
131
105
  Item_bool_func() :Item_int_func() {}
132
106
  Item_bool_func(Item *a) :Item_int_func(a) {}
133
107
  Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
134
 
  Item_bool_func(Session *session, Item_bool_func *item) :Item_int_func(session, item) {}
 
108
  Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {}
135
109
  bool is_bool_func() { return 1; }
136
110
  void fix_length_and_dec() { decimals=0; max_length=1; }
137
 
  uint32_t decimal_precision() const { return 1; }
 
111
  uint decimal_precision() const { return 1; }
138
112
};
139
113
 
140
114
 
147
121
{
148
122
public:
149
123
  virtual bool val_bool();
150
 
  virtual int64_t val_int();
 
124
  virtual longlong val_int();
151
125
  virtual void fix_length_and_dec();
152
126
  virtual void print(String *str, enum_query_type query_type);
153
127
 
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
/*
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_bool_func(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
 
  int64_t val_int();
 
239
  longlong 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
 
392
371
{
393
372
public:
394
373
  Item_func_not(Item *a) :Item_bool_func(a) {}
395
 
  int64_t val_int();
 
374
  longlong 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
435
414
  bool *trig_var;
436
415
public:
437
416
  Item_func_trig_cond(Item *a, bool *f) : Item_bool_func(a) { trig_var= f; }
438
 
  int64_t val_int() { return *trig_var ? args[0]->val_int() : 1; }
 
417
  longlong 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"; };
441
420
  bool const_item() const { return false; }
460
439
    {}
461
440
  virtual void top_level_item() { abort_on_null= 1; }
462
441
  bool top_level() { return abort_on_null; }
463
 
  int64_t val_int();
 
442
  longlong val_int();
464
443
  enum Functype functype() const { return NOT_ALL_FUNC; }
465
444
  const char *func_name() const { return "<not>"; }
466
445
  virtual void print(String *str, enum_query_type query_type);
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
 
476
455
public:
477
456
 
478
457
  Item_func_nop_all(Item *a) :Item_func_not_all(a) {}
479
 
  int64_t val_int();
 
458
  longlong 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
 
486
465
{
487
466
public:
488
467
  Item_func_eq(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
489
 
  int64_t val_int();
 
468
  longlong val_int();
490
469
  enum Functype functype() const { return EQ_FUNC; }
491
470
  enum Functype rev_functype() const { return EQ_FUNC; }
492
471
  cond_result eq_cmp_result() const { return COND_TRUE; }
498
477
{
499
478
public:
500
479
  Item_func_equal(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
501
 
  int64_t val_int();
 
480
  longlong val_int();
502
481
  void fix_length_and_dec();
503
482
  table_map not_null_tables() const { return 0; }
504
483
  enum Functype functype() const { return EQUAL_FUNC; }
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
 
513
492
{
514
493
public:
515
494
  Item_func_ge(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
516
 
  int64_t val_int();
 
495
  longlong val_int();
517
496
  enum Functype functype() const { return GE_FUNC; }
518
497
  enum Functype rev_functype() const { return LE_FUNC; }
519
498
  cond_result eq_cmp_result() const { return COND_TRUE; }
526
505
{
527
506
public:
528
507
  Item_func_gt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
529
 
  int64_t val_int();
 
508
  longlong val_int();
530
509
  enum Functype functype() const { return GT_FUNC; }
531
510
  enum Functype rev_functype() const { return LT_FUNC; }
532
511
  cond_result eq_cmp_result() const { return COND_FALSE; }
539
518
{
540
519
public:
541
520
  Item_func_le(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {};
542
 
  int64_t val_int();
 
521
  longlong val_int();
543
522
  enum Functype functype() const { return LE_FUNC; }
544
523
  enum Functype rev_functype() const { return GE_FUNC; }
545
524
  cond_result eq_cmp_result() const { return COND_TRUE; }
552
531
{
553
532
public:
554
533
  Item_func_lt(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
555
 
  int64_t val_int();
 
534
  longlong val_int();
556
535
  enum Functype functype() const { return LT_FUNC; }
557
536
  enum Functype rev_functype() const { return GT_FUNC; }
558
537
  cond_result eq_cmp_result() const { return COND_FALSE; }
565
544
{
566
545
public:
567
546
  Item_func_ne(Item *a,Item *b) :Item_bool_rowready_func2(a,b) {}
568
 
  int64_t val_int();
 
547
  longlong 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
 
619
598
  Arg_comparator ge_cmp, le_cmp;
620
599
  Item_func_between(Item *a, Item *b, Item *c)
621
600
    :Item_func_opt_neg(a, b, c), compare_as_dates(false) {}
622
 
  int64_t val_int();
 
601
  longlong val_int();
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
 
636
615
{
637
616
public:
638
617
  Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {}
639
 
  int64_t val_int();
 
618
  longlong val_int();
640
619
  optimize_type select_optimize() const { return OPTIMIZE_NONE; }
641
620
  const char *func_name() const { return "strcmp"; }
642
621
 
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)
665
644
  {
666
645
    allowed_arg_cols= 0;    // Fetch this value from first argument
667
646
  }
668
 
  int64_t val_int();
 
647
  longlong 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
 
680
659
public:
681
660
  Item_func_coalesce(List<Item> &list) :Item_func_numhybrid(list) {}
682
661
  double real_op();
683
 
  int64_t int_op();
 
662
  longlong int_op();
684
663
  String *str_op(String *);
685
664
  my_decimal *decimal_op(my_decimal *);
686
665
  void fix_length_and_dec();
699
678
public:
700
679
  Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
701
680
  double real_op();
702
 
  int64_t int_op();
 
681
  longlong int_op();
703
682
  String *str_op(String *str);
704
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
 
723
698
    :Item_func(a,b,c), cached_result_type(INT_RESULT)
724
699
  {}
725
700
  double val_real();
726
 
  int64_t val_int();
 
701
  longlong val_int();
727
702
  String *val_str(String *str);
728
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
 
743
718
    :Item_bool_func2(a,b), cached_result_type(INT_RESULT)
744
719
  {}
745
720
  double val_real();
746
 
  int64_t val_int();
 
721
  longlong val_int();
747
722
  String *val_str(String *str);
748
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;
837
816
  Item_result result_type() { return STRING_RESULT; }
838
817
};
839
818
 
840
 
class in_int64_t :public in_vector
 
819
class in_longlong :public in_vector
841
820
{
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_longlong 
849
828
  {
850
 
    int64_t val;
851
 
    int64_t unsigned_flag;  // Use int64_t, not bool, to preserve alignment
 
829
    longlong val;
 
830
    longlong unsigned_flag;  // Use longlong, 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_longlong(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
 
    return new Item_int((int64_t)0);
 
843
    return new Item_int((longlong)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
 
    ((Item_int*) item)->value= ((packed_int64_t*) base)[pos].val;
869
 
    ((Item_int*) item)->unsigned_flag= (bool)
870
 
      ((packed_int64_t*) base)[pos].unsigned_flag;
 
847
    ((Item_int*) item)->value= ((packed_longlong*) base)[pos].val;
 
848
    ((Item_int*) item)->unsigned_flag= (my_bool)
 
849
      ((packed_longlong*) base)[pos].unsigned_flag;
871
850
  }
872
851
  Item_result result_type() { return INT_RESULT; }
873
852
 
874
 
  friend int cmp_int64_t(void *cmp_arg, packed_int64_t *a,packed_int64_t *b);
 
853
  friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
875
854
};
876
855
 
877
856
 
881
860
  If the left item is a constant one then its value is cached in the
882
861
  lval_cache variable.
883
862
*/
884
 
class in_datetime :public in_int64_t
 
863
class in_datetime :public in_longlong
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_longlong(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);
898
 
  friend int cmp_int64_t(void *cmp_arg, packed_int64_t *a,packed_int64_t *b);
 
875
  void set(uint pos,Item *item);
 
876
  uchar *get_value(Item *item);
 
877
  friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
899
878
};
900
879
 
901
880
 
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
  }
922
901
{
923
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
913
    my_decimal *dec= ((my_decimal *)base) + pos;
935
914
    Item_decimal *item_dec= (Item_decimal*)item;
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;
 
929
  CHARSET_INFO *cmp_charset;
951
930
  cmp_item() { cmp_charset= &my_charset_bin; }
952
931
  virtual ~cmp_item() {}
953
932
  virtual void store_value(Item *item)= 0;
954
933
  virtual int cmp(Item *item)= 0;
955
934
  // for optimized IN with row
956
935
  virtual int compare(cmp_item *item)= 0;
957
 
  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);
958
937
  virtual cmp_item *make_same()= 0;
959
 
  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)
960
940
  {
961
941
    store_value(item);
962
942
  }
963
943
};
964
944
 
965
 
class cmp_item_string :public cmp_item
 
945
class cmp_item_string :public cmp_item 
966
946
{
967
947
protected:
968
948
  String *value_res;
969
949
public:
970
950
  cmp_item_string () {}
971
 
  cmp_item_string (const CHARSET_INFO * const cs) { cmp_charset= cs; }
972
 
  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; }
973
953
  friend class cmp_item_sort_string;
974
954
  friend class cmp_item_sort_string_in_static;
975
955
};
982
962
public:
983
963
  cmp_item_sort_string():
984
964
    cmp_item_string() {}
985
 
  cmp_item_sort_string(const CHARSET_INFO * const cs):
 
965
  cmp_item_sort_string(CHARSET_INFO *cs):
986
966
    cmp_item_string(cs),
987
967
    value(value_buff, sizeof(value_buff), cs) {}
988
968
  void store_value(Item *item)
1001
981
  {
1002
982
    cmp_item_string *l_cmp= (cmp_item_string *) ci;
1003
983
    return sortcmp(value_res, l_cmp->value_res, cmp_charset);
1004
 
  }
 
984
  } 
1005
985
  cmp_item *make_same();
1006
 
  void set_charset(const CHARSET_INFO * const cs)
 
986
  void set_charset(CHARSET_INFO *cs)
1007
987
  {
1008
988
    cmp_charset= cs;
1009
989
    value.set_quick(value_buff, sizeof(value_buff), cs);
1012
992
 
1013
993
class cmp_item_int :public cmp_item
1014
994
{
1015
 
  int64_t value;
 
995
  longlong value;
1016
996
public:
1017
997
  cmp_item_int() {}                           /* Remove gcc warning */
1018
998
  void store_value(Item *item)
1039
1019
*/
1040
1020
class cmp_item_datetime :public cmp_item
1041
1021
{
1042
 
  uint64_t value;
 
1022
  ulonglong value;
1043
1023
public:
1044
 
  Session *session;
 
1024
  THD *thd;
1045
1025
  /* Item used for issuing warnings. */
1046
1026
  Item *warn_item;
1047
1027
  /* Cache for the left item. */
1048
1028
  Item *lval_cache;
1049
1029
 
1050
1030
  cmp_item_datetime(Item *warn_item_arg)
1051
 
    :session(current_session), warn_item(warn_item_arg), lval_cache(0) {}
 
1031
    :thd(current_thd), warn_item(warn_item_arg), lval_cache(0) {}
1052
1032
  void store_value(Item *item);
1053
1033
  int cmp(Item *arg);
1054
1034
  int compare(cmp_item *ci);
1089
1069
};
1090
1070
 
1091
1071
 
1092
 
/*
 
1072
/* 
1093
1073
   cmp_item for optimized IN with row (right part string, which never
1094
1074
   be changed)
1095
1075
*/
1099
1079
 protected:
1100
1080
  String value;
1101
1081
public:
1102
 
  cmp_item_sort_string_in_static(const CHARSET_INFO * const cs):
 
1082
  cmp_item_sort_string_in_static(CHARSET_INFO *cs):
1103
1083
    cmp_item_string(cs) {}
1104
1084
  void store_value(Item *item)
1105
1085
  {
1106
1086
    value_res= item->val_str(&value);
1107
1087
  }
1108
 
  int cmp(Item *)
 
1088
  int cmp(Item *item __attribute__((__unused__)))
1109
1089
  {
1110
1090
    // Should never be called
1111
1091
    assert(0);
1127
1107
  The class Item_func_case is the CASE ... WHEN ... THEN ... END function
1128
1108
  implementation.
1129
1109
 
1130
 
  When there is no expression between CASE and the first WHEN
 
1110
  When there is no expression between CASE and the first WHEN 
1131
1111
  (the CASE expression) then this function simple checks all WHEN expressions
1132
1112
  one after another. When some WHEN expression evaluated to TRUE then the
1133
1113
  value of the corresponding THEN expression is returned.
1146
1126
  int first_expr_num, else_expr_num;
1147
1127
  enum Item_result cached_result_type, left_result_type;
1148
1128
  String tmp_value;
1149
 
  uint32_t ncases;
 
1129
  uint ncases;
1150
1130
  Item_result cmp_type;
1151
1131
  DTCollation cmp_collation;
1152
1132
  enum_field_types cached_field_type;
1153
 
  cmp_item *cmp_items[DECIMAL_RESULT+1]; /* For all result types */
 
1133
  cmp_item *cmp_items[5]; /* For all result types */
1154
1134
  cmp_item *case_item;
1155
1135
public:
1156
1136
  Item_func_case(List<Item> &list, Item *first_expr_arg, Item *else_expr_arg)
1169
1149
      list.push_back(else_expr_arg);
1170
1150
    }
1171
1151
    set_arguments(list);
1172
 
    memset(&cmp_items, 0, sizeof(cmp_items));
 
1152
    bzero(&cmp_items, sizeof(cmp_items));
1173
1153
  }
1174
1154
  double val_real();
1175
 
  int64_t val_int();
 
1155
  longlong val_int();
1176
1156
  String *val_str(String *);
1177
1157
  my_decimal *val_decimal(my_decimal *);
1178
 
  bool fix_fields(Session *session, Item **ref);
 
1158
  bool fix_fields(THD *thd, Item **ref);
1179
1159
  void fix_length_and_dec();
1180
 
  uint32_t decimal_precision() const;
 
1160
  uint decimal_precision() const;
1181
1161
  table_map not_null_tables() const { return 0; }
1182
1162
  enum Item_result result_type () const { return cached_result_type; }
1183
1163
  enum_field_types field_type() const { return cached_field_type; }
1184
1164
  const char *func_name() const { return "case"; }
1185
1165
  virtual void print(String *str, enum_query_type query_type);
1186
1166
  Item *find_item(String *str);
1187
 
  const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
 
1167
  CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1188
1168
  void cleanup();
1189
1169
  void agg_str_lengths(Item *arg);
1190
1170
  void agg_num_lengths(Item *arg);
1207
1187
class Item_func_in :public Item_func_opt_neg
1208
1188
{
1209
1189
public:
1210
 
  /*
 
1190
  /* 
1211
1191
    an array of values when the right hand arguments of IN
1212
 
    are all SQL constant and there are no nulls
 
1192
    are all SQL constant and there are no nulls 
1213
1193
  */
1214
1194
  in_vector *array;
1215
1195
  bool have_null;
1216
 
  /*
 
1196
  /* 
1217
1197
    true when all arguments of the IN clause are of compatible types
1218
1198
    and can be used safely as comparisons for key conditions
1219
1199
  */
1226
1206
    :Item_func_opt_neg(list), array(0), have_null(0),
1227
1207
    arg_types_compatible(false)
1228
1208
  {
1229
 
    memset(&cmp_items, 0, sizeof(cmp_items));
 
1209
    bzero(&cmp_items, sizeof(cmp_items));
1230
1210
    allowed_arg_cols= 0;  // Fetch this value from first argument
1231
1211
  }
1232
 
  int64_t val_int();
1233
 
  bool fix_fields(Session *, Item **);
 
1212
  longlong val_int();
 
1213
  bool fix_fields(THD *, Item **);
1234
1214
  void fix_length_and_dec();
1235
 
  uint32_t decimal_precision() const { return 1; }
 
1215
  uint decimal_precision() const { return 1; }
1236
1216
  void cleanup()
1237
1217
  {
 
1218
    uint i;
1238
1219
    Item_int_func::cleanup();
1239
1220
    delete array;
1240
1221
    array= 0;
1241
 
    for (int i= STRING_RESULT; i <= DECIMAL_RESULT; i++)
 
1222
    for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
1242
1223
    {
1243
1224
      delete cmp_items[i];
1244
1225
      cmp_items[i]= 0;
1252
1233
  const char *func_name() const { return " IN "; }
1253
1234
  bool nulls_in_row();
1254
1235
  bool is_bool_func() { return 1; }
1255
 
  const CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
 
1236
  CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
1256
1237
};
1257
1238
 
1258
1239
class cmp_item_row :public cmp_item
1259
1240
{
1260
1241
  cmp_item **comparators;
1261
 
  uint32_t n;
 
1242
  uint n;
1262
1243
public:
1263
1244
  cmp_item_row(): comparators(0), n(0) {}
1264
1245
  ~cmp_item_row();
1276
1257
{
1277
1258
  cmp_item_row tmp;
1278
1259
public:
1279
 
  in_row(uint32_t elements, Item *);
 
1260
  in_row(uint elements, Item *);
1280
1261
  ~in_row();
1281
 
  void set(uint32_t pos,Item *item);
1282
 
  unsigned char *get_value(Item *item);
 
1262
  void set(uint pos,Item *item);
 
1263
  uchar *get_value(Item *item);
1283
1264
  friend void Item_func_in::fix_length_and_dec();
1284
1265
  Item_result result_type() { return ROW_RESULT; }
1285
1266
};
1289
1270
class Item_func_isnull :public Item_bool_func
1290
1271
{
1291
1272
protected:
1292
 
  int64_t cached_value;
 
1273
  longlong cached_value;
1293
1274
public:
1294
1275
  Item_func_isnull(Item *a) :Item_bool_func(a) {}
1295
 
  int64_t val_int();
 
1276
  longlong val_int();
1296
1277
  enum Functype functype() const { return ISNULL_FUNC; }
1297
1278
  void fix_length_and_dec()
1298
1279
  {
1307
1288
    {
1308
1289
      used_tables_cache= 0;                     /* is always false */
1309
1290
      const_item_cache= 1;
1310
 
      cached_value= (int64_t) 0;
 
1291
      cached_value= (longlong) 0;
1311
1292
    }
1312
1293
    else
1313
1294
    {
1316
1297
          !with_subselect)
1317
1298
      {
1318
1299
        /* Remember if the value is always NULL or never NULL */
1319
 
        cached_value= (int64_t) args[0]->is_null();
 
1300
        cached_value= (longlong) args[0]->is_null();
1320
1301
      }
1321
1302
    }
1322
1303
  }
1323
1304
  table_map not_null_tables() const { return 0; }
1324
1305
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1325
 
  Item *neg_transformer(Session *session);
1326
 
  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; }
1327
1308
};
1328
1309
 
1329
1310
/* Functions used by HAVING for rewriting IN subquery */
1330
1311
 
1331
1312
class Item_in_subselect;
1332
1313
 
1333
 
/*
 
1314
/* 
1334
1315
  This is like IS NOT NULL but it also remembers if it ever has
1335
1316
  encountered a NULL.
1336
1317
*/
1342
1323
    :Item_func_isnull(a), owner(ow)
1343
1324
  {}
1344
1325
  enum Functype functype() const { return ISNOTNULLTEST_FUNC; }
1345
 
  int64_t val_int();
 
1326
  longlong val_int();
1346
1327
  const char *func_name() const { return "<is_not_null_test>"; }
1347
1328
  void update_used_tables();
1348
1329
  /*
1358
1339
  bool abort_on_null;
1359
1340
public:
1360
1341
  Item_func_isnotnull(Item *a) :Item_bool_func(a), abort_on_null(0) {}
1361
 
  int64_t val_int();
 
1342
  longlong val_int();
1362
1343
  enum Functype functype() const { return ISNOTNULL_FUNC; }
1363
1344
  void fix_length_and_dec()
1364
1345
  {
1368
1349
  optimize_type select_optimize() const { return OPTIMIZE_NULL; }
1369
1350
  table_map not_null_tables() const
1370
1351
  { return abort_on_null ? not_null_tables_cache : 0; }
1371
 
  Item *neg_transformer(Session *session);
 
1352
  Item *neg_transformer(THD *thd);
1372
1353
  virtual void print(String *str, enum_query_type query_type);
1373
 
  const CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
 
1354
  CHARSET_INFO *compare_collation() { return args[0]->collation.collation; }
1374
1355
  void top_level_item() { abort_on_null=1; }
1375
1356
};
1376
1357
 
1393
1374
  enum { alphabet_size = 256 };
1394
1375
 
1395
1376
  Item *escape_item;
1396
 
 
 
1377
  
1397
1378
  bool escape_used_in_parsing;
1398
1379
 
1399
 
 
1400
1380
public:
1401
 
 
1402
 
  char *escape;
 
1381
  int escape;
1403
1382
 
1404
1383
  Item_func_like(Item *a,Item *b, Item *escape_arg, bool escape_used)
1405
 
    :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), 
1406
1385
     bmGs(0), bmBc(0), escape_item(escape_arg),
1407
 
     escape_used_in_parsing(escape_used), escape(NULL) {}
1408
 
  int64_t val_int();
 
1386
     escape_used_in_parsing(escape_used) {}
 
1387
  longlong val_int();
1409
1388
  enum Functype functype() const { return LIKE_FUNC; }
1410
1389
  optimize_type select_optimize() const;
1411
1390
  cond_result eq_cmp_result() const { return COND_TRUE; }
1412
1391
  const char *func_name() const { return "like"; }
1413
 
  bool fix_fields(Session *session, Item **ref);
 
1392
  bool fix_fields(THD *thd, Item **ref);
1414
1393
  void cleanup();
1415
1394
};
1416
1395
 
1425
1404
  table_map and_tables_cache;
1426
1405
 
1427
1406
public:
1428
 
 
1429
 
  using Item::split_sum_func;
1430
 
 
1431
1407
  /* Item_cond() is only used to create top level items */
1432
1408
  Item_cond(): Item_bool_func(), abort_on_null(1)
1433
1409
  { const_item_cache=0; }
1437
1413
    list.push_back(i1);
1438
1414
    list.push_back(i2);
1439
1415
  }
1440
 
  Item_cond(Session *session, Item_cond *item);
 
1416
  Item_cond(THD *thd, Item_cond *item);
1441
1417
  Item_cond(List<Item> &nlist)
1442
1418
    :Item_bool_func(), list(nlist), abort_on_null(0) {}
1443
1419
  bool add(Item *item) { return list.push_back(item); }
1444
1420
  bool add_at_head(Item *item) { return list.push_front(item); }
1445
1421
  void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
1446
 
  bool fix_fields(Session *, Item **ref);
1447
 
  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);
1448
1424
 
1449
1425
  enum Type type() const { return COND_ITEM; }
1450
1426
  List<Item>* argument_list() { return &list; }
1451
1427
  table_map used_tables() const;
1452
1428
  void update_used_tables();
1453
1429
  virtual void print(String *str, enum_query_type query_type);
1454
 
  void split_sum_func(Session *session, Item **ref_pointer_array, List<Item> &fields);
1455
 
  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,
1456
1432
                         COND **conds);
1457
1433
  void top_level_item() { abort_on_null=1; }
1458
 
  void copy_andor_arguments(Session *session, Item_cond *item);
1459
 
  bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1460
 
  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);
1461
1437
  void traverse_cond(Cond_traverser, void *arg, traverse_order order);
1462
 
  void neg_arguments(Session *session);
1463
 
  enum_field_types field_type() const { return DRIZZLE_TYPE_LONGLONG; }
1464
 
  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__)))
1465
1441
  { return true; }
1466
 
  Item *compile(Item_analyzer analyzer, unsigned char **arg_p,
1467
 
                Item_transformer transformer, unsigned char *arg_t);
 
1442
  Item *compile(Item_analyzer analyzer, uchar **arg_p,
 
1443
                Item_transformer transformer, uchar *arg_t);
1468
1444
};
1469
1445
 
1470
1446
 
1485
1461
  A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
1486
1462
  substituted for the item representing the same multiple equality
1487
1463
  f1=f2=f3.
1488
 
  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 
1489
1465
  f2=f1 and f1=f2, or instead of just the predicate f1=f2.
1490
1466
 
1491
 
  An item of the class Item_equal inherits equalities from outer
 
1467
  An item of the class Item_equal inherits equalities from outer 
1492
1468
  conjunctive levels.
1493
1469
 
1494
1470
  Suppose we have a where condition of the following form:
1499
1475
    f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
1500
1476
 
1501
1477
  An object of the class Item_equal can contain an optional constant
1502
 
  item c. Then it represents a multiple equality of the form
 
1478
  item c. Then it represents a multiple equality of the form 
1503
1479
  c=f1=...=fk.
1504
1480
 
1505
1481
  Objects of the class Item_equal are used for the following:
1514
1490
  It also can give us additional index scans and can allow us to
1515
1491
  improve selectivity estimates.
1516
1492
 
1517
 
  3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the
1518
 
  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 
1519
1495
  before the table tj then in any predicate P in the where condition
1520
1496
  the occurrence of tj.fj is substituted for ti.fi. This can allow
1521
1497
  an evaluation of the predicate at an earlier step.
1522
1498
 
1523
 
  When feature 1 is supported they say that join transitive closure
 
1499
  When feature 1 is supported they say that join transitive closure 
1524
1500
  is employed.
1525
1501
  When feature 2 is supported they say that search argument transitive
1526
1502
  closure is employed.
1529
1505
  We do not just add predicates, we rather dynamically replace some
1530
1506
  predicates that can not be used to access tables in the investigated
1531
1507
  plan for those, obtained by substitution of some fields for equal fields,
1532
 
  that can be used.
 
1508
  that can be used.     
1533
1509
 
1534
1510
  Prepared Statements/Stored Procedures note: instances of class
1535
1511
  Item_equal are created only at the time a PS/SP is executed and
1559
1535
  inline Item* get_const() { return const_item; }
1560
1536
  void add(Item *c);
1561
1537
  void add(Item_field *f);
1562
 
  uint32_t members();
 
1538
  uint members();
1563
1539
  bool contains(Field *field);
1564
1540
  Item_field* get_first() { return fields.head(); }
1565
1541
  void merge(Item_equal *item);
1566
1542
  void update_const();
1567
1543
  enum Functype functype() const { return MULT_EQUAL_FUNC; }
1568
 
  int64_t val_int();
 
1544
  longlong val_int(); 
1569
1545
  const char *func_name() const { return "multiple equal"; }
1570
1546
  optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
1571
1547
  void sort(Item_field_cmpfunc cmp, void *arg);
1572
1548
  friend class Item_equal_iterator;
1573
1549
  void fix_length_and_dec();
1574
 
  bool fix_fields(Session *session, Item **ref);
 
1550
  bool fix_fields(THD *thd, Item **ref);
1575
1551
  void update_used_tables();
1576
 
  bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1577
 
  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);
1578
1554
  virtual void print(String *str, enum_query_type query_type);
1579
 
  const CHARSET_INFO *compare_collation()
 
1555
  CHARSET_INFO *compare_collation() 
1580
1556
  { return fields.head()->collation.collation; }
1581
 
};
 
1557
}; 
1582
1558
 
1583
 
class COND_EQUAL: public memory::SqlAlloc
 
1559
class COND_EQUAL: public Sql_alloc
1584
1560
{
1585
1561
public:
1586
 
  uint32_t max_members;               /* max number of members the current level
1587
 
                                     list and all lower level lists */
 
1562
  uint max_members;               /* max number of members the current level
 
1563
                                     list and all lower level lists */ 
1588
1564
  COND_EQUAL *upper_levels;       /* multiple equalities of upper and levels */
1589
 
  List<Item_equal> current_level; /* list of multiple equalities of
 
1565
  List<Item_equal> current_level; /* list of multiple equalities of 
1590
1566
                                     the current and level           */
1591
1567
  COND_EQUAL()
1592
 
  {
 
1568
  { 
1593
1569
    upper_levels= 0;
1594
1570
  }
1595
1571
};
1598
1574
class Item_equal_iterator : public List_iterator_fast<Item_field>
1599
1575
{
1600
1576
public:
1601
 
  inline Item_equal_iterator(Item_equal &item_equal)
 
1577
  inline Item_equal_iterator(Item_equal &item_equal) 
1602
1578
    :List_iterator_fast<Item_field> (item_equal.fields)
1603
1579
  {}
1604
1580
  inline Item_field* operator++(int)
1605
 
  {
 
1581
  { 
1606
1582
    Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
1607
1583
    return  item;
1608
1584
  }
1609
 
  inline void rewind(void)
1610
 
  {
 
1585
  inline void rewind(void) 
 
1586
  { 
1611
1587
    List_iterator_fast<Item_field>::rewind();
1612
1588
  }
1613
1589
};
1615
1591
class Item_cond_and :public Item_cond
1616
1592
{
1617
1593
public:
1618
 
  COND_EQUAL cond_equal;  /* contains list of Item_equal objects for
 
1594
  COND_EQUAL cond_equal;  /* contains list of Item_equal objects for 
1619
1595
                             the current and level and reference
1620
 
                             to multiple equalities of upper and levels */
 
1596
                             to multiple equalities of upper and levels */  
1621
1597
  Item_cond_and() :Item_cond() {}
1622
1598
  Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1623
 
  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) {}
1624
1600
  Item_cond_and(List<Item> &list_arg): Item_cond(list_arg) {}
1625
1601
  enum Functype functype() const { return COND_AND_FUNC; }
1626
 
  int64_t val_int();
 
1602
  longlong val_int();
1627
1603
  const char *func_name() const { return "and"; }
1628
1604
  table_map not_null_tables() const
1629
1605
  { return abort_on_null ? not_null_tables_cache: and_tables_cache; }
1630
 
  Item* copy_andor_structure(Session *session)
 
1606
  Item* copy_andor_structure(THD *thd)
1631
1607
  {
1632
1608
    Item_cond_and *item;
1633
 
    if ((item= new Item_cond_and(session, this)))
1634
 
       item->copy_andor_arguments(session, this);
 
1609
    if ((item= new Item_cond_and(thd, this)))
 
1610
       item->copy_andor_arguments(thd, this);
1635
1611
    return item;
1636
1612
  }
1637
 
  Item *neg_transformer(Session *session);
 
1613
  Item *neg_transformer(THD *thd);
1638
1614
};
1639
1615
 
1640
1616
inline bool is_cond_and(Item *item)
1651
1627
public:
1652
1628
  Item_cond_or() :Item_cond() {}
1653
1629
  Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1654
 
  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) {}
1655
1631
  Item_cond_or(List<Item> &list_arg): Item_cond(list_arg) {}
1656
1632
  enum Functype functype() const { return COND_OR_FUNC; }
1657
 
  int64_t val_int();
 
1633
  longlong val_int();
1658
1634
  const char *func_name() const { return "or"; }
1659
1635
  table_map not_null_tables() const { return and_tables_cache; }
1660
 
  Item* copy_andor_structure(Session *session)
 
1636
  Item* copy_andor_structure(THD *thd)
1661
1637
  {
1662
1638
    Item_cond_or *item;
1663
 
    if ((item= new Item_cond_or(session, this)))
1664
 
      item->copy_andor_arguments(session, this);
 
1639
    if ((item= new Item_cond_or(thd, this)))
 
1640
      item->copy_andor_arguments(thd, this);
1665
1641
    return item;
1666
1642
  }
1667
 
  Item *neg_transformer(Session *session);
 
1643
  Item *neg_transformer(THD *thd);
1668
1644
};
1669
1645
 
1670
1646
inline bool is_cond_or(Item *item)
1689
1665
  enum Functype functype() const { return COND_XOR_FUNC; }
1690
1666
  /* TODO: remove the next line when implementing XOR optimization */
1691
1667
  enum Type type() const { return FUNC_ITEM; }
1692
 
  int64_t val_int();
 
1668
  longlong val_int();
1693
1669
  const char *func_name() const { return "xor"; }
1694
1670
  void top_level_item() {}
1695
1671
};
1696
1672
 
1697
 
enum_field_types agg_field_type(Item **items, uint32_t nitems);
1698
 
 
1699
1673
 
1700
1674
/* Some useful inline functions */
1701
1675
 
1707
1681
}
1708
1682
 
1709
1683
Item *and_expressions(Item *a, Item *b, Item **org_item);
1710
 
 
1711
 
} /* namespace drizzled */
1712
 
 
1713
 
#endif /* DRIZZLED_ITEM_CMPFUNC_H */