~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/functions/func.cc

  • Committer: Brian Aker
  • Date: 2008-10-18 15:43:20 UTC
  • mto: (492.3.20 drizzle-clean-code)
  • mto: This revision was merged to the branch mainline in revision 530.
  • Revision ID: brian@tangent.org-20081018154320-jc9jyij3mdf08abp
Updating tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
#include <config.h>
21
 
 
22
 
#include <drizzled/check_stack_overrun.h>
23
 
#include <drizzled/current_session.h>
24
 
#include <drizzled/error.h>
25
 
#include <drizzled/field/decimal.h>
26
 
#include <drizzled/field/double.h>
27
 
#include <drizzled/field/int32.h>
28
 
#include <drizzled/field/int64.h>
29
 
#include <drizzled/field/size.h>
30
 
#include <drizzled/function/math/int.h>
31
 
#include <drizzled/session.h>
 
20
#include <drizzled/server_includes.h>
 
21
 
 
22
#include CSTDINT_H
 
23
#include <cassert>
 
24
 
 
25
#include <drizzled/version.h>
 
26
 
 
27
#include <drizzled/sql_string.h>
32
28
#include <drizzled/sql_list.h>
33
 
#include <drizzled/sql_string.h>
34
 
 
35
 
#include <limits>
36
 
#include <algorithm>
37
 
 
38
 
using namespace std;
39
 
 
40
 
namespace drizzled
41
 
