~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/sum.h

pandora-build v0.100 - Fixes several bugs found by cb1kenobi. Add several thoughts from folks at LCA.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000-2006 MySQL AB
2
 
 
3
 
   This program is free software; you can redistribute it and/or modify
4
 
   it under the terms of the GNU General Public License as published by
5
 
   the Free Software Foundation; version 2 of the License.
6
 
 
7
 
   This program is distributed in the hope that it will be useful,
8
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 
   GNU General Public License for more details.
11
 
 
12
 
   You should have received a copy of the GNU General Public License
13
 
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
 
 
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008 Sun Microsystems
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; version 2 of the License.
 
9
 *
 
10
 *  This program is distributed in the hope that it will be useful,
 
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 *  GNU General Public License for more details.
 
14
 *
 
15
 *  You should have received a copy of the GNU General Public License
 
16
 *  along with this program; if not, write to the Free Software
 
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
18
 */
 
19
 
 
20
#ifndef DRIZZLED_ITEM_SUM_H
 
21
#define DRIZZLED_ITEM_SUM_H
16
22
 
17
23
/* classes for sum functions */
18
24
 
19
 
#ifdef USE_PRAGMA_INTERFACE
20
 
#pragma interface                       /* gcc class implementation */
21
 
#endif
22
 
 
23
 
#include <mysys/my_tree.h>
 
25
 
 
26
#include "drizzled/my_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
extern "C"
 
33
int group_concat_key_cmp_with_distinct(void* arg, const void* key1,
 
34
                                       const void* key2);
 
35
 
 
36
extern "C"
 
37
int group_concat_key_cmp_with_order(void* arg, const void* key1,
 
38
                                    const void* key2);
 
39
 
 
40
class Select_Lex;
 
41
struct order_st;
24
42
 
25
43
/*
26
44
  Class Item_sum is the base class used for special expressions that SQL calls
30
48
 GENERAL NOTES
31
49
 
32
50
  A set function cannot be used in certain positions where expressions are
33
 
  accepted. There are some quite explicable restrictions for the usage of 
 
51
  accepted. There are some quite explicable restrictions for the usage of
34
52
  set functions.
35
53
 
36
54
  In the query:
37
55
    SELECT AVG(b) FROM t1 WHERE SUM(b) > 20 GROUP by a
38
56
  the usage of the set function AVG(b) is legal, while the usage of SUM(b)
39
 
  is illegal. A WHERE condition must contain expressions that can be 
 
57
  is illegal. A WHERE condition must contain expressions that can be
40
58
  evaluated for each row of the table. Yet the expression SUM(b) can be
41
59
  evaluated only for each group of rows with the same value of column a.
42
60
  In the query:
61
79
  The problem of finding the query where to aggregate a particular
62
80
  set function is not so simple as it seems to be.
63
81
 
64
 
  In the query: 
 
82
  In the query:
65
83
    SELECT t1.a FROM t1 GROUP BY t1.a
66
84
     HAVING t1.a > ALL(SELECT t2.c FROM t2 GROUP BY t2.c
67
85
                         HAVING SUM(t1.a) < t2.c)
68
86
  the set function can be evaluated for both outer and inner selects.
69
87
  If we evaluate SUM(t1.a) for the outer query then we get the value of t1.a
70
 
  multiplied by the cardinality of a group in table t1. In this case 
 
88
  multiplied by the cardinality of a group in table t1. In this case
71
89
  in each correlated subquery SUM(t1.a) is used as a constant. But we also
72
90
  can evaluate SUM(t1.a) for the inner query. In this case t1.a will be a
73
91
  constant for each correlated subquery and summation is performed
74
92
  for each group of table t2.
75
93
  (Here it makes sense to remind that the query
76
 
    SELECT c FROM t GROUP BY a HAVING SUM(1) < a 
 
94
    SELECT c FROM t GROUP BY a HAVING SUM(1) < a
77
95
  is quite legal in our SQL).
78
96
 
79
97
  So depending on what query we assign the set function to we
115
133
 
116
134
  3. SELECT t1.a FROM t1 GROUP BY t1.a
117
135
       HAVING t1.a > ALL(SELECT t2.b FROM t2
118
 
                           WHERE t2.b > ALL (SELECT t3.c FROM t3 
 
136
                           WHERE t2.b > ALL (SELECT t3.c FROM t3
119
137
                                               WHERE SUM(t1.a+t2.b) < t3.c))
120
138
  In this query evaluation of SUM(t1.a+t2.b) is not legal neither in the second
121
139
  nor in the third subqueries. So this query is invalid.
144
162
    SELECT t2.c FROM t2 GROUP BY t2.c HAVING AVG(t2.c+s)
145
163
  than returns some result set.
146
164
 
147
 
  By the same reason the following query with a subquery 
 
165
  By the same reason the following query with a subquery
148
166
    SELECT t1.a FROM t1 GROUP BY t1.a
149
167
      HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
150
168
                        HAVING AVG(SUM(t1.b)) > 20)
204
222
  and reports an error if it is illegal.
205
223
  The method register_sum_func serves to link the items for the set functions
206
224
  that are aggregated in the embedding (sub)queries. Circular chains of such
207
 
  functions are attached to the corresponding st_select_lex structures
 
225
  functions are attached to the corresponding Select_Lex structures
208
226
  through the field inner_sum_func_list.
209
227
 
210
228
  Exploiting the fact that the members mentioned above are used in one
211
229
  recursive function we could have allocated them on the thread stack.
212
230
  Yet we don't do it now.
213
 
  
 
231
 
214
232
  We assume that the nesting level of subquries does not exceed 127.
215
233
  TODO: to catch queries where the limit is exceeded to make the
216
 
  code clean here.  
217
 
    
218
 
*/ 
 
234
  code clean here.
219
235
 
220
 
class st_select_lex;
 
236
*/
221
237
 
