~mysql/mysql-server/mysql-6.0

« back to all changes in this revision

Viewing changes to sql/item_sum.cc

  • Committer: bk at mysql
  • Date: 2000-07-31 19:29:14 UTC
  • Revision ID: sp1r-bk@work.mysql.com-20000731192914-08846
Import changeset

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either version 2 of the License, or
 
6
   (at your option) any later version.
 
7
   
 
8
   This program is distributed in the hope that it will be useful,
 
9
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
   GNU General Public License for more details.
 
12
   
 
13
   You should have received a copy of the GNU General Public License
 
14
   along with this program; if not, write to the Free Software
 
15
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
16
 
 
17
 
 
18
/* Sum functions (COUNT, MIN...) */
 
19
 
 
20
#ifdef __GNUC__
 
21
#pragma implementation                          // gcc: Class implementation
 
22
#endif
 
23
 
 
24
#include "mysql_priv.h"
 
25
 
 
26
 
 
27
Item_sum::Item_sum(List<Item> &list)
 
28
{
 
29
  arg_count=list.elements;
 
30
  if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
 
31
  {
 
32
    uint i=0;
 
33
    List_iterator<Item> li(list);
 
34
    Item *item;
 
35
 
 
36
    while ((item=li++))
 
37
    {
 
38
      args[i++]= item;
 
39
    }
 
40
  }
 
41
  with_sum_func=1;
 
42
  list.empty();                                 // Fields are used
 
43
}
 
44
 
 
45
 
 
46
void Item_sum::make_field(Send_field *tmp_field)
 
47
{
 
48
  if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
 
49
    ((Item_field*) args[0])->field->make_field(tmp_field);
 
50
  else
 
51
  {
 
52
    tmp_field->flags=0;
 
53
    if (!maybe_null)
 
54
      tmp_field->flags|= NOT_NULL_FLAG;
 
55
    tmp_field->length=max_length;
 
56
    tmp_field->decimals=decimals;
 
57
    tmp_field->type=(result_type() == INT_RESULT ? FIELD_TYPE_LONG :
 
58
                     result_type() == REAL_RESULT ? FIELD_TYPE_DOUBLE :
 
59
                     FIELD_TYPE_VAR_STRING);
 
60
  }
 
61
  tmp_field->table_name=(char*)"";
 
62
  tmp_field->col_name=name;
 
63
}
 
64
 
 
65
void Item_sum::print(String *str)
 
66
{
 
67
  str->append(func_name());
 
68
  str->append('(');
 
69
  for (uint i=0 ; i < arg_count ; i++)
 
70
  {
 
71
    if (i)
 
72
      str->append(',');
 
73
    args[i]->print(str);
 
74
  }
 
75
  str->append(')');
 
76
}
 
77
 
 
78
void Item_sum::fix_num_length_and_dec()
 
79
{
 
80
  decimals=0;
 
81
  for (uint i=0 ; i < arg_count ; i++)
 
82
    set_if_bigger(decimals,args[i]->decimals);
 
83
  max_length=float_length(decimals);
 
84
}
 
85
 
 
86
 
 
87
String *
 
88
Item_sum_num::val_str(String *str)
 
89
{
 
90
  double nr=val();
 
91
  if (null_value)
 
92
    return 0;
 
93
  str->set(nr,decimals);
 
94
  return str;
 
95
}
 
96
 
 
97
 
 
98
String *
 
99
Item_sum_int::val_str(String *str)
 
100
{
 
101
  longlong nr=val_int();
 
102
  if (null_value)
 
103
    return 0;
 
104
  char buff[21];
 
105
  uint length= (uint) (longlong10_to_str(nr,buff,-10)-buff);
 
106
  str->copy(buff,length);
 
107
  return str;
 
108
}
 
109
 
 
110
 
 
111
bool
 
112
Item_sum_num::fix_fields(THD *thd,TABLE_LIST *tables)
 
113
{
 
114
  if (!thd->allow_sum_func)
 
115
  {
 
116
    my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0));
 