{
42
 
 
43
 
 
44
 
Item_func::Item_func(void):
45
 
  _session(*current_session),
46
 
  allowed_arg_cols(1), arg_count(0),
47
 
  const_item_cache(false)
48
 
  {
49
 
    with_sum_func= 0;
50
 
    collation.set(DERIVATION_SYSCONST);
51
 
  }
52
 
 
53
 
Item_func::Item_func(Item *a):
54
 
  _session(*current_session),
55
 
  allowed_arg_cols(1), arg_count(1),
56
 
  const_item_cache(false)
57
 
  {
58
 
    args= tmp_arg;
59
 
    args[0]= a;
60
 
    with_sum_func= a->with_sum_func;
61
 
    collation.set(DERIVATION_SYSCONST);
62
 
  }
63
 
 
64
 
Item_func::Item_func(Item *a,Item *b):
65
 
  _session(*current_session),
66
 
  allowed_arg_cols(1), arg_count(2),
67
 
  const_item_cache(false)
68
 
  {
69
 
    args= tmp_arg;
70
 
    args[0]= a; args[1]= b;
71
 
    with_sum_func= a->with_sum_func || b->with_sum_func;
72
 
    collation.set(DERIVATION_SYSCONST);
73
 
  }
74
 
 
75
 
Item_func::Item_func(Item *a,Item *b,Item *c):
76
 
  _session(*current_session),
77
 
  allowed_arg_cols(1),
78
 
  const_item_cache(false)
79
 
  {
80
 
    arg_count= 0;
81
 
    if ((args= (Item**) memory::sql_alloc(sizeof(Item*)*3)))
82
 
    {
83
 
      arg_count= 3;
84
 
      args[0]= a; args[1]= b; args[2]= c;
85
 
      with_sum_func= a->with_sum_func || b->with_sum_func || c->with_sum_func;
86
 
    }
87
 
    collation.set(DERIVATION_SYSCONST);
88
 
  }
89
 
 
90
 
Item_func::Item_func(Item *a,Item *b,Item *c,Item *d):
91
 
  _session(*current_session),
92
 
  allowed_arg_cols(1),
93
 
  const_item_cache(false)
94
 
  {
95
 
    arg_count= 0;
96
 
    if ((args= (Item**) memory::sql_alloc(sizeof(Item*)*4)))
97
 
    {
98
 
      arg_count= 4;
99
 
      args[0]= a; args[1]= b; args[2]= c; args[3]= d;
100
 
      with_sum_func= a->with_sum_func || b->with_sum_func ||
101
 
        c->with_sum_func || d->with_sum_func;
102
 
    }
103
 
    collation.set(DERIVATION_SYSCONST);
104
 
  }
105
 
 
106
 
Item_func::Item_func(Item *a,Item *b,Item *c,Item *d,Item* e):
107
 
  _session(*current_session),
108
 
  allowed_arg_cols(1),
109
 
  const_item_cache(false)
110
 
  {
111
 
    arg_count= 5;
112
 
    if ((args= (Item**) memory::sql_alloc(sizeof(Item*)*5)))
113
 
    {
114
 
      args[0]= a; args[1]= b; args[2]= c; args[3]= d; args[4]= e;
115
 
      with_sum_func= a->with_sum_func || b->with_sum_func ||
116
 
        c->with_sum_func || d->with_sum_func || e->with_sum_func ;
117
 
    }
118
 
    collation.set(DERIVATION_SYSCONST);
119
 
  }
 
29
 
 
30
#include <drizzled/functions/int.h>
120
31
 
121
32
 
122
33
void Item_func::set_arguments(List<Item> &list)
124
35
  allowed_arg_cols= 1;
125
36
  arg_count=list.elements;
126
37
  args= tmp_arg;                                // If 2 arguments
127
 
  if (arg_count <= 2 || (args=(Item**) memory::sql_alloc(sizeof(Item*)*arg_count)))
 
38
  if (arg_count <= 2 || (args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
128
39
  {
129
 
    List<Item>::iterator li(list.begin());
 
40
    List_iterator_fast<Item> li(list);
130
41
    Item *item;
131
42
    Item **save_args= args;
132
43
 
136
47
      with_sum_func|=item->with_sum_func;
137
48
    }
138
49
  }
139
 
  list.clear();          // Fields are used
 
50
  list.empty();          // Fields are used
140
51
}
141
52
 
142
 
Item_func::Item_func(List<Item> &list) :
143
 
  _session(*current_session),
144
 
  allowed_arg_cols(1),
145
 
  const_item_cache(false)
 
53
Item_func::Item_func(List<Item> &list)
 
54
  :allowed_arg_cols(1)
146
55
{
147
 
  collation.set(DERIVATION_SYSCONST);
148
56
  set_arguments(list);
149
57
}
150
58
 
151
 
Item_func::Item_func(Session *session, Item_func *item) :
152
 
  Item_result_field(session, item),
153
 
  _session(*current_session),
154
 
  allowed_arg_cols(item->allowed_arg_cols),
155
 
  arg_count(item->arg_count),
156
 
  used_tables_cache(item->used_tables_cache),
157
 
  not_null_tables_cache(item->not_null_tables_cache),
158
 
  const_item_cache(item->const_item_cache)
 
59
Item_func::Item_func(THD *thd, Item_func *item)
 
60
  :Item_result_field(thd, item),
 
61
   allowed_arg_cols(item->allowed_arg_cols),
 
62
   arg_count(item->arg_count),
 
63
   used_tables_cache(item->used_tables_cache),
 
64
   not_null_tables_cache(item->not_null_tables_cache),
 
65
   const_item_cache(item->const_item_cache)
159
66
{
160
67
  if (arg_count)
161
68
  {
163
70
      args= tmp_arg;
164
71
    else
165
72
    {
166
 
      if (!(args=(Item**) session->getMemRoot()->allocate(sizeof(Item*)*arg_count)))
 
73
      if (!(args=(Item**) thd->alloc(sizeof(Item*)*arg_count)))
167
74
        return;
168
75
    }
169
76
    memcpy(args, item->args, sizeof(Item*)*arg_count);
170
77
  }
171
 
  collation.set(DERIVATION_SYSCONST);
172
78
}
173
79
 
174
80
 
177
83
 
178
84
  SYNOPSIS:
179
85
  fix_fields()
180
 
  session    Thread object
 
86
  thd    Thread object
181
87
  ref    Pointer to where this object is used.  This reference
182
88
  is used if we want to replace this object with another
183
89
  one (for example in the summary functions).
206
112
*/
207
113
 
208
114
bool
209
 
Item_func::fix_fields(Session *session, Item **)
 
115
Item_func::fix_fields(THD *thd, Item **ref __attribute__((unused)))
210
116
{
211
117
  assert(fixed == 0);
212
118
  Item **arg,**arg_end;
213
 
  void *save_session_marker= session->session_marker;
 
119
  void *save_thd_marker= thd->thd_marker;
214
120
  unsigned char buff[STACK_BUFF_ALLOC];      // Max argument in function
215
 
  session->session_marker= 0;
 
121
  thd->thd_marker= 0;
216
122
  used_tables_cache= not_null_tables_cache= 0;
217
 
  const_item_cache= true;
 
123
  const_item_cache=1;
218
124
 
219
 
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
 
125
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
220
126
    return true;        // Fatal error if flag is set!
221
127
  if (arg_count)
222
128
  {            // Print purify happy
227
133
        We can't yet set item to *arg as fix_fields may change *arg
228
134
        We shouldn't call fix_fields() twice, so check 'fixed' field first
229
135
      */
230
 
      if ((!(*arg)->fixed && (*arg)->fix_fields(session, arg)))
231
 
        return true;
 
136
      if ((!(*arg)->fixed && (*arg)->fix_fields(thd, arg)))
 
137
        return true;        /* purecov: inspected */
232
138
      item= *arg;
233
139
 
234
140
      if (allowed_arg_cols)
255
161
    }
256
162
  }
257
163
  fix_length_and_dec();
258
 
  if (session->is_error()) // An error inside fix_length_and_dec occured
 
164
  if (thd->is_error()) // An error inside fix_length_and_dec occured
259
165
    return true;
260
166
  fixed= 1;
261
 
  session->session_marker= save_session_marker;
 
167
  thd->thd_marker= save_thd_marker;
262
168
  return false;
263
169
}
264
170
 
