~drizzle-trunk/drizzle/development

489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
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
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
20
#include "config.h"
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
21
22
#include <drizzled/sql_string.h>
23
#include <drizzled/sql_list.h>
24
642.1.30 by Lee
move math functions to drizzled/function/math directory
25
#include <drizzled/function/math/int.h>
584.5.1 by Monty Taylor
Removed field includes from field.h.
26
#include <drizzled/field/int64_t.h>
27
#include <drizzled/field/long.h>
28
#include <drizzled/field/double.h>
670.1.1 by Monty Taylor
Renamed fdecimal.* to decimal.*. Let's see how many things we can break!
29
#include <drizzled/field/decimal.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
30
#include <drizzled/session.h>
629.6.7 by Lee
final clean up of item/func functions moving them to the functions directory
31
#include <drizzled/error.h>
670.2.4 by Monty Taylor
Removed more stuff from the headers.
32
#include <drizzled/check_stack_overrun.h>
919.2.11 by Monty Taylor
Removed C99 isnan() usage, which allows us to remove the util/math.{cc,h} workarounds. Yay for standards!
33
#include <limits>
1067.4.2 by Nathan Williams
All files in drizzled/function/ now use std::min instead of cmin.
34
#include <algorithm>
919.2.11 by Monty Taylor
Removed C99 isnan() usage, which allows us to remove the util/math.{cc,h} workarounds. Yay for standards!
35
36
using namespace std;
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
37
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
38
namespace drizzled
39
{
40
41
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
42
void Item_func::set_arguments(List<Item> &list)
43
{
44
  allowed_arg_cols= 1;
45
  arg_count=list.elements;
46
  args= tmp_arg;                                // If 2 arguments
1253.1.6 by Monty Taylor
Moved mem_root functions into drizzled::memory:: namespace.
47
  if (arg_count <= 2 || (args=(Item**) memory::sql_alloc(sizeof(Item*)*arg_count)))
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
48
  {
49
    List_iterator_fast<Item> li(list);
50
    Item *item;
51
    Item **save_args= args;
52
53
    while ((item=li++))
54
    {
55
      *(save_args++)= item;
56
      with_sum_func|=item->with_sum_func;
57
    }
58
  }
59
  list.empty();          // Fields are used
60
}
61
1633.4.7 by Brian Aker
Put a copy of the Session in the root of function to make use of.
62
Item_func::Item_func(List<Item> &list) :
63
  _session(*current_session),
64
  allowed_arg_cols(1)
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
65
{
1717.1.2 by LinuxJedi
Set string functions to use DERIVATION_SYSCONST.
66
  collation.set(DERIVATION_SYSCONST);
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
67
  set_arguments(list);
68
}
69
1633.4.7 by Brian Aker
Put a copy of the Session in the root of function to make use of.
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)
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
78
{
79
  if (arg_count)
80
  {
81
    if (arg_count <=2)
82
      args= tmp_arg;
83
    else
84
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
85
      if (!(args=(Item**) session->alloc(sizeof(Item*)*arg_count)))
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
86
        return;
87
    }
88
    memcpy(args, item->args, sizeof(Item*)*arg_count);
89
  }