117
    return 1;
 
118
  }
 
119
  thd->allow_sum_func=0;                        // No included group funcs
 
120
  decimals=0;
 
121
  maybe_null=0;
 
122
  for (uint i=0 ; i < arg_count ; i++)
 
123
  {
 
124
    if (args[i]->fix_fields(thd,tables))
 
125
      return 1;
 
126
    if (decimals < args[i]->decimals)
 
127
      decimals=args[i]->decimals;
 
128
    maybe_null |= args[i]->maybe_null;
 
129
  }
 
130
  result_field=0;
 
131
  max_length=float_length(decimals);
 
132
  null_value=1;
 
133
  fix_length_and_dec();
 
134
  thd->allow_sum_func=1;                        // Allow group functions
 
135
  return 0;
 
136
}
 
137
 
 
138
 
 
139
bool
 
140
Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables)
 
141
{
 
142
  Item *item=args[0];
 
143
  if (!thd->allow_sum_func)
 
144
  {
 
145
    my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0));
 
146
    return 1;
 
147
  }
 
148
  thd->allow_sum_func=0;                        // No included group funcs
 
149
  if (item->fix_fields(thd,tables))
 
150
    return 1;
 
151
  hybrid_type=item->result_type();
 
152
  if (hybrid_type == INT_RESULT)
 
153
    max_length=21;
 
154
  else if (hybrid_type == REAL_RESULT)
 
155
    max_length=float_length(decimals);
 
156
  else
 
157
    max_length=item->max_length;
 
158
  decimals=item->decimals;
 
159
  maybe_null=item->maybe_null;
 
160
  binary=item->binary;
 
161
  result_field=0;
 
162
  null_value=1;
 
163
  fix_length_and_dec();
 
164
  thd->allow_sum_func=1;                        // Allow group functions
 
165
  return 0;
 
166
}
 
167
 
 
168
 
 
169
/***********************************************************************
 
170
** reset and add of sum_func
 
171
***********************************************************************/
 
172
 
 
173
void Item_sum_sum::reset()
 
174
{
 
175
  null_value=0; sum=0.0; Item_sum_sum::add();
 
176
}
 
177
 
 
178
bool Item_sum_sum::add()
 
179
{
 
180
  sum+=args[0]->val();
 
181
  return 0;
 
182
}
 
183
 
 
184
double Item_sum_sum::val()
 
185
{
 
186
  return sum;
 
187
}
 
188
 
 
189
 
 
190
void Item_sum_count::reset()
 
191
{
 
192
  count=0; add();
 
193
}
 
194
 
 
195
bool Item_sum_count::add()
 
196
{
 
197
  if (!args[0]->maybe_null)
 
198
    count++;
 
199
  else
 
200
  {
 
201
    (void) args[0]->val_int();
 
202
    if (!args[0]->null_value)
 
203
      count++;
 
204
  }
 
205
  return 0;
 
206
}
 
207
 
 
208
longlong Item_sum_count::val_int()
 
209
{
 
210
  return (longlong) count;
 
211
}
 
212
 
 
213
/*
 
214
** Avgerage
 
215
*/
 
216
 
 
217
void Item_sum_avg::reset()
 
218
{
 
219
  sum=0.0; count=0; Item_sum_avg::add();
 
220
}
 
221
 
 
222
bool Item_sum_avg::add()
 
223
{
 
224
  double nr=args[0]->val();
 
225
  if (!args[0]->null_value)
 
226
  {
 
227
    sum+=nr;
 
228
    count++;
 
229
  }
 
230
  return 0;
 
231
}
 
232
 
 
233
double Item_sum_avg::val()
 
234
{
 
235
  if (!count)
 
236
  {
 
237
    null_value=1;
 
238
    return 0.0;
 
239
  }
 
240
  null_value=0;
 
241
  return sum/ulonglong2double(count);
 
242
}
 
243
 
 
244
 
 
245
/*
 
246
** Standard deviation
 
247
*/
 