265
171
 
266
 
void Item_func::fix_after_pullout(Select_Lex *new_parent,
267
 
                                  Item **)
 
172
void Item_func::fix_after_pullout(st_select_lex *new_parent,
 
173
                                  Item **ref __attribute__((unused)))
268
174
{
269
175
  Item **arg,**arg_end;
270
176
 
271
177
  used_tables_cache= not_null_tables_cache= 0;
272
 
  const_item_cache= false;
 
178
  const_item_cache=1;
273
179
 
274
180
  if (arg_count)
275
181
  {
309
215
    Item **arg,**arg_end;
310
216
 
311
217
    switch (order) {
312
 
    case (T_PREFIX):
 
218
    case(PREFIX):
313
219
      (*traverser)(this, argument);
314
220
      for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
315
221
      {
316
222
        (*arg)->traverse_cond(traverser, argument, order);
317
223
      }
318
224
      break;
319
 
    case (T_POSTFIX):
 
225
    case (POSTFIX):
320
226
      for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
321
227
      {
322
228
        (*arg)->traverse_cond(traverser, argument, order);
358
264
        return 0;
359
265
 
360
266
      /*
361
 
        Session::change_item_tree() should be called only if the tree was
 
267
        THD::change_item_tree() should be called only if the tree was
362
268
        really transformed, i.e. when a new item has been created.
363
269
        Otherwise we'll be allocating a lot of unnecessary memory for
364
270
        change records at each execution.
365
271
      */
366
272
      if (*arg != new_item)
367
 
        getSession().change_item_tree(arg, new_item);
 
273
        current_thd->change_item_tree(arg, new_item);
368
274
    }
369
275
  }
370
276
  return (this->*transformer)(argument);
412
318
      unsigned char *arg_v= *arg_p;
413
319
      Item *new_item= (*arg)->compile(analyzer, &arg_v, transformer, arg_t);
414
320
      if (new_item && *arg != new_item)
415
 
        current_session->change_item_tree(arg, new_item);
 
321
        current_thd->change_item_tree(arg, new_item);
416
322
    }
417
323
  }
418
324
  return (this->*transformer)(arg_t);
422
328
   See comments in Item_cmp_func::split_sum_func()
423
329
*/
424
330
 
425
 
void Item_func::split_sum_func(Session *session, Item **ref_pointer_array,
 
331
void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
426
332
                               List<Item> &fields)
427
333
{
428
334
  Item **arg, **arg_end;
429
335
  for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++)
