~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/functions/func.cc

  • Committer: Monty Taylor
  • Date: 2008-10-14 16:33:44 UTC
  • mfrom: (512 drizzle)
  • mto: (511.1.5 codestyle)
  • mto: This revision was merged to the branch mainline in revision 515.
  • Revision ID: monty@inaugust.com-20081014163344-9xprk712n9hmbrzr
MergedĀ fromĀ trunk.

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
 
#include "config.h"
 
20
#include <drizzled/server_includes.h>
 
21
 
 
22
#include CSTDINT_H
 
23
#include <cassert>
 
24
 
 
25
#include <drizzled/version.h>
21
26
 
22
27
#include <drizzled/sql_string.h>
23
28
#include <drizzled/sql_list.h>
24
29
 
25
 
#include <drizzled/function/math/int.h>
26
 
#include <drizzled/field/int32.h>
27
 
#include <drizzled/field/int64.h>
28
 
#include <drizzled/field/double.h>
29
 
#include <drizzled/field/decimal.h>
30
 
#include <drizzled/session.h>
31
 
#include <drizzled/error.h>
32
 
#include <drizzled/check_stack_overrun.h>
33
 
#include <limits>
34
 
#include <algorithm>
35
 
 
36
 
using namespace std;
37
 
 
38
 
namespace drizzled
39
 
{
 
30
#include <drizzled/functions/int.h>
40
31
 
41
32
 
42
33
void Item_func::set_arguments(List<Item> &list)
44
35
  allowed_arg_cols= 1;
45
36
  arg_count=list.elements;
46
37
  args= tmp_arg;                                // If 2 arguments
47
 
  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)))
48
39
  {
49
40
    List_iterator_fast<Item> li(list);
50
41
    Item *item;
59
50
  list.empty();          // Fields are used
60
51
}
61
52
 
62
 
Item_func::Item_func(List<Item> &list) :
63
 
  _session(*current_session),
64
 
  allowed_arg_cols(1)
 
53
Item_func::Item_func(List<Item> &list)
 
54
  :allowed_arg_cols(1)
65
55
{
66
 
  collation.set(DERIVATION_SYSCONST);
67
56
  set_arguments(list);
68
57
}
69
58
 
70
 
Item_func::Item_func(Session *session, Item_func *item) :
71
 
  Item_result_field(session, item),
72
 
  _session(*current_session),
73
 
  allowed_arg_cols(item->allowed_arg_cols),
74
 
  arg_count(item->arg_count),
75
 
  used_tables_cache(item->used_tables_cache),
76
 
  not_null_tables_cache(item->not_null_tables_cache),
77
 
  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)
78
66
{
79
67
  if (arg_count)
80
68
  {
82
70
      args= tmp_arg;
83
71
    else
84
72
    {
85
 
      if (!(args=(Item**) session->alloc(sizeof(Item*)*arg_count)))
 
73
      if (!(args=(Item**) thd->alloc(sizeof(Item*)*arg_count)))
86
74
        return;
87
75
    }
88
76
    memcpy(args, item->args, sizeof(Item*)*arg_count);
89
77
  }
90
 
  collation.set(DERIVATION_SYSCONST);
91
78
}
92
79
 
93
80
 
96
83
 
97
84
  SYNOPSIS:
98
85
  fix_fields()
99
 
  session    Thread object
 
86
  thd    Thread object
100
87
  ref    Pointer to where this object is used.  This reference
101
88
  is used if we want to replace this object with another
102
89
  one (for example in the summary functions).
125
112
*/
126
113
 
127
114
bool
128
 
Item_func::fix_fields(Session *session, Item **)
 
115
Item_func::fix_fields(THD *thd, Item **ref __attribute__((unused)))
129
116
{
130
117
  assert(fixed == 0);
131
118
  Item **arg,**arg_end;
132
 
  void *save_session_marker= session->session_marker;
 
119
  void *save_thd_marker= thd->thd_marker;
133
120
  unsigned char buff[STACK_BUFF_ALLOC];      // Max argument in function
134
 
  session->session_marker= 0;
 
121
  thd->thd_marker= 0;
135
122
  used_tables_cache= not_null_tables_cache= 0;
136
123
  const_item_cache=1;
137
124
 
138
 
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
 
125
  if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
139
126
    return true;        // Fatal error if flag is set!
140
127
  if (arg_count)
141
128
  {            // Print purify happy
146
133
        We can't yet set item to *arg as fix_fields may change *arg
147
134
        We shouldn't call fix_fields() twice, so check 'fixed' field first
148
135
      */
149
 
      if ((!(*arg)->fixed && (*arg)->fix_fields(session, arg)))
150
 
        return true;
 
136
      if ((!(*arg)->fixed && (*arg)->fix_fields(thd, arg)))
 
137
        return true;        /* purecov: inspected */
151
138
      item= *arg;
152
139
 
153
140
      if (allowed_arg_cols)
174
161
    }
175
162
  }