248
 
 
249
void Item_sum_std::reset()
 
250
{
 
251
  sum=sum_sqr=0.0; count=0; (void) Item_sum_std::add();
 
252
}
 
253
 
 
254
bool Item_sum_std::add()
 
255
{
 
256
  double nr=args[0]->val();
 
257
  if (!args[0]->null_value)
 
258
  {
 
259
    sum+=nr;
 
260
    sum_sqr+=nr*nr;
 
261
    count++;
 
262
  }
 
263
  return 0;
 
264
}
 
265
 
 
266
double Item_sum_std::val()
 
267
{
 
268
  if (!count)
 
269
  {
 
270
    null_value=1;
 
271
    return 0.0;
 
272
  }
 
273
  null_value=0;
 
274
  /* Avoid problems when the precision isn't good enough */
 
275
  double tmp=ulonglong2double(count);
 
276
  double tmp2=(sum_sqr - sum*sum/tmp)/tmp;
 
277
  return tmp2 <= 0.0 ? 0.0 : sqrt(tmp2);
 
278
}
 
279
 
 
280
 
 
281
void Item_sum_std::reset_field()
 
282
{
 
283
  double nr=args[0]->val();
 
284
  char *res=result_field->ptr;
 
285
 
 
286
  if (args[0]->null_value)
 
287
    bzero(res,sizeof(double)*2+sizeof(longlong));
 
288
  else
 
289
  {
 
290
    float8store(res,nr);
 
291
    nr*=nr;
 
292
    float8store(res+sizeof(double),nr);
 
293
    longlong tmp=1;
 
294
    int8store(res+sizeof(double)*2,tmp);
 
295
  }
 
296
}
 
297
 
 
298
void Item_sum_std::update_field(int offset)
 
299
{
 
300
  double nr,old_nr,old_sqr;
 
301
  longlong field_count;
 
302
  char *res=result_field->ptr;
 
303
 
 
304
  float8get(old_nr,res+offset);
 
305
  float8get(old_sqr,res+offset+sizeof(double));
 
306
  field_count=sint8korr(res+offset+sizeof(double)*2);
 
307
 
 
308
  nr=args[0]->val();
 
309
  if (!args[0]->null_value)
 
310
  {
 
311
    old_nr+=nr;
 
312
    old_sqr+=nr*nr;
 
313
    field_count++;
 
314
  }
 
315
  float8store(res,old_nr);
 
316
  float8store(res+sizeof(double),old_sqr);
 
317
  int8store(res+sizeof(double)*2,field_count);
 
318
}
 
319
 
 
320
/* min & max */
 
321
 
 
322
double Item_sum_hybrid::val()
 
323
{
 
324
  if (null_value)
 
325
    return 0.0;
 
326
  if (hybrid_type == STRING_RESULT)
 
327
  {
 
328
    String *res;  res=val_str(&str_value);
 
329
    return res ? atof(res->c_ptr()) : 0.0;
 
330
  }
 
331
  return sum;
 
332
}
 
333
 
 
334
 
 
335
String *
 
336
Item_sum_hybrid::val_str(String *str)
 
337
{
 
338
  if (null_value)
 
339
    return 0;
 
340
  if (hybrid_type == STRING_RESULT)
 
341
    return &value;
 
342
  str->set(sum,decimals);
 
343
  return str;
 
344
}
 
345
 
 
346
 
 
347
bool Item_sum_min::add()
 
348
{
 
349
  if (hybrid_type != STRING_RESULT)
 
350
  {
 
351
    double nr=args[0]->val();
 
352
    if (!args[0]->null_value && (null_value || nr < sum))
 
353
    {
 
354
      sum=nr;
 
355
      null_value=0;
 
356
    }
 
357
  }
 
358
  else
 
359
  {
 
360
    String *result=args[0]->val_str(&tmp_value);
 
361
    if (!args[0]->null_value &&
 
362
        (null_value ||
 
363
         (binary ? stringcmp(&value,result) : sortcmp(&value,result)) > 0))
 
364
    {
 
365
      value.copy(*result);
 
366
      null_value=0;
 
367
    }
 
368
  }
 
369
  return 0;
 
370
}
 