1717.1.2 by LinuxJedi
Set string functions to use DERIVATION_SYSCONST.
90
  collation.set(DERIVATION_SYSCONST);
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
91
}
92
93
94
/*
95
  Resolve references to table column for a function and its argument
96
97
  SYNOPSIS:
98
  fix_fields()
520.1.22 by Brian Aker
Second pass of thd cleanup
99
  session    Thread object
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
100
  ref    Pointer to where this object is used.  This reference
101
  is used if we want to replace this object with another
102
  one (for example in the summary functions).
103
104
  DESCRIPTION
105
  Call fix_fields() for all arguments to the function.  The main intention
106
  is to allow all Item_field() objects to setup pointers to the table fields.
107
108
  Sets as a side effect the following class variables:
109
  maybe_null  Set if any argument may return NULL
110
  with_sum_func  Set if any of the arguments contains a sum function
111
  used_tables_cache Set to union of the tables used by arguments
112
113
  str_value.charset If this is a string function, set this to the
114
  character set for the first argument.
115
  If any argument is binary, this is set to binary
116
117
  If for any item any of the defaults are wrong, then this can
118
  be fixed in the fix_length_and_dec() function that is called
119
  after this one or by writing a specialized fix_fields() for the
120
  item.
121
122
  RETURN VALUES
123
  false  ok
124
  true  Got error.  Stored with my_error().
125
*/
126
127
bool
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
128
Item_func::fix_fields(Session *session, Item **)
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
129
{
130
  assert(fixed == 0);
131
  Item **arg,**arg_end;
520.1.22 by Brian Aker
Second pass of thd cleanup
132
  void *save_session_marker= session->session_marker;
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
133
  unsigned char buff[STACK_BUFF_ALLOC];      // Max argument in function
520.1.22 by Brian Aker
Second pass of thd cleanup
134
  session->session_marker= 0;
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
135
  used_tables_cache= not_null_tables_cache= 0;
136
  const_item_cache=1;
137
520.1.22 by Brian Aker
Second pass of thd cleanup
138
  if (check_stack_overrun(session, STACK_MIN_SIZE, buff))
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
139
    return true;        // Fatal error if flag is set!
140
  if (arg_count)
141
  {            // Print purify happy
142
    for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
143
    {
144
      Item *item;
145
      /*
146
        We can't yet set item to *arg as fix_fields may change *arg
147
        We shouldn't call fix_fields() twice, so check 'fixed' field first
148
      */
520.1.22 by Brian Aker
Second pass of thd cleanup
149
      if ((!(*arg)->fixed && (*arg)->fix_fields(session, arg)))
971.6.11 by Eric Day
Removed purecov messages.
150
        return true;
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
151
      item= *arg;
152
153
      if (allowed_arg_cols)
154
      {
155
        if (item->check_cols(allowed_arg_cols))
156
          return 1;
157
      }
158
      else
159
      {
160
        /*  we have to fetch allowed_arg_cols from first argument */
161
        assert(arg == args); // it is first argument
162
        allowed_arg_cols= item->cols();
163
        assert(allowed_arg_cols); // Can't be 0 any more
164
      }
165
166
      if (item->maybe_null)
167
        maybe_null=1;
168
169
      with_sum_func= with_sum_func || item->with_sum_func;
170
      used_tables_cache|=     item->used_tables();
171
      not_null_tables_cache|= item->not_null_tables();
172
      const_item_cache&=      item->const_item();
173
      with_subselect|=        item->with_subselect;
174
    }
175
  }
176
  fix_length_and_dec();
520.1.22 by Brian Aker
Second pass of thd cleanup
177
  if (session->is_error()) // An error inside fix_length_and_dec occured
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
178
    return true;
179
  fixed= 1;
520.1.22 by Brian Aker
Second pass of thd cleanup
180
  session->session_marker= save_session_marker;
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
181
  return false;
182
}
183
184
846 by Brian Aker
Removing on typedeffed class.
185
void Item_func::fix_after_pullout(Select_Lex *new_parent,
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
186
                                  Item **)
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
187
{
188
  Item **arg,**arg_end;
189
190
  used_tables_cache= not_null_tables_cache= 0;
191
  const_item_cache=1;
192
193
  if (arg_count)
194
  {
195
    for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
196
    {
197
      (*arg)->fix_after_pullout(new_parent, arg);
198
      Item *item= *arg;
199
200
      used_tables_cache|=     item->used_tables();
201
      not_null_tables_cache|= item->not_null_tables();
202
      const_item_cache&=      item->const_item();
203
    }
204
  }
205
}
206
207
208
bool Item_func::walk(Item_processor processor, bool walk_subquery,
209
                     unsigned char *argument)
210
{
211
  if (arg_count)
212
  {
213
    Item **arg,**arg_end;
214
    for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
215
    {
216
      if ((*arg)->walk(processor, walk_subquery, argument))
217
        return 1;
218
    }
219
  }
220
  return (this->*processor)(argument);
221
}
222
223
void Item_func::traverse_cond(Cond_traverser traverser,
224
                              void *argument, traverse_order order)