222
238
class Item_sum :public Item_result_field
223
239
{
225
241
  enum Sumfunctype
226
242
  { COUNT_FUNC, COUNT_DISTINCT_FUNC, SUM_FUNC, SUM_DISTINCT_FUNC, AVG_FUNC,
227
243
    AVG_DISTINCT_FUNC, MIN_FUNC, MAX_FUNC, STD_FUNC,
228
 
    VARIANCE_FUNC, SUM_BIT_FUNC, UDF_SUM_FUNC, GROUP_CONCAT_FUNC
 
244
    VARIANCE_FUNC, SUM_BIT_FUNC, GROUP_CONCAT_FUNC
229
245
  };
230
246
 
231
247
  Item **args, *tmp_args[2];
232
248
  Item **ref_by; /* pointer to a ref to the object used to register it */
233
249
  Item_sum *next; /* next in the circular chain of registered objects  */
234
 
  uint arg_count;
235
 
  Item_sum *in_sum_func;  /* embedding set function if any */ 
236
 
  st_select_lex * aggr_sel; /* select where the function is aggregated       */ 
 
250
  uint32_t arg_count;
 
251
  Item_sum *in_sum_func;  /* embedding set function if any */
 
252
  Select_Lex * aggr_sel; /* select where the function is aggregated       */
237
253
  int8_t nest_level;        /* number of the nesting level of the set function */
238
254
  int8_t aggr_level;        /* nesting level of the aggregating subquery       */
239
255
  int8_t max_arg_level;     /* max level of unbound column references          */
247
263
  */
248
264
  List<Item_field> outer_fields;
249
265
 
250
 
protected:  
 
266
protected:
251
267
  table_map used_tables_cache;
252
268
  bool forced_const;
253
269
 
254
 
public:  
 
270
public:
255
271
 
256
272
  void mark_as_sum_func();
257
273
  Item_sum() :arg_count(0), quick_group(1), forced_const(false)
258
274
  {
259
275
    mark_as_sum_func();
260
276
  }
261
 
  Item_sum(Item *a) :args(tmp_args), arg_count(1), quick_group(1), 
 
277
  Item_sum(Item *a) :args(tmp_args), arg_count(1), quick_group(1),
262
278
    forced_const(false)
263
279
  {
264
280
    args[0]=a;
272
288
  }
273
289
  Item_sum(List<Item> &list);
274
290
  //Copy constructor, need to perform subselects with temporary tables
275
 
  Item_sum(THD *thd, Item_sum *item);
 
291
  Item_sum(Session *session, Item_sum *item);
276
292
  enum Type type() const { return SUM_FUNC_ITEM; }
277
293
  virtual enum Sumfunctype sum_func () const=0;
278
294
 
337
353
    { return new Item_field(field); }
338
354
  table_map used_tables() const { return used_tables_cache; }
339
355
  void update_used_tables ();
340
 
  void cleanup() 
341
 
  { 
 
356
  void cleanup()
 
357
  {
342
358
    Item::cleanup();
343
 
    forced_const= false; 
 
359
    forced_const= false;
344
360
  }
345
361
  bool is_null() { return null_value; }
346
 
  void make_const () 
347
 
  { 
348
 
    used_tables_cache= 0; 
349
 
    forced_const= true; 
 
362
  void make_const ()
 
363
  {
 
364
    used_tables_cache= 0;
 
365
    forced_const= true;
350
366
  }
351
367
  virtual bool const_item() const { return forced_const; }
352
 
  void make_field(Send_field *field);
 
368
  void make_field(SendField *field);
353
369
  virtual void print(String *str, enum_query_type query_type);
354
370
  void fix_num_length_and_dec();
355
371
 
363
379
  */
364
380
  void no_rows_in_result() { clear(); }
365
381
 
366
 
  virtual bool setup(THD *thd __attribute__((unused))) {return 0;}
 
382
  virtual bool setup(Session *) {return 0;}
367
383
  virtual void make_unique(void) {}
368
 
  Item *get_tmp_table_item(THD *thd);
369
 
  virtual Field *create_tmp_field(bool group, TABLE *table,
370
 
                                  uint convert_blob_length);
371
 
  bool walk(Item_processor processor, bool walk_subquery, uchar *argument);
372
 
  bool init_sum_func_check(THD *thd);
373
 
  bool check_sum_func(THD *thd, Item **ref);
374
 
  bool register_sum_func(THD *thd, Item **ref);
375
 
  st_select_lex *depended_from() 
 
384
  Item *get_tmp_table_item(Session *session);
 
385
  virtual Field *create_tmp_field(bool group, Table *table,
 
386
                                  uint32_t convert_blob_length);
 
387
  bool walk(Item_processor processor, bool walk_subquery, unsigned char *argument);
 
388
  bool init_sum_func_check(Session *session);
 
389
  bool check_sum_func(Session *session, Item **ref);
 
390
  bool register_sum_func(Session *session, Item **ref);
 
391
  Select_Lex *depended_from()
376
392
    { return (nest_level == aggr_level ? 0 : aggr_sel); }
377
393
};
378
394
 
381
397
{
382
398
protected:
383
399
  /*
384
 
   val_xxx() functions may be called several times during the execution of a 
 
400
   val_xxx() functions may be called several times during the execution of a
385
401
   query. Derived classes that require extensive calculation in val_xxx()
386
 
   maintain cache of aggregate value. This variable governs the validity of 
 
402
   maintain cache of aggregate value. This variable governs the validity of
387
403
   that cache.
388
404
  */
389
405
  bool is_evaluated;
390
406
public:
391
407
  Item_sum_num() :Item_sum(),is_evaluated(false) {}
392
 
  Item_sum_num(Item *item_par) 
 
408
  Item_sum_num(Item *item_par)
393
409
    :Item_sum(item_par), is_evaluated(false) {}
394
410
  Item_sum_num(Item *a, Item* b) :Item_sum(a,b),is_evaluated(false) {}
395
 
  Item_sum_num(List<Item> &list) 
 
411
  Item_sum_num(List<Item> &list)
396
412
    :Item_sum(list), is_evaluated(false) {}
397
 
  Item_sum_num(THD *thd, Item_sum_num *item) 
398
 
    :Item_sum(thd, item),is_evaluated(item->is_evaluated) {}
399
 
  bool fix_fields(THD *, Item **);
400
 
  int64_t val_int()
401
 
  {
402
 
    assert(fixed == 1);
403
 
    return (int64_t) rint(val_real());             /* Real as default */
404
 
  }
 
413
  Item_sum_num(Session *session, Item_sum_num *item)
 
414
    :Item_sum(session, item),is_evaluated(item->is_evaluated) {}
 
415
  bool fix_fields(Session *, Item **);
 
416
  int64_t val_int();
405
417
  String *val_str(String*str);
406
418
  my_decimal *val_decimal(my_decimal *);
407
419
  void reset_field();
413
425
public:
414
426
  Item_sum_int(Item *item_par) :Item_sum_num(item_par) {}
415
427
  Item_sum_int(List<Item> &list) :Item_sum_num(list) {}
416
 
  Item_sum_int(THD *thd, Item_sum_int *item) :Item_sum_num(thd, item) {}
 
428
  Item_sum_int(Session *session, Item_sum_int *item) :Item_sum_num(session, item) {}
417
429
  double val_real() { assert(fixed == 1); return (double) val_int(); }
418
430
  String *val_str(String*str);
419
431
  my_decimal *val_decimal(my_decimal *);
429
441
  Item_result hybrid_type;
430
442
  double sum;
431
443
  my_decimal dec_buffs[2];
432
 
  uint curr_dec_buff;
 
444
  uint32_t curr_dec_buff;
433
445
  void fix_length_and_dec();
434
446
 
435
447
public:
436
448
  Item_sum_sum(Item *item_par) :Item_sum_num(item_par) {}
437
 
  Item_sum_sum(THD *thd, Item_sum_sum *item);
 
449
  Item_sum_sum(Session *session, Item_sum_sum *item);
438
450
  enum Sumfunctype sum_func () const {return SUM_FUNC;}
439
451
  void clear();
440
452
  bool add();
447
459
  void update_field();
448
460
  void no_rows_in_result() {}
449
461
  const char *func_name() const { return "sum("; }
450
 
  Item *copy_or_same(THD* thd);
 
462
  Item *copy_or_same(Session* session);
451
463
};
452
464
 
453
465
 
464
476
  Hybrid_type val;
465
477
  /* storage for unique elements */
466
478
  Unique *tree;
467
 
  TABLE *table;
 
479
  Table *table;
468
480
  enum enum_field_types table_field_type;
469
 
  uint tree_key_length;
 
481
  uint32_t tree_key_length;
470
482
protected:
471
 
  Item_sum_distinct(THD *thd, Item_sum_distinct *item);
 
483
  Item_sum_distinct(Session *session, Item_sum_distinct *item);
472
484
public:
473
485
  Item_sum_distinct(Item *item_par);
474
486
  ~Item_sum_distinct();
475
487
 
476
 
  bool setup(THD *thd);
 
488
  bool setup(Session *session);
477
489
  void clear();
478
490
  void cleanup();
479
491
  bool add();
489
501
  void update_field() {} // not used
490
502
  virtual void no_rows_in_result() {}
491
503
  void fix_length_and_dec();
492
 
  enum Item_result result_type () const { return val.traits->type(); }
 
504
  enum Item_result result_type () const;
493
505
  virtual void calculate_val_and_count();
494
506
  virtual bool unique_walk_function(void *elem);
495
507
};
504
516
class Item_sum_sum_distinct :public Item_sum_distinct
505
517
{
506
518
private:
507
 
  Item_sum_sum_distinct(THD *thd, Item_sum_sum_distinct *item)
508
 
    :Item_sum_distinct(thd, item) {}
 
519
  Item_sum_sum_distinct(Session *session, Item_sum_sum_distinct *item)
 
520
    :Item_sum_distinct(session, item) {}
509
521
public:
510
522
  Item_sum_sum_distinct(Item *item_arg) :Item_sum_distinct(item_arg) {}
511
523
 
512
524
  enum Sumfunctype sum_func () const { return SUM_DISTINCT_FUNC; }
513
525
  const char *func_name() const { return "sum(distinct "; }
514
 
  Item *copy_or_same(THD* thd) { return new Item_sum_sum_distinct(thd, this); }
 
526
  Item *copy_or_same(Session* session) { return new Item_sum_sum_distinct(session, this); }
515
527
};
516
528
 
517
529
 
520
532
class Item_sum_avg_distinct: public Item_sum_distinct
521
533
{
522
534
private:
523
 
  Item_sum_avg_distinct(THD *thd, Item_sum_avg_distinct *original)
524
 
    :Item_sum_distinct(thd, original) {}
 
535
  Item_sum_avg_distinct(Session *session, Item_sum_avg_distinct *original)
 
536
    :Item_sum_distinct(session, original) {}
525
537
public:
526
 
  uint prec_increment;
 
538
  uint32_t prec_increment;
527
539
  Item_sum_avg_distinct(Item *item_arg) : Item_sum_distinct(item_arg) {}
528
540
 
529
541
  void fix_length_and_dec();
530
542
  virtual void calculate_val_and_count();
531
543
  enum Sumfunctype sum_func () const { return AVG_DISTINCT_FUNC; }
532
544
  const char *func_name() const { return "avg(distinct "; }
533
 
  Item *copy_or_same(THD* thd) { return new Item_sum_avg_distinct(thd, this); }
 
545
  Item *copy_or_same(Session* session) { return new Item_sum_avg_distinct(session, this); }
534
546
};
535
547
 
536
548
 
542
554
  Item_sum_count(Item *item_par)
543
555
    :Item_sum_int(item_par),count(0)
544
556
  {}
545
 
  Item_sum_count(THD *thd, Item_sum_count *item)
546
 
    :Item_sum_int(thd, item), count(item->count)
 
557
  Item_sum_count(Session *session, Item_sum_count *item)
 
558
    :Item_sum_int(session, item), count(item->count)
547
559
  {}
548
560
  enum Sumfunctype sum_func () const { return COUNT_FUNC; }
549
561
  void clear();
550
562
  void no_rows_in_result() { count=0; }
551
563
  bool add();
552
 
  void make_const(int64_t count_arg) 
553
 
  { 
 
564
  void make_const_count(int64_t count_arg)
 
565
  {
554
566
    count=count_arg;
555
567
    Item_sum::make_const();
556
568
  }
559
571
  void cleanup();
560
572
  void update_field();
561
573
  const char *func_name() const { return "count("; }
562
 
  Item *copy_or_same(THD* thd);
 
574
  Item *copy_or_same(Session* session);
563
575
};
564
576
 
565
577
 
566
 
class TMP_TABLE_PARAM;
 
578
class Tmp_Table_Param;
567
579
 
568
580
class Item_sum_count_distinct :public Item_sum_int
569
581
{
570
 
  TABLE *table;
 
582
  Table *table;
571
583
  uint32_t *field_lengths;
572
 
  TMP_TABLE_PARAM *tmp_table_param;
 
584
  Tmp_Table_Param *tmp_table_param;
573
585
  bool force_copy_fields;
574
586
  /*
575
587
    If there are no blobs, we can use a tree, which
584
596
  */
585
597
  int64_t count;
586
598
  /*
587
 
    Following is 0 normal object and pointer to original one for copy 
 
599
    Following is 0 normal object and pointer to original one for copy
588
600
    (to correctly free resources)
589
601
  */
590
602
  Item_sum_count_distinct *original;
591
 
  uint tree_key_length;
 
603
  uint32_t tree_key_length;
592
604
 
593
605
 
594
606
  bool always_null;             // Set to 1 if the result is always NULL
595
607
 
596
608
 
597
 
  friend int composite_key_cmp(void* arg, uchar* key1, uchar* key2);
598
 
  friend int simple_str_key_cmp(void* arg, uchar* key1, uchar* key2);
 
609
  friend int composite_key_cmp(void* arg, unsigned char* key1, unsigned char* key2);
 
610
  friend int simple_str_key_cmp(void* arg, unsigned char* key1, unsigned char* key2);
599
611
 
600
612
public:
601
613
  Item_sum_count_distinct(List<Item> &list)
603
615
     force_copy_fields(0), tree(0), count(0),
604
616
     original(0), always_null(false)
605
617
  { quick_group= 0; }
606
 
  Item_sum_count_distinct(THD *thd, Item_sum_count_distinct *item)
607
 
    :Item_sum_int(thd, item), table(item->table),
 
618
  Item_sum_count_distinct(Session *session, Item_sum_count_distinct *item)
 
619
    :Item_sum_int(session, item), table(item->table),
608
620
     field_lengths(item->field_lengths),
609
621
     tmp_table_param(item->tmp_table_param),
610
 
     force_copy_fields(0), tree(item->tree), count(item->count), 
 
622
     force_copy_fields(0), tree(item->tree), count(item->count),
611
623
     original(item), tree_key_length(item->tree_key_length),
612
624
     always_null(item->always_null)
613
625
  {}
622
634
  void reset_field() { return ;}                // Never called
623
635
  void update_field() { return ; }              // Never called
624
636
  const char *func_name() const { return "count(distinct "; }
625
 
  bool setup(THD *thd);
 
637
  bool setup(Session *session);
626
638
  void make_unique();
627
 
  Item *copy_or_same(THD* thd);
 
639
  Item *copy_or_same(Session* session);
628
640
  void no_rows_in_result() {}
629
641
};
630
642
 
638
650
public:
639
651
  Field *field;
640
652
  Item_result hybrid_type;
641
 
  uint f_precision, f_scale, dec_bin_size;
642
 
  uint prec_increment;
 
653
  uint32_t f_precision, f_scale, dec_bin_size;
 
654
  uint32_t prec_increment;
643
655
  Item_avg_field(Item_result res_type, Item_sum_avg *item);
644
656
  enum Type type() const { return FIELD_AVG_ITEM; }
645
657
  double val_real();
650
662
  enum_field_types field_type() const
651
663
  {
652
664
    return hybrid_type == DECIMAL_RESULT ?
653
 
      DRIZZLE_TYPE_NEWDECIMAL : DRIZZLE_TYPE_DOUBLE;
 
665
      DRIZZLE_TYPE_DECIMAL : DRIZZLE_TYPE_DOUBLE;
654
666
  }
655
667
  void fix_length_and_dec() {}
656
668
  enum Item_result result_type () const { return hybrid_type; }
661
673
{
662
674
public:
663
675
  uint64_t count;
664
 
  uint prec_increment;
665
 
  uint f_precision, f_scale, dec_bin_size;
 
676
  uint32_t prec_increment;
 
677
  uint32_t f_precision, f_scale, dec_bin_size;
666
678
 
667
679
  Item_sum_avg(Item *item_par) :Item_sum_sum(item_par), count(0) {}
668
 
  Item_sum_avg(THD *thd, Item_sum_avg *item)
669
 
    :Item_sum_sum(thd, item), count(item->count),
 
680
  Item_sum_avg(Session *session, Item_sum_avg *item)
 
681
    :Item_sum_sum(session, item), count(item->count),
670
682
    prec_increment(item->prec_increment) {}
671
683
 
672
684
  void fix_length_and_dec();
675
687
  bool add();
676
688
  double val_real();
677
689
  // In SPs we might force the "wrong" type with select into a declare variable
678
 
  int64_t val_int() { return (int64_t) rint(val_real()); }
 
690
  int64_t val_int();
679
691
  my_decimal *val_decimal(my_decimal *);
680
692
  String *val_str(String *str);
681
693
  void reset_field();
682
694
  void update_field();
683
 
  Item *result_item(Field *field __attribute__((unused)))
 
695
  Item *result_item(Field *)
684
696
  { return new Item_avg_field(hybrid_type, this); }
685
697
  void no_rows_in_result() {}
686
698
  const char *func_name() const { return "avg("; }
687
 
  Item *copy_or_same(THD* thd);
688
 
  Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
 
699
  Item *copy_or_same(Session* session);
 
700
  Field *create_tmp_field(bool group, Table *table, uint32_t convert_blob_length);
689
701
  void cleanup()
690
702
  {
691
703
    count= 0;
700
712
public:
701
713
  Field *field;
702
714
  Item_result hybrid_type;
703
 
  uint f_precision0, f_scale0;
704
 
  uint f_precision1, f_scale1;
705
 
  uint dec_bin_size0, dec_bin_size1;
706
 
  uint sample;
707
 
  uint prec_increment;
 
715
  uint32_t f_precision0, f_scale0;
 
716
  uint32_t f_precision1, f_scale1;
 
717
  uint32_t dec_bin_size0, dec_bin_size1;
 
718
  uint32_t sample;
 
719
  uint32_t prec_increment;
708
720
  Item_variance_field(Item_sum_variance *item);
709
721
  enum Type type() const {return FIELD_VARIANCE_ITEM; }
710
722
  double val_real();
711
 
  int64_t val_int()
712
 
  { /* can't be fix_fields()ed */ return (int64_t) rint(val_real()); }
 
723
  int64_t val_int();
713
724
  String *val_str(String *str)
714
725
  { return val_string_from_real(str); }
715
726
  my_decimal *val_decimal(my_decimal *dec_buf)
718
729
  enum_field_types field_type() const
719
730
  {
720
731
    return hybrid_type == DECIMAL_RESULT ?
721
 
      DRIZZLE_TYPE_NEWDECIMAL : DRIZZLE_TYPE_DOUBLE;
 
732
      DRIZZLE_TYPE_DECIMAL : DRIZZLE_TYPE_DOUBLE;
722
733
  }
723
734
  void fix_length_and_dec() {}
724
735
  enum Item_result result_type () const { return hybrid_type; }
730
741
 
731
742
  =  sum (ai - avg(a))^2 / count(a) )
732
743
  =  sum (ai^2 - 2*ai*avg(a) + avg(a)^2) / count(a)
733
 
  =  (sum(ai^2) - sum(2*ai*avg(a)) + sum(avg(a)^2))/count(a) = 
734
 
  =  (sum(ai^2) - 2*avg(a)*sum(a) + count(a)*avg(a)^2)/count(a) = 
735
 
  =  (sum(ai^2) - 2*sum(a)*sum(a)/count(a) + count(a)*sum(a)^2/count(a)^2 )/count(a) = 
736
 
  =  (sum(ai^2) - 2*sum(a)^2/count(a) + sum(a)^2/count(a) )/count(a) = 
 
744
  =  (sum(ai^2) - sum(2*ai*avg(a)) + sum(avg(a)^2))/count(a) =
 
745
  =  (sum(ai^2) - 2*avg(a)*sum(a) + count(a)*avg(a)^2)/count(a) =
 
746
  =  (sum(ai^2) - 2*sum(a)*sum(a)/count(a) + count(a)*sum(a)^2/count(a)^2 )/count(a) =
 
747
  =  (sum(ai^2) - 2*sum(a)^2/count(a) + sum(a)^2/count(a) )/count(a) =
737
748
  =  (sum(ai^2) - sum(a)^2/count(a))/count(a)
738
749
 
739
750
But, this falls prey to catastrophic cancellation.  Instead, use the recurrence formulas
740
751
 
741
 
  M_{1} = x_{1}, ~ M_{k} = M_{k-1} + (x_{k} - M_{k-1}) / k newline 
 
752
  M_{1} = x_{1}, ~ M_{k} = M_{k-1} + (x_{k} - M_{k-1}) / k newline
742
753
  S_{1} = 0, ~ S_{k} = S_{k-1} + (x_{k} - M_{k-1}) times (x_{k} - M_{k}) newline
743
754
  for 2 <= k <= n newline
744
755
  ital variance = S_{n} / (n-1)
754
765
  int cur_dec;
755
766
  double recurrence_m, recurrence_s;    /* Used in recurrence relation. */
756
767
  uint64_t count;
757
 
  uint f_precision0, f_scale0;
758
 
  uint f_precision1, f_scale1;
759
 
  uint dec_bin_size0, dec_bin_size1;
760
 
  uint sample;
761
 
  uint prec_increment;
 
768
  uint32_t f_precision0, f_scale0;
 
769
  uint32_t f_precision1, f_scale1;
 
770
  uint32_t dec_bin_size0, dec_bin_size1;
 
771
  uint32_t sample;
 
772
  uint32_t prec_increment;
762
773
 
763
 
  Item_sum_variance(Item *item_par, uint sample_arg) :Item_sum_num(item_par),
 
774
  Item_sum_variance(Item *item_par, uint32_t sample_arg) :Item_sum_num(item_par),
764
775
    hybrid_type(REAL_RESULT), count(0), sample(sample_arg)
765
776
    {}
766
 
  Item_sum_variance(THD *thd, Item_sum_variance *item);
 
777
  Item_sum_variance(Session *session, Item_sum_variance *item);
767
778
  enum Sumfunctype sum_func () const { return VARIANCE_FUNC; }
768
779
  void clear();
769
780
  bool add();
770
781
  double val_real();
 
782
  int64_t val_int();
771
783
  my_decimal *val_decimal(my_decimal *);
772
784
  void reset_field();
773
785
  void update_field();
774
 
  Item *result_item(Field *field __attribute__((unused)))
 
786
  Item *result_item(Field *)
775
787
  { return new Item_variance_field(this); }
776
788
  void no_rows_in_result() {}
777
789
  const char *func_name() const
778
790
    { return sample ? "var_samp(" : "variance("; }
779
 
  Item *copy_or_same(THD* thd);
780
 
  Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
 
791
  Item *copy_or_same(Session* session);
 
792
  Field *create_tmp_field(bool group, Table *table, uint32_t convert_blob_length);
781
793
  enum Item_result result_type () const { return REAL_RESULT; }
782
794
  void cleanup()
783
795
  {
806
818
class Item_sum_std :public Item_sum_variance
807
819
{
808
820
  public:
809
 
  Item_sum_std(Item *item_par, uint sample_arg)
 
821
  Item_sum_std(Item *item_par, uint32_t sample_arg)
810
822
    :Item_sum_variance(item_par, sample_arg) {}
811
 
  Item_sum_std(THD *thd, Item_sum_std *item)
812
 
    :Item_sum_variance(thd, item)
 
823
  Item_sum_std(Session *session, Item_sum_std *item)
 
824
    :Item_sum_variance(session, item)
813
825
    {}
814
826
  enum Sumfunctype sum_func () const { return STD_FUNC; }
815
827
  double val_real();
816
 
  Item *result_item(Field *field __attribute__((unused)))
 
828
  Item *result_item(Field *)
817
829
    { return new Item_std_field(this); }
818
830
  const char *func_name() const { return "std("; }
819
 
  Item *copy_or_same(THD* thd);
 
831
  Item *copy_or_same(Session* session);
820
832
  enum Item_result result_type () const { return REAL_RESULT; }
821
833
  enum_field_types field_type() const { return DRIZZLE_TYPE_DOUBLE;}
822
834
};
841
853
    hybrid_type(INT_RESULT), hybrid_field_type(DRIZZLE_TYPE_LONGLONG),
842
854
    cmp_sign(sign), was_values(true)
843
855
  { collation.set(&my_charset_bin); }
844
 
  Item_sum_hybrid(THD *thd, Item_sum_hybrid *item);
845
 
  bool fix_fields(THD *, Item **);
 
856
  Item_sum_hybrid(Session *session, Item_sum_hybrid *item);
 
857
  bool fix_fields(Session *, Item **);
846
858
  void clear();
847
859
  double val_real();
848
860
  int64_t val_int();
860
872
  void cleanup();
861
873
  bool any_value() { return was_values; }
862
874
  void no_rows_in_result();
863
 
  Field *create_tmp_field(bool group, TABLE *table,
864
 
                          uint convert_blob_length);
 
875
  Field *create_tmp_field(bool group, Table *table,
 
876
                          uint32_t convert_blob_length);
865
877
};
866
878
 
867
879
 
869
881
{
870
882
public:
871
883
  Item_sum_min(Item *item_par) :Item_sum_hybrid(item_par,1) {}
872
 
  Item_sum_min(THD *thd, Item_sum_min *item) :Item_sum_hybrid(thd, item) {}
 
884
  Item_sum_min(Session *session, Item_sum_min *item) :Item_sum_hybrid(session, item) {}
873
885
  enum Sumfunctype sum_func () const {return MIN_FUNC;}
874
886
 
875
887
  bool add();
876
888
  const char *func_name() const { return "min("; }
877
 
  Item *copy_or_same(THD* thd);
 
889
  Item *copy_or_same(Session* session);
878
890
};
879
891
 
880
892
 
882
894
{
883
895
public:
884
896
  Item_sum_max(Item *item_par) :Item_sum_hybrid(item_par,-1) {}
885
 
  Item_sum_max(THD *thd, Item_sum_max *item) :Item_sum_hybrid(thd, item) {}
 
897
  Item_sum_max(Session *session, Item_sum_max *item) :Item_sum_hybrid(session, item) {}
886
898
  enum Sumfunctype sum_func () const {return MAX_FUNC;}
887
899
 
888
900
  bool add();
889
901
  const char *func_name() const { return "max("; }
890
 
  Item *copy_or_same(THD* thd);
 
902
  Item *copy_or_same(Session* session);
891
903
};
892
904
 
893
905
 
899
911
public:
900
912
  Item_sum_bit(Item *item_par,uint64_t reset_arg)
901
913
    :Item_sum_int(item_par),reset_bits(reset_arg),bits(reset_arg) {}
902
 
  Item_sum_bit(THD *thd, Item_sum_bit *item):
903
 
    Item_sum_int(thd, item), reset_bits(item->reset_bits), bits(item->bits) {}
 
914
  Item_sum_bit(Session *session, Item_sum_bit *item):
 
915
    Item_sum_int(session, item), reset_bits(item->reset_bits), bits(item->bits) {}
904
916
  enum Sumfunctype sum_func () const {return SUM_BIT_FUNC;}
905
917
  void clear();
906
918
  int64_t val_int();
919
931
class Item_sum_or :public Item_sum_bit
920
932
{
921
933
public:
922
 
  Item_sum_or(Item *item_par) :Item_sum_bit(item_par,0LL) {}
923
 
  Item_sum_or(THD *thd, Item_sum_or *item) :Item_sum_bit(thd, item) {}
 
934
  Item_sum_or(Item *item_par) :Item_sum_bit(item_par,0) {}
 
935
  Item_sum_or(Session *session, Item_sum_or *item) :Item_sum_bit(session, item) {}
924
936
  bool add();
925
937
  const char *func_name() const { return "bit_or("; }
926
 
  Item *copy_or_same(THD* thd);
 
938
  Item *copy_or_same(Session* session);
927
939
};
928
940
 
929
941
 
931
943
{
932
944
  public:
933
945
  Item_sum_and(Item *item_par) :Item_sum_bit(item_par, UINT64_MAX) {}
934
 
  Item_sum_and(THD *thd, Item_sum_and *item) :Item_sum_bit(thd, item) {}
 
946
  Item_sum_and(Session *session, Item_sum_and *item) :Item_sum_bit(session, item) {}
935
947
  bool add();
936
948
  const char *func_name() const { return "bit_and("; }
937
 
  Item *copy_or_same(THD* thd);
 
949
  Item *copy_or_same(Session* session);
938
950
};
939
951
 
940
952
class Item_sum_xor :public Item_sum_bit
941
953
{
942
954
  public:
943
 
  Item_sum_xor(Item *item_par) :Item_sum_bit(item_par,0LL) {}
944
 
  Item_sum_xor(THD *thd, Item_sum_xor *item) :Item_sum_bit(thd, item) {}
 
955
  Item_sum_xor(Item *item_par) :Item_sum_bit(item_par,0) {}
 
956
  Item_sum_xor(Session *session, Item_sum_xor *item) :Item_sum_bit(session, item) {}
945
957
  bool add();
946
958
  const char *func_name() const { return "bit_xor("; }
947
 
  Item *copy_or_same(THD* thd);
948
 
};
949
 
 
950
 
 
951
 
/*
952
 
  User defined aggregates
953
 
*/
954
 
 
955
 
class Item_udf_sum : public Item_sum
956
 
{
957
 
protected:
958
 
  udf_handler udf;
959
 
 
960
 
public:
961
 
  Item_udf_sum(udf_func *udf_arg)
962
 
    :Item_sum(), udf(udf_arg)
963
 
  { quick_group=0; }
964
 
  Item_udf_sum(udf_func *udf_arg, List<Item> &list)
965
 
    :Item_sum(list), udf(udf_arg)
966
 
  { quick_group=0;}
967
 
  Item_udf_sum(THD *thd, Item_udf_sum *item)
968
 
    :Item_sum(thd, item), udf(item->udf)
969
 
  { udf.not_original= true; }
970
 
  const char *func_name() const { return udf.name(); }
971
 
  bool fix_fields(THD *thd, Item **ref)
972
 
  {
973
 
    assert(fixed == 0);
974
 
 
975
 
    if (init_sum_func_check(thd))
976
 
      return true;
977
 
 
978
 
    fixed= 1;
979
 
    if (udf.fix_fields(thd, this, this->arg_count, this->args))
980
 
      return true;
981
 
 
982
 
    return check_sum_func(thd, ref);
983
 
  }
984
 
  enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
985
 
  virtual bool have_field_update(void) const { return 0; }
986
 
 
987
 
  void clear();
988
 
  bool add();
989
 
  void reset_field() {};
990
 
  void update_field() {};
991
 
  void cleanup();
992
 
  virtual void print(String *str, enum_query_type query_type);
993
 
};
994
 
 
995
 
 
996
 
class Item_sum_udf_float :public Item_udf_sum
997
 
{
998
 
 public:
999
 
  Item_sum_udf_float(udf_func *udf_arg)
1000
 
    :Item_udf_sum(udf_arg) {}
1001
 
  Item_sum_udf_float(udf_func *udf_arg, List<Item> &list)
1002
 
    :Item_udf_sum(udf_arg, list) {}
1003
 
  Item_sum_udf_float(THD *thd, Item_sum_udf_float *item)
1004
 
    :Item_udf_sum(thd, item) {}
1005
 
  int64_t val_int()
1006
 
  {
1007
 
    assert(fixed == 1);
1008
 
    return (int64_t) rint(Item_sum_udf_float::val_real());
1009
 
  }
1010
 
  double val_real();
1011
 
  String *val_str(String*str);
1012
 
  my_decimal *val_decimal(my_decimal *);
1013
 
  void fix_length_and_dec() { fix_num_length_and_dec(); }
1014
 
  Item *copy_or_same(THD* thd);
1015
 
};
1016
 
 
1017
 
 
1018
 
class Item_sum_udf_int :public Item_udf_sum
1019
 
{
1020
 
public:
1021
 
  Item_sum_udf_int(udf_func *udf_arg)
1022
 
    :Item_udf_sum(udf_arg) {}
1023
 
  Item_sum_udf_int(udf_func *udf_arg, List<Item> &list)
1024
 
    :Item_udf_sum(udf_arg, list) {}
1025
 
  Item_sum_udf_int(THD *thd, Item_sum_udf_int *item)
1026
 
    :Item_udf_sum(thd, item) {}
1027
 
  int64_t val_int();
1028
 
  double val_real()
1029
 
    { assert(fixed == 1); return (double) Item_sum_udf_int::val_int(); }
1030
 
  String *val_str(String*str);
1031
 
  my_decimal *val_decimal(my_decimal *);
1032
 
  enum Item_result result_type () const { return INT_RESULT; }
1033
 
  void fix_length_and_dec() { decimals=0; max_length=21; }
1034
 
  Item *copy_or_same(THD* thd);
1035
 
};
1036
 
 
1037
 
 
1038
 
class Item_sum_udf_str :public Item_udf_sum
1039
 
{
1040
 
public:
1041
 
  Item_sum_udf_str(udf_func *udf_arg)
1042
 
    :Item_udf_sum(udf_arg) {}
1043
 
  Item_sum_udf_str(udf_func *udf_arg, List<Item> &list)
1044
 
    :Item_udf_sum(udf_arg,list) {}
1045
 
  Item_sum_udf_str(THD *thd, Item_sum_udf_str *item)
1046
 
    :Item_udf_sum(thd, item) {}
1047
 
  String *val_str(String *);
1048
 
  double val_real()
1049
 
  {
1050
 
    int err_not_used;
1051
 
    char *end_not_used;
1052
 
    String *res;
1053
 
    res=val_str(&str_value);
1054
 
    return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),
1055
 
                            &end_not_used, &err_not_used) : 0.0;
1056
 
  }
1057
 
  int64_t val_int()
1058
 
  {
1059
 
    int err_not_used;
1060
 
    char *end;
1061
 
    String *res;
1062
 
    const CHARSET_INFO *cs;
1063
 
 
1064
 
    if (!(res= val_str(&str_value)))
1065
 
      return 0;                                 /* Null value */
1066
 
    cs= res->charset();
1067
 
    end= (char*) res->ptr()+res->length();
1068
 
    return cs->cset->strtoll10(cs, res->ptr(), &end, &err_not_used);
1069
 
  }
1070
 
  my_decimal *val_decimal(my_decimal *dec);
1071
 
  enum Item_result result_type () const { return STRING_RESULT; }
1072
 
  void fix_length_and_dec();
1073
 
  Item *copy_or_same(THD* thd);
1074
 
};
1075
 
 
1076
 
 
1077
 