371
 
 
372
 
 
373
bool Item_sum_max::add()
 
374
{
 
375
  if (hybrid_type != STRING_RESULT)
 
376
  {
 
377
    double nr=args[0]->val();
 
378
    if (!args[0]->null_value && (null_value || nr > sum))
 
379
    {
 
380
      sum=nr;
 
381
      null_value=0;
 
382
    }
 
383
  }
 
384
  else
 
385
  {
 
386
    String *result=args[0]->val_str(&tmp_value);
 
387
    if (!args[0]->null_value &&
 
388
        (null_value ||
 
389
         (binary ? stringcmp(&value,result) : sortcmp(&value,result)) < 0))
 
390
    {
 
391
      value.copy(*result);
 
392
      null_value=0;
 
393
    }
 
394
  }
 
395
  return 0;
 
396
}
 
397
 
 
398
 
 
399
/* bit_or and bit_and */
 
400
 
 
401
longlong Item_sum_bit::val_int()
 
402
{
 
403
  return (longlong) bits;
 
404
}
 
405
 
 
406
void Item_sum_bit::reset()
 
407
{
 
408
  bits=reset_bits; add();
 
409
}
 
410
 
 
411
bool Item_sum_or::add()
 
412
{
 
413
  ulonglong value= (ulonglong) args[0]->val_int();
 
414
  if (!args[0]->null_value)
 
415
    bits|=value;
 
416
  return 0;
 
417
}
 
418
 
 
419
bool Item_sum_and::add()
 
420
{
 
421
  ulonglong value= (ulonglong) args[0]->val_int();
 
422
  if (!args[0]->null_value)
 
423
    bits&=value;
 
424
  return 0;
 
425
}
 
426
 
 
427
/************************************************************************
 
428
** reset result of a Item_sum with is saved in a tmp_table
 
429
*************************************************************************/
 
430
 
 
431
void Item_sum_num::reset_field()
 
432
{
 
433
  double nr=args[0]->val();
 
434
  char *res=result_field->ptr;
 
435
 
 
436
  if (maybe_null)
 
437
  {
 
438
    if (args[0]->null_value)
 
439
    {
 
440
      nr=0.0;
 
441
      result_field->set_null();
 
442
    }
 
443
    else
 
444
      result_field->set_notnull();
 
445
  }
 
446
  float8store(res,nr);
 
447
}
 
448
 
 
449
 
 
450
void Item_sum_hybrid::reset_field()
 
451
{
 
452
  if (hybrid_type == STRING_RESULT)
 
453
  {
 
454
    char buff[MAX_FIELD_WIDTH];
 
455
    String tmp(buff,sizeof(buff)),*res;
 
456
 
 
457
    res=args[0]->val_str(&tmp);
 
458
    if (args[0]->null_value)
 
459
    {
 
460
      result_field->set_null();
 
461
      result_field->reset();
 
462
    }
 
463
    else
 
464
    {
 
465
      result_field->set_notnull();
 
466
      result_field->store(res->ptr(),res->length());
 
467
    }
 
468
  }
 
469
  else if (hybrid_type == INT_RESULT)
 
470
  {
 
471
    longlong nr=args[0]->val_int();
 
472
 
 
473
    if (maybe_null)
 
474
    {
 
475
      if (args[0]->null_value)
 
476
      {
 
477
        nr=0;
 
478
        result_field->set_null();
 
479
      }
 
480
      else
 
481
        result_field->set_notnull();
 
482
    }
 
483
    result_field->store(nr);
 
484
  }
 
485
  else                                          // REAL_RESULT
 
486
  {
 
487
    double nr=args[0]->val();
 
488
 
 
489
    if (maybe_null)
 
490
    {
 
491
      if (args[0]->null_value)
 
492
      {
 
493
        nr=0.0;
 
494
        result_field->set_null();
 
495
      }
 
496
      else
 
497
        result_field->set_notnull();
 
498
    }
 
499
    result_field->store(nr);
 
500
  }
 
501
}
 
