~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item_sum.h

  • Committer: Monty Taylor
  • Date: 2008-10-22 23:45:01 UTC
  • Revision ID: monty@inaugust.com-20081022234501-hwybvprata8ba98l
Moved handler_error_messages array out of header file. Moved associated
functions to live with it.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#ifndef DRIZZLED_ITEM_SUM_H
21
 
#define DRIZZLED_ITEM_SUM_H
22
20
 
23
21
/* classes for sum functions */
24
22
 
25
23
 
26
 
#include "drizzled/tree.h"
27
 
#include <drizzled/hybrid_type.h>
28
 
#include <drizzled/item.h>
29
 
#include <drizzled/item/field.h>
30
 
#include <drizzled/item/bin_string.h>
31
 
 
32
 
namespace drizzled
33
 
{
34
 
 
35
 
int group_concat_key_cmp_with_distinct(void* arg, const void* key1,
36
 
                                       const void* key2);
37
 
 
38
 
int group_concat_key_cmp_with_order(void* arg, const void* key1,
39
 
                                    const void* key2);
40
 
 
41
 
class Select_Lex;
42
 
struct Order;
 
24
#include <mysys/my_tree.h>
43
25
 
44
26
/*
45
27
  Class Item_sum is the base class used for special expressions that SQL calls
49
31
 GENERAL NOTES
50
32
 
51
33
  A set function cannot be used in certain positions where expressions are
52
 
  accepted. There are some quite explicable restrictions for the usage of
 
34
  accepted. There are some quite explicable restrictions for the usage of 
53
35
  set functions.
54
36
 
55
37
  In the query:
56
38
    SELECT AVG(b) FROM t1 WHERE SUM(b) > 20 GROUP by a
57
39
  the usage of the set function AVG(b) is legal, while the usage of SUM(b)
58
 
  is illegal. A WHERE condition must contain expressions that can be
 
40
  is illegal. A WHERE condition must contain expressions that can be 
59
41
  evaluated for each row of the table. Yet the expression SUM(b) can be
60
42
  evaluated only for each group of rows with the same value of column a.
61
43
  In the query:
80
62
  The problem of finding the query where to aggregate a particular
81
63
  set function is not so simple as it seems to be.
82
64
 
83
 
  In the query:
 
65
  In the query: 
84
66
    SELECT t1.a FROM t1 GROUP BY t1.a
85
67
     HAVING t1.a > ALL(SELECT t2.c FROM t2 GROUP BY t2.c
86
68
                         HAVING SUM(t1.a) < t2.c)
87
69
  the set function can be evaluated for both outer and inner selects.
88
70
  If we evaluate SUM(t1.a) for the outer query then we get the value of t1.a
89
 
  multiplied by the cardinality of a group in table t1. In this case
 
71
  multiplied by the cardinality of a group in table t1. In this case 
90
72
  in each correlated subquery SUM(t1.a) is used as a constant. But we also
91
73
  can evaluate SUM(t1.a) for the inner query. In this case t1.a will be a
92
74
  constant for each correlated subquery and summation is performed
93
75
  for each group of table t2.
94
76
  (Here it makes sense to remind that the query
95
 
    SELECT c FROM t GROUP BY a HAVING SUM(1) < a
 
77
    SELECT c FROM t GROUP BY a HAVING SUM(1) < a 
96
78
  is quite legal in our SQL).
97
79
 
98
80
  So depending on what query we assign the set function to we
134
116
 
135
117
  3. SELECT t1.a FROM t1 GROUP BY t1.a
136
118
       HAVING t1.a > ALL(SELECT t2.b FROM t2
137
 
                           WHERE t2.b > ALL (SELECT t3.c FROM t3
 
119
                           WHERE t2.b > ALL (SELECT t3.c FROM t3 
138
120
                                               WHERE SUM(t1.a+t2.b) < t3.c))
139
121
  In this query evaluation of SUM(t1.a+t2.b) is not legal neither in the second
140
122
  nor in the third subqueries. So this query is invalid.
163
145
    SELECT t2.c FROM t2 GROUP BY t2.c HAVING AVG(t2.c+s)
164
146
  than returns some result set.
165
147
 
166
 
  By the same reason the following query with a subquery
 
148
  By the same reason the following query with a subquery 
167
149
    SELECT t1.a FROM t1 GROUP BY t1.a
168
150
      HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
169
151
                        HAVING AVG(SUM(t1.b)) > 20)
223
205
  and reports an error if it is illegal.
224
206
  The method register_sum_func serves to link the items for the set functions
225
207
  that are aggregated in the embedding (sub)queries. Circular chains of such
226
 
  functions are attached to the corresponding Select_Lex structures
 
208
  functions are attached to the corresponding st_select_lex structures
227
209
  through the field inner_sum_func_list.
228
210
 
229
211
  Exploiting the fact that the members mentioned above are used in one
230
212
  recursive function we could have allocated them on the thread stack.
231
213
  Yet we don't do it now.
232
 
 
 
214
  
233
215
  We assume that the nesting level of subquries does not exceed 127.
234
216
  TODO: to catch queries where the limit is exceeded to make the
235
 
  code clean here.
 
217
  code clean here.  
 
218
    
 
219
*/ 
236
220
 
237
 
*/
 
221
class st_select_lex;
238
222
 
239
223
class Item_sum :public Item_result_field
240
224
{
249
233
  Item **ref_by; /* pointer to a ref to the object used to register it */
250
234
  Item_sum *next; /* next in the circular chain of registered objects  */
251
235
  uint32_t arg_count;
252
 
  Item_sum *in_sum_func;  /* embedding set function if any */
253
 
  Select_Lex * aggr_sel; /* select where the function is aggregated       */
 
236
  Item_sum *in_sum_func;  /* embedding set function if any */ 
 
237
  st_select_lex * aggr_sel; /* select where the function is aggregated       */ 
254
238
  int8_t nest_level;        /* number of the nesting level of the set function */
255
239
  int8_t aggr_level;        /* nesting level of the aggregating subquery       */
256
240
  int8_t max_arg_level;     /* max level of unbound column references          */
264
248
  */
265
249
  List<Item_field> outer_fields;
266
250
 
267
 
protected:
 
251
protected:  
268
252
  table_map used_tables_cache;
269
253
  bool forced_const;
270
254
 
271
 
public:
 
255
public:  
272
256
 
273
257
  void mark_as_sum_func();
274
258
  Item_sum() :arg_count(0), quick_group(1), forced_const(false)
275
259
  {
276
260
    mark_as_sum_func();
277
261
  }
278
 
  Item_sum(Item *a) :args(tmp_args), arg_count(1), quick_group(1),
 
262
  Item_sum(Item *a) :args(tmp_args), arg_count(1), quick_group(1), 
279
263
    forced_const(false)
280
264
  {
281
265
    args[0]=a;
354
338
    { return new Item_field(field); }
355
339
  table_map used_tables() const { return used_tables_cache; }
356
340
  void update_used_tables ();
357
 
  void cleanup()
358
 
  {
 
341
  void cleanup() 
 
342
  { 
359
343
    Item::cleanup();
360
 
    forced_const= false;
 
344
    forced_const= false; 
361
345
  }
362
346
  bool is_null() { return null_value; }
363
 
  void make_const ()
364
 
  {
365
 
    used_tables_cache= 0;
366
 
    forced_const= true;
 
347
  void make_const () 
 
348
  { 
 
349
    used_tables_cache= 0; 
 
350
    forced_const= true; 
367
351
  }
368
352
  virtual bool const_item() const { return forced_const; }
369
 
  void make_field(SendField *field);
 
353
  void make_field(Send_field *field);
370
354
  virtual void print(String *str, enum_query_type query_type);
371
355
  void fix_num_length_and_dec();
372
356
 
380
364
  */
381
365
  void no_rows_in_result() { clear(); }
382
366
 
383
 
  virtual bool setup(Session *) {return 0;}
 
367
  virtual bool setup(Session *session __attribute__((unused))) {return 0;}
384
368
  virtual void make_unique(void) {}
385
369
  Item *get_tmp_table_item(Session *session);
386
370
  virtual Field *create_tmp_field(bool group, Table *table,
389
373
  bool init_sum_func_check(Session *session);
390
374
  bool check_sum_func(Session *session, Item **ref);
391
375
  bool register_sum_func(Session *session, Item **ref);
392
 
  Select_Lex *depended_from()
 
376
  st_select_lex *depended_from() 
393
377
    { return (nest_level == aggr_level ? 0 : aggr_sel); }
394
378
};
395
379
 
398
382
{
399
383
protected:
400
384
  /*
401
 
   val_xxx() functions may be called several times during the execution of a
 
385
   val_xxx() functions may be called several times during the execution of a 
402
386
   query. Derived classes that require extensive calculation in val_xxx()
403
 
   maintain cache of aggregate value. This variable governs the validity of
 
387
   maintain cache of aggregate value. This variable governs the validity of 
404
388
   that cache.
405
389
  */
406
390
  bool is_evaluated;
407
391
public:
408
392
  Item_sum_num() :Item_sum(),is_evaluated(false) {}
409
 
  Item_sum_num(Item *item_par)
 
393
  Item_sum_num(Item *item_par) 
410
394
    :Item_sum(item_par), is_evaluated(false) {}
411
395
  Item_sum_num(Item *a, Item* b) :Item_sum(a,b),is_evaluated(false) {}
412
 
  Item_sum_num(List<Item> &list)
 
396
  Item_sum_num(List<Item> &list) 
413
397
    :Item_sum(list), is_evaluated(false) {}
414
 
  Item_sum_num(Session *session, Item_sum_num *item)
 
398
  Item_sum_num(Session *session, Item_sum_num *item) 
415
399
    :Item_sum(session, item),is_evaluated(item->is_evaluated) {}
416
400
  bool fix_fields(Session *, Item **);
417
 
  int64_t val_int();
 
401
  int64_t val_int()
 
402
  {
 
403
    assert(fixed == 1);
 
404
    return (int64_t) rint(val_real());             /* Real as default */
 
405
  }
418
406
  String *val_str(String*str);
419
407
  my_decimal *val_decimal(my_decimal *);
420
408
  void reset_field();
502
490
  void update_field() {} // not used
503
491
  virtual void no_rows_in_result() {}
504
492
  void fix_length_and_dec();
505
 
  enum Item_result result_type () const;
 
493
  enum Item_result result_type () const { return val.traits->type(); }
506
494
  virtual void calculate_val_and_count();
507
495
  virtual bool unique_walk_function(void *elem);
508
496
};
562
550
  void clear();
563
551
  void no_rows_in_result() { count=0; }
564
552
  bool add();
565
 
  void make_const_count(int64_t count_arg)
566
 
  {
 
553
  void make_const(int64_t count_arg) 
 
554
  { 
567
555
    count=count_arg;
568
556
    Item_sum::make_const();
569
557
  }
576
564
};
577
565
 
578
566
 
579
 
class Tmp_Table_Param;
 
567
class TMP_TABLE_PARAM;
580
568
 
581
569
class Item_sum_count_distinct :public Item_sum_int
582
570
{
583
571
  Table *table;
584
572
  uint32_t *field_lengths;
585
 
  Tmp_Table_Param *tmp_table_param;
 
573
  TMP_TABLE_PARAM *tmp_table_param;
586
574
  bool force_copy_fields;
587
575
  /*
588
576
    If there are no blobs, we can use a tree, which
597
585
  */
598
586
  int64_t count;
599
587
  /*
600
 
    Following is 0 normal object and pointer to original one for copy
 
588
    Following is 0 normal object and pointer to original one for copy 
601
589
    (to correctly free resources)
602
590
  */
603
591
  Item_sum_count_distinct *original;
620
608
    :Item_sum_int(session, item), table(item->table),
621
609
     field_lengths(item->field_lengths),
622
610
     tmp_table_param(item->tmp_table_param),
623
 
     force_copy_fields(0), tree(item->tree), count(item->count),
 
611
     force_copy_fields(0), tree(item->tree), count(item->count), 
624
612
     original(item), tree_key_length(item->tree_key_length),
625
613
     always_null(item->always_null)
626
614
  {}
663
651
  enum_field_types field_type() const
664
652
  {
665
653
    return hybrid_type == DECIMAL_RESULT ?
666
 
      DRIZZLE_TYPE_DECIMAL : DRIZZLE_TYPE_DOUBLE;
 
654
      DRIZZLE_TYPE_NEWDECIMAL : DRIZZLE_TYPE_DOUBLE;
667
655
  }
668
656
  void fix_length_and_dec() {}
669
657
  enum Item_result result_type () const { return hybrid_type; }
688
676
  bool add();
689
677
  double val_real();
690
678
  // In SPs we might force the "wrong" type with select into a declare variable
691
 
  int64_t val_int();
 
679
  int64_t val_int() { return (int64_t) rint(val_real()); }
692
680
  my_decimal *val_decimal(my_decimal *);
693
681
  String *val_str(String *str);
694
682
  void reset_field();
695
683
  void update_field();
696
 
  Item *result_item(Field *)
 
684
  Item *result_item(Field *field __attribute__((unused)))
697
685
  { return new Item_avg_field(hybrid_type, this); }
698
686
  void no_rows_in_result() {}
699
687
  const char *func_name() const { return "avg("; }
721
709
  Item_variance_field(Item_sum_variance *item);
722
710
  enum Type type() const {return FIELD_VARIANCE_ITEM; }
723
711
  double val_real();
724
 
  int64_t val_int();
 
712
  int64_t val_int()
 
713
  { /* can't be fix_fields()ed */ return (int64_t) rint(val_real()); }
725
714
  String *val_str(String *str)
726
715
  { return val_string_from_real(str); }
727
716
  my_decimal *val_decimal(my_decimal *dec_buf)
730
719
  enum_field_types field_type() const
731
720
  {
732
721
    return hybrid_type == DECIMAL_RESULT ?
733
 
      DRIZZLE_TYPE_DECIMAL : DRIZZLE_TYPE_DOUBLE;
 
722
      DRIZZLE_TYPE_NEWDECIMAL : DRIZZLE_TYPE_DOUBLE;
734
723
  }
735
724
  void fix_length_and_dec() {}
736
725
  enum Item_result result_type () const { return hybrid_type; }
742
731
 
743
732
  =  sum (ai - avg(a))^2 / count(a) )
744
733
  =  sum (ai^2 - 2*ai*avg(a) + avg(a)^2) / count(a)
745
 
  =  (sum(ai^2) - sum(2*ai*avg(a)) + sum(avg(a)^2))/count(a) =
746
 
  =  (sum(ai^2) - 2*avg(a)*sum(a) + count(a)*avg(a)^2)/count(a) =
747
 
  =  (sum(ai^2) - 2*sum(a)*sum(a)/count(a) + count(a)*sum(a)^2/count(a)^2 )/count(a) =
748
 
  =  (sum(ai^2) - 2*sum(a)^2/count(a) + sum(a)^2/count(a) )/count(a) =
 
734
  =  (sum(ai^2) - sum(2*ai*avg(a)) + sum(avg(a)^2))/count(a) = 
 
735
  =  (sum(ai^2) - 2*avg(a)*sum(a) + count(a)*avg(a)^2)/count(a) = 
 
736
  =  (sum(ai^2) - 2*sum(a)*sum(a)/count(a) + count(a)*sum(a)^2/count(a)^2 )/count(a) = 
 
737
  =  (sum(ai^2) - 2*sum(a)^2/count(a) + sum(a)^2/count(a) )/count(a) = 
749
738
  =  (sum(ai^2) - sum(a)^2/count(a))/count(a)
750
739
 
751
740
But, this falls prey to catastrophic cancellation.  Instead, use the recurrence formulas
752
741
 
753
 
  M_{1} = x_{1}, ~ M_{k} = M_{k-1} + (x_{k} - M_{k-1}) / k newline
 
742
  M_{1} = x_{1}, ~ M_{k} = M_{k-1} + (x_{k} - M_{k-1}) / k newline 
754
743
  S_{1} = 0, ~ S_{k} = S_{k-1} + (x_{k} - M_{k-1}) times (x_{k} - M_{k}) newline
755
744
  for 2 <= k <= n newline
756
745
  ital variance = S_{n} / (n-1)
780
769
  void clear();
781
770
  bool add();
782
771
  double val_real();
783
 
  int64_t val_int();
784
772
  my_decimal *val_decimal(my_decimal *);
785
773
  void reset_field();
786
774
  void update_field();
787
 
  Item *result_item(Field *)
 
775
  Item *result_item(Field *field __attribute__((unused)))
788
776
  { return new Item_variance_field(this); }
789
777
  void no_rows_in_result() {}
790
778
  const char *func_name() const
826
814
    {}
827
815
  enum Sumfunctype sum_func () const { return STD_FUNC; }
828
816
  double val_real();
829
 
  Item *result_item(Field *)
 
817
  Item *result_item(Field *field __attribute__((unused)))
830
818
    { return new Item_std_field(this); }
831
819
  const char *func_name() const { return "std("; }
832
820
  Item *copy_or_same(Session* session);
966
954
 
967
955
class Item_func_group_concat : public Item_sum
968
956
{
969
 
  Tmp_Table_Param *tmp_table_param;
 
957
  TMP_TABLE_PARAM *tmp_table_param;
970
958
  DRIZZLE_ERROR *warning;
971
959
  String result;
972
960
  String *separator;
975
963
 
976
964
  /**
977
965
     If DISTINCT is used with this GROUP_CONCAT, this member is used to filter
978
 
     out duplicates.
 
966
     out duplicates. 
979
967
     @see Item_func_group_concat::setup
980
968
     @see Item_func_group_concat::add
981
969
     @see Item_func_group_concat::clear
982
970
   */
983
971
  Unique *unique_filter;
984
972
  Table *table;
985
 
  Order **order;
 
973
  order_st **order;
986
974
  Name_resolution_context *context;
987
975
  /** The number of ORDER BY items. */
988
976
  uint32_t arg_count_order;
1004
992
                                                const void* key2);
1005
993
  friend int group_concat_key_cmp_with_order(void* arg, const void* key1,
1006
994
                                             const void* key2);
1007
 
  friend int dump_leaf_key(unsigned char* key, uint32_t,
1008
 
                           Item_func_group_concat *group_concat_item);
 
995
  friend int dump_leaf_key(unsigned char* key,
 
996
                           element_count count __attribute__((unused)),
 
997
                           Item_func_group_concat *group_concat_item);
1009
998
 
1010
999
public:
1011
1000
  Item_func_group_concat(Name_resolution_context *context_arg,
1033
1022
  bool fix_fields(Session *,Item **);
1034
1023
  bool setup(Session *session);
1035
1024
  void make_unique();
1036
 
  double val_real();
1037
 
  int64_t val_int();
 
1025
  double val_real()
 
1026
  {
 
1027
    String *res;  res=val_str(&str_value);
 
1028
    return res ? my_atof(res->c_ptr()) : 0.0;
 
1029
  }
 
1030
  int64_t val_int()
 
1031
  {
 
1032
    String *res;
 
1033
    char *end_ptr;
 
1034
    int error;
 
1035
    if (!(res= val_str(&str_value)))
 
1036
      return (int64_t) 0;
 
1037
    end_ptr= (char*) res->ptr()+ res->length();
 
1038
    return my_strtoll10(res->ptr(), &end_ptr, &error);
 
1039
  }
1038
1040
  my_decimal *val_decimal(my_decimal *decimal_value)
1039
1041
  {
1040
1042
    return val_decimal_from_string(decimal_value);
1046
1048
  virtual bool change_context_processor(unsigned char *cntx)
1047
1049
    { context= (Name_resolution_context *)cntx; return false; }
1048
1050
};
1049
 
 
1050
 
} /* namespace drizzled */
1051
 
 
1052
 
#endif /* DRIZZLED_ITEM_SUM_H */