~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/cmpfunc.h

  • Committer: Monty Taylor
  • Date: 2008-11-16 23:47:43 UTC
  • mto: (584.1.10 devel)
  • mto: This revision was merged to the branch mainline in revision 589.
  • Revision ID: monty@inaugust.com-20081116234743-c38gmv0pa2kdefaj
Broke out cached_item.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
/* compare and test functions */
24
24
 
25
 
#include "drizzled/comp_creator.h"
26
 
#include "drizzled/item/row.h"
27
 
#include "drizzled/item/sum.h"
28
 
#include "drizzled/item/int.h"
29
 
#include "drizzled/item/float.h"
30
 
#include "drizzled/item/decimal.h"
31
 
#include "drizzled/function/math/int.h"
32
 
#include "drizzled/function/numhybrid.h"
33
 
#include "drizzled/session.h"
34
 
#include "drizzled/common.h"
35
 
#include "drizzled/qsort_cmp.h"
36
 
 
37
 
namespace drizzled
38
 
{
 
25
#include <drizzled/comp_creator.h>
 
26
#include <drizzled/item/row.h>
 
27
#include <drizzled/item/sum.h>
39
28
 
40
29
extern Item_result item_cmp_type(Item_result a,Item_result b);
41
30
class Item_bool_func2;
45
34
 
46
35
typedef int (Arg_comparator::*arg_cmp_func)();
47
36
 
48
 
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg);
49
 
 
50
 
uint64_t get_datetime_value(Session *session, 
51
 
                            Item ***item_arg, 
52
 
                            Item **cache_arg,
53
 
                            Item *warn_item, 
54
 
                            bool *is_null);
55
 
 
56
 
class Arg_comparator: public memory::SqlAlloc
 
37
typedef int (*Item_field_cmpfunc)(Item_field *f1, Item_field *f2, void *arg); 
 