502
 
 
503
 
 
504
void Item_sum_sum::reset_field()
 
505
{
 
506
  double nr=args[0]->val();                     // Nulls also return 0
 
507
  float8store(result_field->ptr,nr);
 
508
  null_value=0;
 
509
  result_field->set_notnull();
 
510
}
 
511
 
 
512
 
 
513
void Item_sum_count::reset_field()
 
514
{
 
515
  char *res=result_field->ptr;
 
516
  longlong nr=0;
 
517
 
 
518
  if (!args[0]->maybe_null)
 
519
    nr=1;
 
520
  else
 
521
  {
 
522
    (void) args[0]->val_int();
 
523
    if (!args[0]->null_value)
 
524
      nr=1;
 
525
  }
 
526
  int8store(res,nr);
 
527
}
 
528
 
 
529
 
 
530
void Item_sum_avg::reset_field()
 
531
{
 
532
  double nr=args[0]->val();
 
533
  char *res=result_field->ptr;
 
534
 
 
535
  if (args[0]->null_value)
 
536
    bzero(res,sizeof(double)+sizeof(longlong));
 
537
  else
 
538
  {
 
539
    float8store(res,nr);
 
540
    res+=sizeof(double);
 
541
    longlong tmp=1;
 
542
    int8store(res,tmp);
 
543
  }
 
544
}
 
545
 
 
546
void Item_sum_bit::reset_field()
 
547
{
 
548
  char *res=result_field->ptr;
 
549
  ulonglong nr=(ulonglong) args[0]->val_int();
 
550
  int8store(res,nr);
 
551
}
 
552
 
 
553
/*
 
554
** calc next value and merge it with field_value
 
555
*/
 
556
 
 
557
void Item_sum_sum::update_field(int offset)
 
558
{
 
559
  double old_nr,nr;
 
560
  char *res=result_field->ptr;
 
561
 
 
562
  float8get(old_nr,res+offset);
 
563
  nr=args[0]->val();
 
564
  if (!args[0]->null_value)
 
565
    old_nr+=nr;
 
566
  float8store(res,old_nr);
 
567
}
 
568
 
 
569
 
 
570
void Item_sum_count::update_field(int offset)
 
571
{
 
572
  longlong nr;
 
573
  char *res=result_field->ptr;
 
574
 
 
575
  nr=sint8korr(res+offset);
 
576
  if (!args[0]->maybe_null)
 
577
    nr++;
 
578
  else
 
579
  {
 
580
    (void) args[0]->val_int();
 
581
    if (!args[0]->null_value)
 
582
      nr++;
 
583
  }
 
584
  int8store(res,nr);
 
585
}
 
586
 
 
587
 
 
588
void Item_sum_avg::update_field(int offset)
 
589
{
 
590
  double nr,old_nr;
 
591
  longlong field_count;
 
592
  char *res=result_field->ptr;
 
593
 
 
594
  float8get(old_nr,res+offset);
 
595
  field_count=sint8korr(res+offset+sizeof(double));
 
596
 
 
597
  nr=args[0]->val();
 
598
  if (!args[0]->null_value)
 
599
  {
 
600
    old_nr+=nr;
 
601
    field_count++;
 
602
  }
 
603
  float8store(res,old_nr);
 
604
  res+=sizeof(double);
 
605
  int8store(res,field_count);
 
606
}
 
607
 
 
608
void Item_sum_hybrid::update_field(int offset)
 
609
{
 
610
  if (hybrid_type == STRING_RESULT)
 
611
    min_max_update_str_field(offset);
 
612
  else if (hybrid_type == INT_RESULT)
 
613
    min_max_update_int_field(offset);
 
614
  else
 
615
    min_max_update_real_field(offset);
 
616
}
 
617
 
 
618
 
 
619
void
 