176
163
  fix_length_and_dec();
177
 
  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
178
165
    return true;
179
166
  fixed= 1;
180
 
  session->session_marker= save_session_marker;
 
167
  thd->thd_marker= save_thd_marker;
181
168
  return false;
182
169
}
183
170
 
184
171
 
185
 
void Item_func::fix_after_pullout(Select_Lex *new_parent,
186
 
                                  Item **)
 
172
void Item_func::fix_after_pullout(st_select_lex *new_parent,
 
173
                                  Item **ref __attribute__((unused)))
187
174
{
188
175
  Item **arg,**arg_end;
189
176
 
228
215
    Item **arg,**arg_end;
229
216
 
230
217
    switch (order) {
231
 
    case (T_PREFIX):
 
218
    case(PREFIX):
232
219
      (*traverser)(this, argument);
233
220
      for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
234
221
      {
235
222
        (*arg)->traverse_cond(traverser, argument, order);
236
223
      }
237
224
      break;
238
 
    case (T_POSTFIX):
 
225
    case (POSTFIX):
239
226
      for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
240
227
      {
241
228
        (*arg)->traverse_cond(traverser, argument, order);
277
264
        return 0;
278
265
 
279
266
      /*
280
 
        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
281
268
        really transformed, i.e. when a new item has been created.
282
269
        Otherwise we'll be allocating a lot of unnecessary memory for
283
270
        change records at each execution.
284
271
      */
285
272
      if (*arg != new_item)
286
 
        getSession().change_item_tree(arg, new_item);
 
273
        current_thd->change_item_tree(arg, new_item);
287
274
    }
288
275
  }
289
276
  return (this->*transformer)(argument);
331
318
      unsigned char *arg_v= *arg_p;
332
319
      Item *new_item= (*arg)->compile(analyzer, &arg_v, transformer, arg_t);
333
320
      if (new_item && *arg != new_item)
334
 
        current_session->change_item_tree(arg, new_item);
 
321
        current_thd->change_item_tree(arg, new_item);
335
322
    }
336
323
  }
337
324
  return (this->*transformer)(arg_t);
341
328
   See comments in Item_cmp_func::split_sum_func()
342
329
*/
343
330
 
344
 
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,
345
332
                               List<Item> &fields)
346
333
{
347
334
  Item **arg, **arg_end;
348
335
  for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++)
349
 
    (*arg)->split_sum_func(session, ref_pointer_array, fields, arg, true);
 
336
    (*arg)->split_sum_func2(thd, ref_pointer_array, fields, arg, true);
350
337
}
351
338
 
352
339
 
454
441
 
455
442
Field *Item_func::tmp_table_field(Table *table)
456
443
{
457
 
  Field *field= NULL;
 
444
  Field *field;
458
445
 
459
446
  switch (result_type()) {
460
447
  case INT_RESULT:
461
448
    if (max_length > MY_INT32_NUM_DECIMAL_DIGITS)
462
 
      field= new field::Int64(max_length, maybe_null, name, unsigned_flag);
 
449
      field= new Field_int64_t(max_length, maybe_null, name, unsigned_flag);
463
450
    else
464
 
      field= new field::Int32(max_length, maybe_null, name, unsigned_flag);
 
451
      field= new Field_long(max_length, maybe_null, name, unsigned_flag);
465
452
    break;
466
 
 
467
453
  case REAL_RESULT:
468
454
    field= new Field_double(max_length, maybe_null, name, decimals);
469
455
    break;
470
 
 
471
456
  case STRING_RESULT:
472
457
    return make_string_field(table);
473
 
 
 
458
    break;
474
459
  case DECIMAL_RESULT:
475
 
    field= new Field_decimal(my_decimal_precision_to_length(decimal_precision(),
476
 
                                                            decimals,
477
 
                                                            unsigned_flag),
478
 
                             maybe_null,
479
 
                             name,
480
 
                             decimals,
481
 
                             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);
482
465
    break;
483
466
  case ROW_RESULT:
 
467
  default:
484
468
    // This case should never be chosen
485
469
    assert(0);
 
470
    field= 0;
486
471
    break;
487
472
  }
488
 
 
489
473
  if (field)
490
474
    field->init(table);
491
 
 
492
475
  return field;
493
476
}
494
477
 