225
{
226
  if (arg_count)
227
  {
228
    Item **arg,**arg_end;
229
230
    switch (order) {
798.2.28 by Brian Aker
More pulling of code... master_pos function code removed.
231
    case (T_PREFIX):
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
232
      (*traverser)(this, argument);
233
      for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
234
      {
235
        (*arg)->traverse_cond(traverser, argument, order);
236
      }
237
      break;
798.2.28 by Brian Aker
More pulling of code... master_pos function code removed.
238
    case (T_POSTFIX):
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
239
      for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
240
      {
241
        (*arg)->traverse_cond(traverser, argument, order);
242
      }
243
      (*traverser)(this, argument);
244
    }
245
  }
246
  else
247
    (*traverser)(this, argument);
248
}
249
250
251
/**
252
   Transform an Item_func object with a transformer callback function.
253
254
   The function recursively applies the transform method to each
255
   argument of the Item_func node.
256
   If the call of the method for an argument item returns a new item
257
   the old item is substituted for a new one.
258
   After this the transformer is applied to the root node
259
   of the Item_func object.
260
   @param transformer   the transformer callback function to be applied to
261
   the nodes of the tree of the object
262
   @param argument      parameter to be passed to the transformer
263
264
   @return
265
   Item returned as the result of transformation of the root node
266
*/
267
268
Item *Item_func::transform(Item_transformer transformer, unsigned char *argument)
269
{
270
  if (arg_count)
271
  {
272
    Item **arg,**arg_end;
273
    for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
274
    {
275
      Item *new_item= (*arg)->transform(transformer, argument);
276
      if (!new_item)
277
        return 0;
278
279
      /*
520.1.21 by Brian Aker
THD -> Session rename
280
        Session::change_item_tree() should be called only if the tree was
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
281
        really transformed, i.e. when a new item has been created.
282
        Otherwise we'll be allocating a lot of unnecessary memory for
283
        change records at each execution.
284
      */
285
      if (*arg != new_item)
1633.4.7 by Brian Aker
Put a copy of the Session in the root of function to make use of.
286
        getSession().change_item_tree(arg, new_item);
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
287
    }
288
  }
289
  return (this->*transformer)(argument);
290
}
291
292
293
/**
294
   Compile Item_func object with a processor and a transformer
295
   callback functions.
296
297
   First the function applies the analyzer to the root node of
298
   the Item_func object. Then if the analizer succeeeds (returns true)
299
   the function recursively applies the compile method to each argument
300
   of the Item_func node.
301
   If the call of the method for an argument item returns a new item
302
   the old item is substituted for a new one.
303
   After this the transformer is applied to the root node
304
   of the Item_func object.
305
306
   @param analyzer      the analyzer callback function to be applied to the
307
   nodes of the tree of the object
308
   @param[in,out] arg_p parameter to be passed to the processor
309
   @param transformer   the transformer callback function to be applied to the
310
   nodes of the tree of the object
311
   @param arg_t         parameter to be passed to the transformer
312
313
   @return
314
   Item returned as the result of transformation of the root node
315
*/
316
317
Item *Item_func::compile(Item_analyzer analyzer, unsigned char **arg_p,
318
                         Item_transformer transformer, unsigned char *arg_t)
319
{
320
  if (!(this->*analyzer)(arg_p))
321
    return 0;
322
  if (arg_count)
323
  {
324
    Item **arg,**arg_end;
325
    for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
326
    {
327
      /*
328
        The same parameter value of arg_p must be passed
329
        to analyze any argument of the condition formula.
330
      */
331
      unsigned char *arg_v= *arg_p;
332
      Item *new_item= (*arg)->compile(analyzer, &arg_v, transformer, arg_t);
333
      if (new_item && *arg != new_item)
520.1.22 by Brian Aker
Second pass of thd cleanup
334
        current_session->change_item_tree(arg, new_item);
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
335
    }
336
  }
337
  return (this->*transformer)(arg_t);
338
}
339
340
/**
341
   See comments in Item_cmp_func::split_sum_func()
342
*/
343
520.1.22 by Brian Aker
Second pass of thd cleanup
344
void Item_func::split_sum_func(Session *session, Item **ref_pointer_array,
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
345
                               List<Item> &fields)
346
{
347
  Item **arg, **arg_end;
348
  for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++)