620
Item_sum_hybrid::min_max_update_str_field(int offset)
 
621
{
 
622
  String *res_str=args[0]->val_str(&value);
 
623
 
 
624
  if (args[0]->null_value)
 
625
    result_field->copy_from_tmp(offset);        // Use old value
 
626
  else
 
627
  {
 
628
    res_str->strip_sp();
 
629
    result_field->ptr+=offset;                  // Get old max/min
 
630
    result_field->val_str(&tmp_value,&tmp_value);
 
631
    result_field->ptr-=offset;
 
632
 
 
633
    if (result_field->is_null() ||
 
634
        (cmp_sign * (binary ? stringcmp(res_str,&tmp_value) :
 
635
                 sortcmp(res_str,&tmp_value)) < 0))
 
636
      result_field->store(res_str->ptr(),res_str->length());
 
637
    else
 
638
    {                                           // Use old value
 
639
      char *res=result_field->ptr;
 
640
      memcpy(res,res+offset,result_field->pack_length());
 
641
    }
 
642
    result_field->set_notnull();
 
643
  }
 
644
}
 
645
 
 
646
 
 
647
void
 
648
Item_sum_hybrid::min_max_update_real_field(int offset)
 
649
{
 
650
  double nr,old_nr;
 
651
 
 
652
  result_field->ptr+=offset;
 
653
  old_nr=result_field->val_real();
 
654
  nr=args[0]->val();
 
655
  if (!args[0]->null_value)
 
656
  {
 
657
    if (result_field->is_null(offset) ||
 
658
        (cmp_sign > 0 ? old_nr > nr : old_nr < nr))
 
659
      old_nr=nr;
 
660
    result_field->set_notnull();
 
661
  }
 
662
  else if (result_field->is_null(offset))
 
663
    result_field->set_null();
 
664
  result_field->ptr-=offset;
 
665
  result_field->store(old_nr);
 
666
}
 
667
 
 
668
 
 
669
void
 
670
Item_sum_hybrid::min_max_update_int_field(int offset)
 
671
{
 
672
  longlong nr,old_nr;
 
673
 
 
674
  result_field->ptr+=offset;
 
675
  old_nr=result_field->val_int();
 
676
  nr=args[0]->val_int();
 
677
  if (!args[0]->null_value)
 
678
  {
 
679
    if (result_field->is_null(offset) ||
 
680
        (cmp_sign > 0 ? old_nr > nr : old_nr < nr))
 
681
      old_nr=nr;
 
682
    result_field->set_notnull();
 
683
  }
 
684
  else if (result_field->is_null(offset))
 
685
    result_field->set_null();
 
686
  result_field->ptr-=offset;
 
687
  result_field->store(old_nr);
 
688
}
 
689
 
 
690
 
 
691
void Item_sum_or::update_field(int offset)
 
692
{
 
693
  ulonglong nr;
 
694
  char *res=result_field->ptr;
 
695
 
 
696
  nr=uint8korr(res+offset);
 
697
  nr|= (ulonglong) args[0]->val_int();
 
698
  int8store(res,nr);
 
699
}
 
700
 
 
701
 
 
702
void Item_sum_and::update_field(int offset)
 
703
{
 
704
  ulonglong nr;
 
705
  char *res=result_field->ptr;
 
706
 
 
707
  nr=uint8korr(res+offset);
 
708
  nr&= (ulonglong) args[0]->val_int();
 
709
  int8store(res,nr);
 
710
}
 
711
 
 
712
 
 
713
Item_avg_field::Item_avg_field(Item_sum_avg *item)
 
714
{
 
715
  name=item->name;
 
716
  decimals=item->decimals;
 
717
  max_length=item->max_length;
 
718
  field=item->result_field;
 
719
  maybe_null=1;
 
720
}
 
721
 
 
722
double Item_avg_field::val()
 