class Item_sum_udf_decimal :public Item_udf_sum
1078
 
{
1079
 
public:
1080
 
  Item_sum_udf_decimal(udf_func *udf_arg)
1081
 
    :Item_udf_sum(udf_arg) {}
1082
 
  Item_sum_udf_decimal(udf_func *udf_arg, List<Item> &list)
1083
 
    :Item_udf_sum(udf_arg, list) {}
1084
 
  Item_sum_udf_decimal(THD *thd, Item_sum_udf_decimal *item)
1085
 
    :Item_udf_sum(thd, item) {}
1086
 
  String *val_str(String *);
1087
 
  double val_real();
1088
 
  int64_t val_int();
1089
 
  my_decimal *val_decimal(my_decimal *);
1090
 
  enum Item_result result_type () const { return DECIMAL_RESULT; }
1091
 
  void fix_length_and_dec() { fix_num_length_and_dec(); }
1092
 
  Item *copy_or_same(THD* thd);
1093
 
};
 
959
  Item *copy_or_same(Session* session);
 
960
};
 
961
 
 
962
 
1094
963
 
1095
964
class DRIZZLE_ERROR;
1096
965
 
1097
966
class Item_func_group_concat : public Item_sum
1098
967
{
1099
 
  TMP_TABLE_PARAM *tmp_table_param;
 
968
  Tmp_Table_Param *tmp_table_param;
1100
969
  DRIZZLE_ERROR *warning;
1101
970
  String result;
1102
971
  String *separator;
1105
974
 
1106
975
  /**
1107
976
     If DISTINCT is used with this GROUP_CONCAT, this member is used to filter
1108
 
     out duplicates. 
 
977
     out duplicates.
1109
978
     @see Item_func_group_concat::setup
1110
979
     @see Item_func_group_concat::add
1111
980
     @see Item_func_group_concat::clear
1112
981
   */
1113
982
  Unique *unique_filter;
1114
 
  TABLE *table;
1115
 
  ORDER **order;
 
983
  Table *table;
 
984
  order_st **order;
1116
985
  Name_resolution_context *context;
1117
986
  /** The number of ORDER BY items. */
1118
 
  uint arg_count_order;
 
987
  uint32_t arg_count_order;
1119
988
  /** The number of selected items, aka the expr list. */
1120
 
  uint arg_count_field;
1121
 
  uint count_cut_values;
 
989
  uint32_t arg_count_field;
 
990
  uint32_t count_cut_values;
1122
991
  bool distinct;
1123
992
  bool warning_for_row;
1124
993
  bool always_null;
1134
1003
                                                const void* key2);