584.4.9 by Monty Taylor
Renamed split_sum_func2 to split_sum_func. It's C++.
349
    (*arg)->split_sum_func(session, ref_pointer_array, fields, arg, true);
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
350
}
351
352
353
void Item_func::update_used_tables()
354
{
355
  used_tables_cache=0;
356
  const_item_cache=1;
357
  for (uint32_t i=0 ; i < arg_count ; i++)
358
  {
359
    args[i]->update_used_tables();
360
    used_tables_cache|=args[i]->used_tables();
361
    const_item_cache&=args[i]->const_item();
362
  }
363
}
364
365
366
table_map Item_func::used_tables() const
367
{
368
  return used_tables_cache;
369
}
370
371
372
table_map Item_func::not_null_tables() const
373
{
374
  return not_null_tables_cache;
375
}
376
377
378
void Item_func::print(String *str, enum_query_type query_type)
379
{
380
  str->append(func_name());
381
  str->append('(');
382
  print_args(str, 0, query_type);
383
  str->append(')');
384
}
385
386
387
void Item_func::print_args(String *str, uint32_t from, enum_query_type query_type)
388
{
389
  for (uint32_t i=from ; i < arg_count ; i++)
390
  {
391
    if (i != from)
392
      str->append(',');
393
    args[i]->print(str, query_type);
394
  }
395
}
396
397
398
void Item_func::print_op(String *str, enum_query_type query_type)
399
{
400
  str->append('(');
401
  for (uint32_t i=0 ; i < arg_count-1 ; i++)
402
  {
403
    args[i]->print(str, query_type);
404
    str->append(' ');
405
    str->append(func_name());
406
    str->append(' ');
407
  }
408
  args[arg_count-1]->print(str, query_type);
409
  str->append(')');
410
}
411
412
413
bool Item_func::eq(const Item *item, bool binary_cmp) const
414
{
415
  /* Assume we don't have rtti */
416
  if (this == item)
417
    return 1;
418
  if (item->type() != FUNC_ITEM)
419
    return 0;
420
  Item_func *item_func=(Item_func*) item;
421
  Item_func::Functype func_type;
422
  if ((func_type= functype()) != item_func->functype() ||
423
      arg_count != item_func->arg_count ||
424
      (func_type != Item_func::FUNC_SP &&
425
       func_name() != item_func->func_name()) ||
426
      (func_type == Item_func::FUNC_SP &&
427
       my_strcasecmp(system_charset_info, func_name(), item_func->func_name())))
428
    return 0;
429
  for (uint32_t i=0; i < arg_count ; i++)
430
    if (!args[i]->eq(item_func->args[i], binary_cmp))
431
      return 0;
432
  return 1;
433
}
434
435
436
bool Item_func::get_arg0_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date)
437
{
438
  return (null_value=args[0]->get_date(ltime, fuzzy_date));
439
}
440
441
442
bool Item_func::get_arg0_time(DRIZZLE_TIME *ltime)
443
{
444
  return (null_value=args[0]->get_time(ltime));
445
}
446
447
448
bool Item_func::is_null()
449
{
450
  update_null_value();
451
  return null_value;
452
}
453
454
455
Field *Item_func::tmp_table_field(Table *table)
456
{
457
  Field *field;
458
459
  switch (result_type()) {
460
  case INT_RESULT:
461
    if (max_length > MY_INT32_NUM_DECIMAL_DIGITS)
462
      field= new Field_int64_t(max_length, maybe_null, name, unsigned_flag);
463
    else
464
      field= new Field_long(max_length, maybe_null, name, unsigned_flag);
465
    break;
466
  case REAL_RESULT:
467
    field= new Field_double(max_length, maybe_null, name, decimals);
468
    break;
469
  case STRING_RESULT:
470
    return make_string_field(table);
471
  case DECIMAL_RESULT:
1211.1.1 by Brian Aker
Updating with my change to to DECIMAL from NEWDECIMAL and Stewart's update
472
    field= new Field_decimal(my_decimal_precision_to_length(decimal_precision(),
473
                                                            decimals,
474
                                                            unsigned_flag),
475
                             maybe_null,
476
                             name,
477
                             decimals,
478
                             unsigned_flag);
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
479
    break;
480
  case ROW_RESULT:
481
  default:
482
    // This case should never be chosen
483
    assert(0);
484
    field= 0;
485
    break;
486
  }
487
  if (field)
488
    field->init(table);
489
  return field;
490
}
491
492
493
my_decimal *Item_func::val_decimal(my_decimal *decimal_value)
494
{
495
  assert(fixed);
496
  int2my_decimal(E_DEC_FATAL_ERROR, val_int(), unsigned_flag, decimal_value);
497
  return decimal_value;
498
}
499
500
501
bool Item_func::agg_arg_collations(DTCollation &c, Item **items,
502
                                   uint32_t nitems, uint32_t flags)
503
{
504
  return agg_item_collations(c, func_name(), items, nitems, flags, 1);
505
}
506
507
508
bool Item_func::agg_arg_collations_for_comparison(DTCollation &c,
509
                                                  Item **items,
510
                                                  uint32_t nitems,
511
                                                  uint32_t flags)