527
510
 
528
511
double Item_func::fix_result(double value)
529
512
{
530
 
  static double fix_infinity= numeric_limits<double>::infinity();
531
 
 
532
 
  if (value != fix_infinity && value != -fix_infinity)
 
513
  if (CMATH_NAMESPACE::isfinite(value))
533
514
    return value;
534
515
  null_value=1;
535
516
  return 0.0;
536
517
}
537
 
 
538
 
 
539
 
void Item_func::fix_num_length_and_dec()
540
 
{
541
 
  uint32_t fl_length= 0;
542
 
  decimals=0;
543
 
  for (uint32_t i=0 ; i < arg_count ; i++)
544
 
  {
545
 
    set_if_bigger(decimals,args[i]->decimals);
546
 
    set_if_bigger(fl_length, args[i]->max_length);
547
 
  }
548
 
  max_length=float_length(decimals);
549
 
  if (fl_length > max_length)
550
 
  {
551
 
    decimals= NOT_FIXED_DEC;
552
 
    max_length= float_length(NOT_FIXED_DEC);
553
 
  }
554
 
}
555
 
 
556
 
/**
557
 
  Set max_length/decimals of function if function is fixed point and
558
 
  result length/precision depends on argument ones.
559
 
*/
560
 
 
561
 
void Item_func::count_decimal_length()
562
 
{
563
 
  int max_int_part= 0;
564
 
  decimals= 0;
565
 
  unsigned_flag= 1;
566
 
  for (uint32_t i= 0 ; i < arg_count ; i++)
567
 
  {
568
 
    set_if_bigger(decimals, args[i]->decimals);
569
 
    set_if_bigger(max_int_part, args[i]->decimal_int_part());
570
 
    set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
571
 
  }
572
 
  int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
573
 
  max_length= my_decimal_precision_to_length(precision, decimals,
574
 
                                             unsigned_flag);
575
 
}
576
 
 
577
 
 
578
 
/**
579
 
  Set max_length of if it is maximum length of its arguments.
580
 
*/
581
 
 
582
 
void Item_func::count_only_length()
583
 
{
584
 
  max_length= 0;
585
 
  unsigned_flag= 0;
586
 
  for (uint32_t i=0 ; i < arg_count ; i++)
587
 
  {
588
 
    set_if_bigger(max_length, args[i]->max_length);
589
 
    set_if_bigger(unsigned_flag, args[i]->unsigned_flag);
590
 
  }
591
 
}
592
 
 
593
 
 
594
 
/**
595
 
  Set max_length/decimals of function if function is floating point and
596
 
  result length/precision depends on argument ones.
597
 
*/
598
 
 
599
 
void Item_func::count_real_length()
600
 
{
601
 
  uint32_t length= 0;
602
 
  decimals= 0;
603
 
  max_length= 0;
604
 
  for (uint32_t i=0 ; i < arg_count ; i++)
605
 
  {
606
 
    if (decimals != NOT_FIXED_DEC)
607
 
    {
608
 
      set_if_bigger(decimals, args[i]->decimals);
609
 
      set_if_bigger(length, (args[i]->max_length - args[i]->decimals));
610
 
    }
611
 
    set_if_bigger(max_length, args[i]->max_length);
612
 
  }
613
 
  if (decimals != NOT_FIXED_DEC)
614
 
  {
615
 
    max_length= length;
616
 
    length+= decimals;
617
 
    if (length < max_length)  // If previous operation gave overflow
618
 
      max_length= UINT32_MAX;
619
 
    else
620
 
      max_length= length;
621
 
  }
622
 
}
623
 
 
624
 
 
625
 
 
626
 
void Item_func::signal_divide_by_null()
627
 
{
628
 
  my_error(ER_DIVISION_BY_ZERO, MYF(0));
629
 
  null_value= 0;
630
 
}
631
 
 
632
 
 
633
 
Item *Item_func::get_tmp_table_item(Session *session)
634
 
{
635
 
  if (!with_sum_func && !const_item() && functype() != SUSERVAR_FUNC)
636
 
    return new Item_field(result_field);
637
 
  return copy_or_same(session);
638
 
}
639
 
 
640
 
 
641
 
} /* namespace drizzled */