1135
1004
  friend int group_concat_key_cmp_with_order(void* arg, const void* key1,
1136
1005
                                             const void* key2);
1137
 
  friend int dump_leaf_key(uchar* key,
1138
 
                           element_count count __attribute__((unused)),
1139
 
                           Item_func_group_concat *group_concat_item);
 
1006
  friend int dump_leaf_key(unsigned char* key, uint32_t,
 
1007
                           Item_func_group_concat *group_concat_item);
1140
1008
 
1141
1009
public:
1142
1010
  Item_func_group_concat(Name_resolution_context *context_arg,
1143
1011
                         bool is_distinct, List<Item> *is_select,
1144
1012
                         SQL_LIST *is_order, String *is_separator);
1145
1013
 
1146
 
  Item_func_group_concat(THD *thd, Item_func_group_concat *item);
 
1014
  Item_func_group_concat(Session *session, Item_func_group_concat *item);
1147
1015
  ~Item_func_group_concat();
1148
1016
  void cleanup();
1149
1017
 
1161
1029
  bool add();
1162
1030
  void reset_field() { assert(0); }        // not used
1163
1031
  void update_field() { assert(0); }       // not used
1164
 
  bool fix_fields(THD *,Item **);
1165
 
  bool setup(THD *thd);
 
1032
  bool fix_fields(Session *,Item **);
 