723
{
 
724
  double nr;
 
725
  longlong count;
 
726
  float8get(nr,field->ptr);
 
727
  char *res=(field->ptr+sizeof(double));
 
728
  count=sint8korr(res);
 
729
 
 
730
  if (!count)
 
731
  {
 
732
    null_value=1;
 
733
    return 0.0;
 
734
  }
 
735
  null_value=0;
 
736
  return nr/(double) count;
 
737
}
 
738
 
 
739
String *Item_avg_field::val_str(String *str)
 
740
{
 
741
  double nr=Item_avg_field::val();
 
742
  if (null_value)
 
743
    return 0;
 
744
  str->set(nr,decimals);
 
745
  return str;
 
746
}
 
747
 
 
748
Item_std_field::Item_std_field(Item_sum_std *item)
 
749
{
 
750
  name=item->name;
 
751
  decimals=item->decimals;
 
752
  max_length=item->max_length;
 
753
  field=item->result_field;
 
754
  maybe_null=1;
 
755
}
 
756
 
 
757
double Item_std_field::val()
 
758
{
 
759
  double sum,sum_sqr;
 
760
  longlong count;
 
761
  float8get(sum,field->ptr);
 
762
  float8get(sum_sqr,(field->ptr+sizeof(double)));
 
763
  count=sint8korr(field->ptr+sizeof(double)*2);
 
764
 
 
765
  if (!count)
 
766
  {
 
767
    null_value=1;
 
768
    return 0.0;
 
769
  }
 
770
  null_value=0;
 
771
  double tmp= (double) count;
 
772
  double tmp2=(sum_sqr - sum*sum/tmp)/tmp;
 
773
  return tmp2 <= 0.0 ? 0.0 : sqrt(tmp2);
 
774
}
 
775
 
 
776
String *Item_std_field::val_str(String *str)
 
777
{
 
778
  double nr=val();
 
779
  if (null_value)
 
780
    return 0;
 
781
  str->set(nr,decimals);
 
782
  return str;
 
783
}
 
784
 
 
785
/****************************************************************************
 
786
** COUNT(DISTINCT ...)
 
787
****************************************************************************/
 
788
 
 
789
#include "sql_select.h"
 
790
 
 
791
Item_sum_count_distinct::~Item_sum_count_distinct()
 
792
{
 
793
  if (table)
 
794
    free_tmp_table(current_thd, table);
 
795
  delete tmp_table_param;
 
796
}
 
797
 
 
798
 
 
799
bool Item_sum_count_distinct::fix_fields(THD *thd,TABLE_LIST *tables)
 
800
{
 
801
  if (Item_sum_num::fix_fields(thd,tables) ||
 
802
      !(tmp_table_param= new TMP_TABLE_PARAM))
 
803
    return 1;
 
804
  return 0;
 
805
}
 
806
 
 
807
bool Item_sum_count_distinct::setup(THD *thd)
 
808
{
 
809
  List<Item> list;
 
810
  /* Create a table with an unique key over all parameters */
 
811
  for (uint i=0; i < arg_count ; i++)
 
812
    if (list.push_back(args[i]))
 
813
      return 1;
 
814
  count_field_types(tmp_table_param,list);
 
815
  if (table)
 
816
  {
 
817
    free_tmp_table(thd, table);
 
818
    tmp_table_param->cleanup();
 
819
  }
 
820
  if (!(table=create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, 1,
 
821
                               0, 0, current_lex->options | thd->options)))
 
822
    return 1;
 
823
  table->file->extra(HA_EXTRA_NO_ROWS);         // Don't update rows
 
824
  return 0;
 
825
}
 
826
 
 
827
 
 
828
void Item_sum_count_distinct::reset()
 
829
{
 
830
  table->file->extra(HA_EXTRA_NO_CACHE);
 
831
  table->file->delete_all_rows();
 
832
  table->file->extra(HA_EXTRA_WRITE_CACHE);
 
833
  (void) add();
 
834
}
 
835
 
 
836
bool Item_sum_count_distinct::add()
 