430
 
    (*arg)->split_sum_func(session, ref_pointer_array, fields, arg, true);
 
336
    (*arg)->split_sum_func2(thd, ref_pointer_array, fields, arg, true);
431
337
}
432
338
 
433
339
 
434
340
void Item_func::update_used_tables()
435
341
{
436
342
  used_tables_cache=0;
437
 
  const_item_cache= true;
 
343
  const_item_cache=1;
438
344
  for (uint32_t i=0 ; i < arg_count ; i++)
439
345
  {
440
346
    args[i]->update_used_tables();
514
420
}
515
421
 
516
422
 
517
 
bool Item_func::get_arg0_date(type::Time &ltime, uint32_t fuzzy_date)
 
423
bool Item_func::get_arg0_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date)
518
424
{
519
425
  return (null_value=args[0]->get_date(ltime, fuzzy_date));
520
426
}
521
427
 
522
428
 
523
 
bool Item_func::get_arg0_time(type::Time &ltime)
 
429
bool Item_func::get_arg0_time(DRIZZLE_TIME *ltime)
524
430
{
525
 
  return (null_value= args[0]->get_time(ltime));
 
431
  return (null_value=args[0]->get_time(ltime));
526
432
}
527
433
 
528
434
 
535
441
 
536
442
Field *Item_func::tmp_table_field(Table *table)
537
443
{
538
 
  Field *field= NULL;
 
444
  Field *field;
539
445
 
540
446
  switch (result_type()) {
541
447
  case INT_RESULT:
542
 
    if (unsigned_flag)
543
 
    {
544
 
      field= new field::Size(max_length, maybe_null, name, true);
545
 
    } 
546
 
    else if (max_length > MY_INT32_NUM_DECIMAL_DIGITS)
547
 
    {
548
 
      field= new field::Int64(max_length, maybe_null, name, false);
549
 
    }
 
448
    if (max_length > MY_INT32_NUM_DECIMAL_DIGITS)
 
449
      field= new Field_int64_t(max_length, maybe_null, name, unsigned_flag);
550
450
    else
551
 
    {
552
 
      field= new field::Int32(max_length, maybe_null, name, false);
553
 
    }
554
 
 
 
451
      field= new Field_long(max_length, maybe_null, name, unsigned_flag);
555
452
    break;
556
 
 
557
453
  case REAL_RESULT:
558
454
    field= new Field_double(max_length, maybe_null, name, decimals);
559
455
    break;
560
 
 
561
456
  case STRING_RESULT:
562
457
    return make_string_field(table);
563
 
 
 
458
    break;
564
459
  case DECIMAL_RESULT:
565
 
    field= new Field_decimal(class_decimal_precision_to_length(decimal_precision(),
566
 
                                                            decimals,
567
 
                                                            unsigned_flag),
568
 
                             maybe_null,
569
 
                             name,
570
 
                             decimals,
571
 
                             unsigned_flag);
 
460
    field= new Field_new_decimal(
 
461
                       my_decimal_precision_to_length(decimal_precision(),
 
462
                                                      decimals,
 
463
                                                      unsigned_flag),
 
464
                       maybe_null, name, decimals, unsigned_flag);
572
465
    break;
573
466
  case ROW_RESULT:
 
467
  default:
574
468
    // This case should never be chosen
575
469
    assert(0);
 
470
    field= 0;
576
471
    break;
577
472
  }
578
 
 
579
473
  if (field)
580
474
    field->init(table);
581
 
 
582
475
  return field;
583
476
}
584
477
 
585
478
 
586
 
type::Decimal *Item_func::val_decimal(type::Decimal *decimal_value)
 
479
my_decimal *Item_func::val_decimal(my_decimal *decimal_value)
587
480
{
588
481
  assert(fixed);
589
 
  int2_class_decimal(E_DEC_FATAL_ERROR, val_int(), unsigned_flag, decimal_value);
 
482
  int2my_decimal(E_DEC_FATAL_ERROR, val_int(), unsigned_flag, decimal_value);
590
483
  return decimal_value;
591
484
}
592
485
 
617
510
 