38
 
 
39
class Arg_comparator: public Sql_alloc
57
40
{
58
41
  Item **a, **b;
59
42
  arg_cmp_func func;
246
229
protected:
247
230
  Item_cache *cache;
248
231
  bool save_cache;
249
 
  /*
 
232
  /* 
250
233
    Stores the value of "NULL IN (SELECT ...)" for uncorrelated subqueries:
251
234
      UNKNOWN - "NULL in (SELECT ...)" has not yet been evaluated
252
235
      FALSE   - result is FALSE
383
366
  }
384
367
  Item *neg_transformer(Session *session);
385
368
  virtual Item *negated_item();
386
 
  bool subst_argument_checker(unsigned char **)
 
369
  bool subst_argument_checker(unsigned char **arg __attribute__((unused)))
387
370
  { return true; }
388
371
};
389
372
 
403
386
/*
404
387
  trigcond<param>(arg) ::= param? arg : TRUE
405
388
 
406
 
  The class Item_func_trig_cond is used for guarded predicates
 
389
  The class Item_func_trig_cond is used for guarded predicates 
407
390
  which are employed only for internal purposes.
408
391
  A guarded predicate is an object consisting of an a regular or
409
 
  a guarded predicate P and a pointer to a boolean guard variable g.
 
392
  a guarded predicate P and a pointer to a boolean guard variable g. 
410
393
  A guarded predicate P/g is evaluated to true if the value of the
411
394
  guard g is false, otherwise it is evaluated to the same value that
412
395
  the predicate P: val(P/g)= g ? val(P):true.
418
401
  the objects consisting of three elements: a predicate P, a pointer
419
402
  to a variable g and a firing value s with following evaluation
420
403
  rule: val(P/g,s)= g==s? val(P) : true. It will allow us to build only
421
 
  one item for the objects of the form P/g1/g2...
 
404
  one item for the objects of the form P/g1/g2... 
422
405
 
423
406
  Objects of this class are built only for query execution after
424
407
  the execution plan has been already selected. That's why this
425
 
  class needs only val_int out of generic methods.
426
 
 
 
408
  class needs only val_int out of generic methods. 
 
409
 
427
410
  Current uses of Item_func_trig_cond objects:
428
411
   - To wrap selection conditions when executing outer joins
429
412
   - To wrap condition that is pushed down into subquery
504
487
  enum Functype rev_functype() const { return EQUAL_FUNC; }
505
488
  cond_result eq_cmp_result() const { return COND_TRUE; }
506
489
  const char *func_name() const { return "<=>"; }
507
 
  Item *neg_transformer(Session *) { return 0; }
 
490
  Item *neg_transformer(Session *session __attribute__((unused))) { return 0; }
508
491
};
509
492
 
510
493
 
567
550
  int64_t val_int();
568
551
  enum Functype functype() const { return NE_FUNC; }
569
552
  cond_result eq_cmp_result() const { return COND_FALSE; }
570
 
  optimize_type select_optimize() const { return OPTIMIZE_KEY; }
 
553
  optimize_type select_optimize() const { return OPTIMIZE_KEY; } 
571
554
  const char *func_name() const { return "<>"; }
572
555
  Item *negated_item();
573
556
};
595
578
public:
596
579
  inline void negate() { negated= !negated; }
597
580
  inline void top_level_item() { pred_level= 1; }
598
 
  Item *neg_transformer(Session *)
 
581
  Item *neg_transformer(Session *session __attribute__((unused)))
599
582
  {
600
583
    negated= !negated;
601
584
    return this;
602
585
  }
603
586
  bool eq(const Item *item, bool binary_cmp) const;
604
 
  bool subst_argument_checker(unsigned char **)
 
587
  bool subst_argument_checker(unsigned char **arg __attribute__((unused)))
605
588
  { return true; }
606
589
};
607
590
 
704
687
  enum_field_types field_type() const;
705
688
  void fix_length_and_dec();
706
689
  const char *func_name() const { return "ifnull"; }
707
 
  Field *tmp_table_field()
708
 
  {
709
 
    return Item_func::tmp_table_field();
710
 
  }
711
690
  Field *tmp_table_field(Table *table);
712
691
  uint32_t decimal_precision() const;
713
692
};
765
744
 
766
745
/* A vector of values of some type  */
767
746
 
768
 
class in_vector :public memory::SqlAlloc
 
747
class in_vector :public Sql_alloc
769
748
{
770
749
public:
771
750
  char *base;
775
754
  uint32_t count;
776
755
  uint32_t used_count;
777
756
  in_vector() {}
778
 
  in_vector(uint32_t elements,uint32_t element_length,qsort2_cmp cmp_func,
 
757
  in_vector(uint32_t elements,uint32_t element_length,qsort2_cmp cmp_func, 
779
758
            const CHARSET_INFO * const cmp_coll)
780
 
    :base((char*) memory::sql_calloc(elements*element_length)),
 
759
    :base((char*) sql_calloc(elements*element_length)),
781
760
     size(element_length), compare(cmp_func), collation(cmp_coll),
782
761
     count(elements), used_count(elements) {}
783
762
  virtual ~in_vector() {}
784
763
  virtual void set(uint32_t pos,Item *item)=0;
785
764
  virtual unsigned char *get_value(Item *item)=0;
786
 
  void sort();
 
765
  void sort()
 
766
  {
 
767
    my_qsort2(base,used_count,size,compare, (void *) collation);
 
768
  }
787
769
  int find(Item *item);
788
 
 
789
 
  /*
 
770
  
 
771
  /* 
790
772
    Create an instance of Item_{type} (e.g. Item_decimal) constant object
791
773
    which type allows it to hold an element of this vector without any
792
774
    conversions.
795
777
    for every array element you get (i.e. this implements "FlyWeight" pattern)
796
778
  */
797
779
  virtual Item* create_item() { return NULL; }
798
 
 
 
780
  
799
781
  /*
800
782
    Store the value at position #pos into provided item object
801
783
    SYNOPSIS
804
786
        item  Constant item to store value into. The item must be of the same
805
787
              type that create_item() returns.
806
788
  */
807
 
  virtual void value_to_item(uint32_t, Item *) { }
808
 
 
 
789
  virtual void value_to_item(uint32_t pos __attribute__((unused)),
 
790
                             Item *item __attribute__((unused))) { }
 
791
  
809
792
  /* Compare values number pos1 and pos2 for equality */
810
793
  bool compare_elems(uint32_t pos1, uint32_t pos2)
811
794
  {
824
807
  void set(uint32_t pos,Item *item);
825
808
  unsigned char *get_value(Item *item);
826
809
  Item* create_item()
827
 
  {
 
810
  { 
828
811
    return new Item_string(collation);
829
812
  }
830
813
  void value_to_item(uint32_t pos, Item *item)
831
 
  {
 
814
  {    
832
815
    String *str=((String*) base)+pos;
833
816
    Item_string *to= (Item_string*)item;
834
817
    to->str_value= *str;
841
824
protected:
842
825
  /*
843
826
    Here we declare a temporary variable (tmp) of the same type as the
844
 
    elements of this vector. tmp is used in finding if a given value is in
845
 
    the list.
 
827
    elements of this vector. tmp is used in finding if a given value is in 
 
828
    the list. 
846
829
  */
847
 
  struct packed_int64_t
 
830
  struct packed_int64_t 
848
831
  {
849
832
    int64_t val;
850
833
    int64_t unsigned_flag;  // Use int64_t, not bool, to preserve alignment
853
836
  in_int64_t(uint32_t elements);
854
837
  void set(uint32_t pos,Item *item);
855
838
  unsigned char *get_value(Item *item);
856
 
 
 
839
  
857
840
  Item* create_item()
858
 
  {
859
 
    /*
860
 
      We're created a signed INT, this may not be correct in
 
841
  { 
 
842
    /* 
 
843
      We're created a signed INT, this may not be correct in 
861
844
      general case (see BUG#19342).
862
845
    */
863
846
    return new Item_int((int64_t)0);
906
889
  void set(uint32_t pos,Item *item);
907
890
  unsigned char *get_value(Item *item);
908
891
  Item *create_item()
909
 
  {
 
892
  { 
910
893
    return new Item_float(0.0, 0);
911
894
  }
912
895
  void value_to_item(uint32_t pos, Item *item)
925
908
  void set(uint32_t pos, Item *item);
926
909
  unsigned char *get_value(Item *item);
927
910
  Item *create_item()
928
 
  {
 
911
  { 
929
912
    return new Item_decimal(0, false);
930
913
  }
931
914
  void value_to_item(uint32_t pos, Item *item)
943
926
** Classes for easy comparing of non const items
944
927
*/
945
928
 
946
 
class cmp_item :public memory::SqlAlloc
 
929
class cmp_item :public Sql_alloc
947
930
{
948
931
public:
949
932
  const CHARSET_INFO *cmp_charset;
955
938
  virtual int compare(cmp_item *item)= 0;
956
939
  static cmp_item* get_comparator(Item_result type, const CHARSET_INFO * const cs);
957
940
  virtual cmp_item *make_same()= 0;
958
 
  virtual void store_value_by_template(cmp_item *, Item *item)
 
941
  virtual void store_value_by_template(cmp_item *tmpl  __attribute__((unused)),
 
942
                                       Item *item)
959
943
  {
960
944
    store_value(item);
961
945
  }
962
946
};
963
947
 
964
 
class cmp_item_string :public cmp_item
 
948
class cmp_item_string :public cmp_item 
965
949
{
966
950
protected:
967
951
  String *value_res;
1000
984
  {
1001
985
    cmp_item_string *l_cmp= (cmp_item_string *) ci;
1002
986
    return sortcmp(value_res, l_cmp->value_res, cmp_charset);
1003
 
  }
 
987
  } 
1004
988
  cmp_item *make_same();
1005
989
  void set_charset(const CHARSET_INFO * const cs)
1006
990
  {
1088
1072
};
1089
1073
 
1090
1074
 
1091
 
/*
 
1075
/* 
1092
1076
   cmp_item for optimized IN with row (right part string, which never
1093
1077
   be changed)
1094
1078
*/
1104
1088
  {
1105
1089
    value_res= item->val_str(&value);
1106
1090
  }
1107
 
  int cmp(Item *)
 
1091
  int cmp(Item *item __attribute__((unused)))
1108
1092
  {
1109
1093
    // Should never be called
1110
1094
    assert(0);
1126
1110
  The class Item_func_case is the CASE ... WHEN ... THEN ... END function
1127
1111
  implementation.
1128
1112
 
1129
 
  When there is no expression between CASE and the first WHEN
 
1113
  When there is no expression between CASE and the first WHEN 
1130
1114
  (the CASE expression) then this function simple checks all WHEN expressions
1131
1115
  one after another. When some WHEN expression evaluated to TRUE then the
1132
1116
  value of the corresponding THEN expression is returned.
1206
1190
class Item_func_in :public Item_func_opt_neg
1207
1191
{
1208
1192
public:
1209
 
  /*
 
1193
  /* 
1210
1194
    an array of values when the right hand arguments of IN
1211
 
    are all SQL constant and there are no nulls
 
1195
    are all SQL constant and there are no nulls 
1212
1196
  */
1213
1197
  in_vector *array;
1214
1198
  bool have_null;
1215
 
  /*
 
1199
  /* 
1216
1200
    true when all arguments of the IN clause are of compatible types
1217
1201
    and can be used safely as comparisons for key conditions
1218
1202
  */
1238
1222
    Item_int_func::cleanup();
1239
1223
    delete array;
1240
1224
    array= 0;
1241
 
    for (i= 0; i <= (uint32_t)DECIMAL_RESULT + 1; i++)
 
1225
    for (i= 0; i <= (uint)DECIMAL_RESULT + 1; i++)
1242
1226
    {
1243
1227
      delete cmp_items[i];
1244
1228
      cmp_items[i]= 0;
1330
1314
 
1331
1315
class Item_in_subselect;
1332
1316
 
1333
 
/*
 
1317
/* 
1334
1318
  This is like IS NOT NULL but it also remembers if it ever has
1335
1319
  encountered a NULL.
1336
1320
*/
1393
1377
  enum { alphabet_size = 256 };
1394
1378
 
1395
1379
  Item *escape_item;
1396
 
 
 
1380
  
1397
1381
  bool escape_used_in_parsing;
1398
1382
 
1399
 
 
1400
1383
public:
1401
 
 
1402
 
  char *escape;
 
1384
  int escape;
1403
1385
 
1404
1386
  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),
 
1387
    :Item_bool_func2(a,b), canDoTurboBM(false), pattern(0), pattern_len(0), 
1406
1388
     bmGs(0), bmBc(0), escape_item(escape_arg),
1407
 
     escape_used_in_parsing(escape_used), escape(NULL) {}
 
1389
     escape_used_in_parsing(escape_used) {}
1408
1390
  int64_t val_int();
1409
1391
  enum Functype functype() const { return LIKE_FUNC; }
1410
1392
  optimize_type select_optimize() const;
1425
1407
  table_map and_tables_cache;
1426
1408
 
1427
1409
public:
1428
 
 
1429
 
  using Item::split_sum_func;
1430
 
 
1431
1410
  /* Item_cond() is only used to create top level items */
1432
1411
  Item_cond(): Item_bool_func(), abort_on_null(1)
1433
1412
  { const_item_cache=0; }
1444
1423
  bool add_at_head(Item *item) { return list.push_front(item); }
1445
1424
  void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
1446
1425
  bool fix_fields(Session *, Item **ref);
1447
 
  void fix_after_pullout(Select_Lex *new_parent, Item **ref);
 
1426
  void fix_after_pullout(st_select_lex *new_parent, Item **ref);
1448
1427
 
1449
1428
  enum Type type() const { return COND_ITEM; }
1450
1429
  List<Item>* argument_list() { return &list; }
1461
1440
  void traverse_cond(Cond_traverser, void *arg, traverse_order order);
1462
1441
  void neg_arguments(Session *session);
1463
1442
  enum_field_types field_type() const { return DRIZZLE_TYPE_LONGLONG; }
1464
 
  bool subst_argument_checker(unsigned char **)
 
1443
  bool subst_argument_checker(unsigned char **arg __attribute__((unused)))
1465
1444
  { return true; }
1466
1445
  Item *compile(Item_analyzer analyzer, unsigned char **arg_p,
1467
1446
                Item_transformer transformer, unsigned char *arg_t);
1485
1464
  A conjunction of the predicates f2=f1 and f3=f1 and f3=f2 will be
1486
1465
  substituted for the item representing the same multiple equality
1487
1466
  f1=f2=f3.
1488
 
  An item Item_equal(f1,f2) can appear instead of a conjunction of
 
1467
  An item Item_equal(f1,f2) can appear instead of a conjunction of 
1489
1468
  f2=f1 and f1=f2, or instead of just the predicate f1=f2.
1490
1469
 
1491
 
  An item of the class Item_equal inherits equalities from outer
 
1470
  An item of the class Item_equal inherits equalities from outer 
1492
1471
  conjunctive levels.
1493
1472
 
1494
1473
  Suppose we have a where condition of the following form:
1499
1478
    f1=f3 will be substituted for Item_equal(f1,f2,f3,f4,f5);
1500
1479
 
1501
1480
  An object of the class Item_equal can contain an optional constant
1502
 
  item c. Then it represents a multiple equality of the form
 
1481
  item c. Then it represents a multiple equality of the form 
1503
1482
  c=f1=...=fk.
1504
1483
 
1505
1484
  Objects of the class Item_equal are used for the following:
1514
1493
  It also can give us additional index scans and can allow us to
1515
1494
  improve selectivity estimates.
1516
1495
 
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
 
1496
  3. An object Item_equal(t1.f1,...,tk.fk) is used to optimize the 
 
1497
  selected execution plan for the query: if table ti is accessed 
1519
1498
  before the table tj then in any predicate P in the where condition
1520
1499
  the occurrence of tj.fj is substituted for ti.fi. This can allow
1521
1500
  an evaluation of the predicate at an earlier step.
1522
1501
 
1523
 
  When feature 1 is supported they say that join transitive closure
 
1502
  When feature 1 is supported they say that join transitive closure 
1524
1503
  is employed.
1525
1504
  When feature 2 is supported they say that search argument transitive
1526
1505
  closure is employed.
1529
1508
  We do not just add predicates, we rather dynamically replace some
1530
1509
  predicates that can not be used to access tables in the investigated
1531
1510
  plan for those, obtained by substitution of some fields for equal fields,
1532
 
  that can be used.
 
1511
  that can be used.     
1533
1512
 
1534
1513
  Prepared Statements/Stored Procedures note: instances of class
1535
1514
  Item_equal are created only at the time a PS/SP is executed and
1565
1544
  void merge(Item_equal *item);
1566
1545
  void update_const();
1567
1546
  enum Functype functype() const { return MULT_EQUAL_FUNC; }
1568
 
  int64_t val_int();
 
1547
  int64_t val_int(); 
1569
1548
  const char *func_name() const { return "multiple equal"; }
1570
1549
  optimize_type select_optimize() const { return OPTIMIZE_EQUAL; }
1571
1550
  void sort(Item_field_cmpfunc cmp, void *arg);
1576
1555
  bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
1577
1556
  Item *transform(Item_transformer transformer, unsigned char *arg);
1578
1557
  virtual void print(String *str, enum_query_type query_type);
1579
 
  const CHARSET_INFO *compare_collation()
 
1558
  const CHARSET_INFO *compare_collation() 
1580
1559
  { return fields.head()->collation.collation; }
1581
 
};
 
1560
}; 
1582
1561
 
1583
 
class COND_EQUAL: public memory::SqlAlloc
 
1562
class COND_EQUAL: public Sql_alloc
1584
1563
{
1585
1564
public:
1586
1565
  uint32_t max_members;               /* max number of members the current level
1587
 
                                     list and all lower level lists */
 
1566
                                     list and all lower level lists */ 
1588
1567
  COND_EQUAL *upper_levels;       /* multiple equalities of upper and levels */
1589
 
  List<Item_equal> current_level; /* list of multiple equalities of
 
1568
  List<Item_equal> current_level; /* list of multiple equalities of 
1590
1569
                                     the current and level           */
1591
1570
  COND_EQUAL()
1592
 
  {
 
1571
  { 
1593
1572
    upper_levels= 0;
1594
1573
  }
1595
1574
};
1598
1577
class Item_equal_iterator : public List_iterator_fast<Item_field>
1599
1578
{
1600
1579
public:
1601
 
  inline Item_equal_iterator(Item_equal &item_equal)
 
1580
  inline Item_equal_iterator(Item_equal &item_equal) 
1602
1581
    :List_iterator_fast<Item_field> (item_equal.fields)
1603
1582
  {}
1604
1583
  inline Item_field* operator++(int)
1605
 
  {
 
1584
  { 
1606
1585
    Item_field *item= (*(List_iterator_fast<Item_field> *) this)++;
1607
1586
    return  item;
1608
1587
  }
1609
 
  inline void rewind(void)
1610
 
  {
 
1588
  inline void rewind(void) 
 
1589
  { 
1611
1590
    List_iterator_fast<Item_field>::rewind();
1612
1591
  }
1613
1592
};
1615
1594
class Item_cond_and :public Item_cond
1616
1595
{
1617
1596
public:
1618
 
  COND_EQUAL cond_equal;  /* contains list of Item_equal objects for
 
1597
  COND_EQUAL cond_equal;  /* contains list of Item_equal objects for 
1619
1598
                             the current and level and reference
1620
 
                             to multiple equalities of upper and levels */
 
1599
                             to multiple equalities of upper and levels */  
1621
1600
  Item_cond_and() :Item_cond() {}
1622
1601
  Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
1623
1602
  Item_cond_and(Session *session, Item_cond_and *item) :Item_cond(session, item) {}
1694
1673
  void top_level_item() {}
1695
1674
};
1696
1675
 
1697
 
enum_field_types agg_field_type(Item **items, uint32_t nitems);
1698
 
 
1699
1676
 
1700
1677
/* Some useful inline functions */
1701
1678
 
1708
1685
 
1709
1686
Item *and_expressions(Item *a, Item *b, Item **org_item);
1710
1687
 
1711
 
} /* namespace drizzled */
1712
 
 
1713
1688
#endif /* DRIZZLED_ITEM_CMPFUNC_H */