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