618
511
double Item_func::fix_result(double value)
619
512
{
620
 
  static double fix_infinity= numeric_limits<double>::infinity();
621
 
 
622
 
  if (value != fix_infinity && value != -fix_infinity)
 
513
  if (CMATH_NAMESPACE::isfinite(value))
623
514
    return value;
624
515
  null_value=1;
625
516
  return 0.0;
626
517
}
627
 
 
628
 
 
629
 
void Item_func::fix_num_length_and_dec()
630
 
{
631
 
  uint32_t fl_length= 0;
632
 
  decimals=0;
633
 
  for (uint32_t i=0 ; i < arg_count ; i++)
634
 
  {
635
 
    set_if_bigger(decimals,args[i]->decimals);
636
 
    set_if_bigger(fl_length, args[i]->max_length);
637
 
  }
638
 
  max_length=float_length(decimals);
639
 
  if (fl_length > max_length)
640
 
  {
641
 
    decimals= NOT_FIXED_DEC;
642
 
    max_length= float_length(NOT_FIXED_DEC);
643
 
  }
644
 
}
645
 
 
646
 
/**
647
 
  Set max_length/decimals of function if function is fixed point and
648
 
  result length/precision depends on argument ones.
649
 
*/
650
 
 
651
 
void Item_func::count_decimal_length()
652
 
{
653
 
  int max_int_part= 0;
654
 
  decimals= 0;
655
 
  unsigned_flag= 1;
656
 
  for (uint32_t i= 0 ; i < arg_count ; i++)
657
 
  {
658
 
    set_if_bigger(decimals, args[i]->decimals);
659
 
    set_if_bigger(max_int_part, args[i]->decimal_int_part());
660
 
    set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
661
 
  }
662
 
  int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
663
 
  max_length= class_decimal_precision_to_length(precision, decimals,
664
 
                                             unsigned_flag);
665
 
}
666
 
 
667
 
 
668
 
/**
669
 
  Set max_length of if it is maximum length of its arguments.
670
 
*/
671
 
 
672
 
void Item_func::count_only_length()
673
 
{
674
 
  max_length= 0;
675
 
  unsigned_flag= 0;
676
 
  for (uint32_t i=0 ; i < arg_count ; i++)
677
 
  {
678
 
    set_if_bigger(max_length, args[i]->max_length);
679
 
    set_if_bigger(unsigned_flag, args[i]->unsigned_flag);
680
 
  }
681
 
}
682
 
 
683
 
 
684
 
/**
685
 
  Set max_length/decimals of function if function is floating point and
686
 
  result length/precision depends on argument ones.
687
 
*/
688
 
 
689
 
void Item_func::count_real_length()
690
 
{
691
 
  uint32_t length= 0;
692
 
  decimals= 0;
693
 
  max_length= 0;
694
 
  for (uint32_t i=0 ; i < arg_count ; i++)
695
 
  {
696
 
    if (decimals != NOT_FIXED_DEC)
697
 
    {
698
 
      set_if_bigger(decimals, args[i]->decimals);
699
 
      set_if_bigger(length, (args[i]->max_length - args[i]->decimals));
700
 
    }
701
 
    set_if_bigger(max_length, args[i]->max_length);
702
 
  }
703
 
  if (decimals != NOT_FIXED_DEC)
704
 
  {
705
 
    max_length= length;
706
 
    length+= decimals;
707
 
    if (length < max_length)  // If previous operation gave overflow
708
 
      max_length= UINT32_MAX;
709
 
    else
710
 
      max_length= length;
711
 
  }
712
 
}
713
 
 
714
 
 
715
 
 
716
 
void Item_func::signal_divide_by_null()
717
 
{
718
 
  my_error(ER_DIVISION_BY_ZERO, MYF(0));
719
 
  null_value= 0;
720
 
}
721
 
 
722
 
 
723
 
Item *Item_func::get_tmp_table_item(Session *session)
724
 
{
725
 
  if (!with_sum_func && !const_item() && functype() != SUSERVAR_FUNC)
726
 
    return new Item_field(result_field);
727
 
  return copy_or_same(session);
728
 
}
729
 
 
730
 
 
731
 
} /* namespace drizzled */