837
{
 
838
  int error;
 
839
  copy_fields(tmp_table_param);
 
840
  copy_funcs(tmp_table_param->funcs);
 
841
 
 
842
  if ((error=table->file->write_row(table->record[0])))
 
843
  {
 
844
    if (error != HA_ERR_FOUND_DUPP_KEY &&
 
845
        error != HA_ERR_FOUND_DUPP_UNIQUE)
 
846
    {
 
847
      if (create_myisam_from_heap(table, tmp_table_param, error,1))
 
848
        return 1;                               // Not a table_is_full error
 
849
    }
 
850
  }
 
851
  return 0;
 
852
}
 
853
 
 
854
longlong Item_sum_count_distinct::val_int()
 
855
{
 
856
  if (!table)                                   // Empty query
 
857
    return LL(0);
 
858
  table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
 
859
  return table->file->records;
 
860
}
 
861
 
 
862
/****************************************************************************
 
863
** Functions to handle dynamic loadable aggregates
 
864
** Original source by: Alexis Mikhailov <root@medinf.chuvashia.su>
 
865
** Adapted for UDAs by: Andreas F. Bobak <bobak@relog.ch>.
 
866
** Rewritten by: Monty.
 
867
****************************************************************************/
 
868
 
 
869
#ifdef HAVE_DLOPEN
 
870
 
 
871
void Item_udf_sum::reset()
 
872
{
 
873
  DBUG_ENTER("Item_udf_sum::reset");
 
874
  udf.reset(&null_value);
 
875
  DBUG_VOID_RETURN;
 
876
}
 
877
 
 
878
bool Item_udf_sum::add()
 
879
{
 
880
  DBUG_ENTER("Item_udf_sum::reset");
 
881
  udf.add(&null_value);
 
882
  DBUG_RETURN(0);
 
883
}
 
884
 
 
885
double Item_sum_udf_float::val()
 
886
{
 
887
  DBUG_ENTER("Item_sum_udf_float::val");
 
888
  DBUG_PRINT("info",("result_type: %d  arg_count: %d",
 
889
                     args[0]->result_type(), arg_count));
 
890
  DBUG_RETURN(udf.val(&null_value));
 
891
}
 
892
 
 
893
String *Item_sum_udf_float::val_str(String *str)
 
894
{
 
895
  double nr=val();
 
896
  if (null_value)
 
897
    return 0;                                   /* purecov: inspected */
 
898
  else
 
899
    str->set(nr,decimals);
 
900
  return str;
 
901
}
 
902
 
 
903
 
 
904
longlong Item_sum_udf_int::val_int()
 
905
{
 
906
  DBUG_ENTER("Item_sum_udf_int::val_int");
 
907
  DBUG_PRINT("info",("result_type: %d  arg_count: %d",
 
908
                     args[0]->result_type(), arg_count));
 
909
  DBUG_RETURN(udf.val_int(&null_value));
 
910
}
 
911
 
 
912
String *Item_sum_udf_int::val_str(String *str)
 
913
{
 
914
  longlong nr=val_int();
 
915
  if (null_value)
 
916
    return 0;
 
917
  else
 
918
    str->set(nr);
 
919
  return str;
 
920
}
 
921
 
 
922
/* Default max_length is max argument length */
 
923
 
 
924
void Item_sum_udf_str::fix_length_and_dec()
 
925
{
 
926
  DBUG_ENTER("Item_sum_udf_str::fix_length_and_dec");
 
927
  max_length=0;
 
928
  for (uint i = 0; i < arg_count; i++)
 
929
    set_if_bigger(max_length,args[i]->max_length);
 
930
  DBUG_VOID_RETURN;
 
931
}
 
932
 
 
933
String *Item_sum_udf_str::val_str(String *str)
 
934
{
 
935
  DBUG_ENTER("Item_sum_udf_str::str");
 
936
  String *res=udf.val_str(str,&str_value);
 
937
  null_value = !res;
 
938
  DBUG_RETURN(res);
 
939
}
 
940
 
 
941
#endif /* HAVE_DLOPEN */