512
{
513
  return agg_item_collations_for_comparison(c, func_name(),
514
                                            items, nitems, flags);
515
}
516
517
518
bool Item_func::agg_arg_charsets(DTCollation &c, Item **items, uint32_t nitems,
519
                                 uint32_t flags, int item_sep)
520
{
521
  return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep);
522
}
523
524
525
double Item_func::fix_result(double value)
526
{
919.2.10 by Monty Taylor
Remove C99 isfinite().
527
  static double fix_infinity= numeric_limits<double>::infinity();
528
529
  if (value != fix_infinity && value != -fix_infinity)
489.1.8 by Monty Taylor
Split out Item_int_func and Item_func from Item_func. (don't think too hard about the second one)
530
    return value;
531
  null_value=1;
532
  return 0.0;
533
}
629.6.7 by Lee
final clean up of item/func functions moving them to the functions directory
534
535
536
void Item_func::fix_num_length_and_dec()
537
{
538
  uint32_t fl_length= 0;
539
  decimals=0;
540
  for (uint32_t i=0 ; i < arg_count ; i++)
541
  {
542
    set_if_bigger(decimals,args[i]->decimals);
543
    set_if_bigger(fl_length, args[i]->max_length);
544
  }
545
  max_length=float_length(decimals);
546
  if (fl_length > max_length)
547
  {
548
    decimals= NOT_FIXED_DEC;
549
    max_length= float_length(NOT_FIXED_DEC);
550
  }
551
}
552
553
/**
554
  Set max_length/decimals of function if function is fixed point and
555
  result length/precision depends on argument ones.
556
*/
557
558
void Item_func::count_decimal_length()
559
{
560
  int max_int_part= 0;
561
  decimals= 0;
562
  unsigned_flag= 1;
1067.4.2 by Nathan Williams
All files in drizzled/function/ now use std::min instead of cmin.
563
  for (uint32_t i= 0 ; i < arg_count ; i++)
629.6.7 by Lee
final clean up of item/func functions moving them to the functions directory
564
  {
565
    set_if_bigger(decimals, args[i]->decimals);
566
    set_if_bigger(max_int_part, args[i]->decimal_int_part());
567
    set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
568
  }
1067.4.2 by Nathan Williams
All files in drizzled/function/ now use std::min instead of cmin.
569
  int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
629.6.7 by Lee
final clean up of item/func functions moving them to the functions directory
570
  max_length= my_decimal_precision_to_length(precision, decimals,
571
                                             unsigned_flag);
572
}
573
574
575
/**
576
  Set max_length of if it is maximum length of its arguments.
577
*/
578
579
void Item_func::count_only_length()
580
{
581
  max_length= 0;
582
  unsigned_flag= 0;
583
  for (uint32_t i=0 ; i < arg_count ; i++)
584
  {
585
    set_if_bigger(max_length, args[i]->max_length);
586
    set_if_bigger(unsigned_flag, args[i]->unsigned_flag);
587
  }
588
}
589
590
591
/**
592
  Set max_length/decimals of function if function is floating point and
593
  result length/precision depends on argument ones.
594
*/
595
596
void Item_func::count_real_length()
597
{
598
  uint32_t length= 0;
599
  decimals= 0;
600
  max_length= 0;
601
  for (uint32_t i=0 ; i < arg_count ; i++)
602
  {
603
    if (decimals != NOT_FIXED_DEC)
604
    {
605
      set_if_bigger(decimals, args[i]->decimals);
606
      set_if_bigger(length, (args[i]->max_length - args[i]->decimals));
607
    }
608
    set_if_bigger(max_length, args[i]->max_length);
609
  }
610
  if (decimals != NOT_FIXED_DEC)
611
  {
612
    max_length= length;
613
    length+= decimals;
614
    if (length < max_length)  // If previous operation gave overflow
615
      max_length= UINT32_MAX;
616
    else
617
      max_length= length;
618
  }
619
}
620
621
622
623
void Item_func::signal_divide_by_null()
624
{
1812.4.2 by Brian Aker
Fix issue with divide by zero not being an error.
625
  my_error(ER_DIVISION_BY_ZERO, MYF(0));
626
  null_value= 0;
629.6.7 by Lee
final clean up of item/func functions moving them to the functions directory
627
}
628
629
630
Item *Item_func::get_tmp_table_item(Session *session)
631
{
632
  if (!with_sum_func && !const_item() && functype() != SUSERVAR_FUNC)
633
    return new Item_field(result_field);
634
  return copy_or_same(session);
635
}
636
637
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
638
} /* namespace drizzled */