1033
  bool setup(Session *session);
1166
1034
  void make_unique();
1167
 
  double val_real()
1168
 
  {
1169
 
    String *res;  res=val_str(&str_value);
1170
 
    return res ? my_atof(res->c_ptr()) : 0.0;
1171
 
  }
1172
 
  int64_t val_int()
1173
 
  {
1174
 
    String *res;
1175
 
    char *end_ptr;
1176
 
    int error;
1177
 
    if (!(res= val_str(&str_value)))
1178
 
      return (int64_t) 0;
1179
 
    end_ptr= (char*) res->ptr()+ res->length();
1180
 
    return my_strtoll10(res->ptr(), &end_ptr, &error);
1181
 
  }
 
1035
  double val_real();
 
1036
  int64_t val_int();
1182
1037
  my_decimal *val_decimal(my_decimal *decimal_value)
1183
1038
  {
1184
1039
    return val_decimal_from_string(decimal_value);
1185
1040
  }
1186
1041
  String* val_str(String* str);
1187
 
  Item *copy_or_same(THD* thd);
 
1042
  Item *copy_or_same(Session* session);
1188
1043
  void no_rows_in_result() {}
1189
1044
  virtual void print(String *str, enum_query_type query_type);
1190
 
  virtual bool change_context_processor(uchar *cntx)
 
1045
  virtual bool change_context_processor(unsigned char *cntx)
1191
1046
    { context= (Name_resolution_context *)cntx; return false; }
1192
1047
};
 
1048
 
 
1049
#endif /* DRIZZLED_ITEM_SUM_H */