~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
492.3.26 by Lee
Changes to get drizzle building on Solaris 10 (SPARC)
20
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)
21
#include <drizzled/server_includes.h>
22
23
#include CSTDINT_H
24
#include <cassert>
25
26
#include <drizzled/sql_string.h>
27
#include <drizzled/sql_list.h>
28
642.1.30 by Lee
move math functions to drizzled/function/math directory
29
#include <drizzled/function/math/int.h>
584.5.1 by Monty Taylor
Removed field includes from field.h.
30
#include <drizzled/field/int64_t.h>
31
#include <drizzled/field/long.h>
32
#include <drizzled/field/double.h>
670.1.1 by Monty Taylor
Renamed fdecimal.* to decimal.*. Let's see how many things we can break!
33
#include <drizzled/field/decimal.h>
572.1.4 by Monty Taylor
Removed a bunch of unusued tests and defines from autoconf.
34
#include CMATH_H
520.9.3 by mordred
zomg. Solaris actually builds all the way!!!
35
#include <drizzled/util/math.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.
36
#include <drizzled/session.h>
629.6.7 by Lee
final clean up of item/func functions moving them to the functions directory
37
#include <drizzled/error.h>
670.2.4 by Monty Taylor
Removed more stuff from the headers.
38
#include <drizzled/check_stack_overrun.h>
572.1.4 by Monty Taylor
Removed a bunch of unusued tests and defines from autoconf.
39
40
#if defined(CMATH_NAMESPACE)
41
using namespace CMATH_NAMESPACE;
42
#endif
43
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)
44
45
46
void Item_func::set_arguments(List<Item> &list)
47
{
48
  allowed_arg_cols= 1;
49
  arg_count=list.elements;
50
  args= tmp_arg;                                // If 2 arguments
51
  if (arg_count <= 2 || (args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
52
  {
53
    List_iterator_fast<Item> li(list);
54
    Item *item;
55
    Item **save_args= args;
56
57
    while ((item=li++))
58
    {
59
      *(save_args++)= item;
60
      with_sum_func|=item->with_sum_func;
61
    }
62
  }
63
  list.empty();          // Fields are used
64
}
65
66
Item_func::Item_func(List<Item> &list)
67
  :allowed_arg_cols(1)
68
{
69
  set_arguments(list);
70
}
71
520.1.22 by Brian Aker
Second pass of thd cleanup
72
Item_func::Item_func(Session *session, Item_func *item)
73
  :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)
74
   allowed_arg_cols(item->allowed_arg_cols),
75
   arg_count(item->arg_count),
76
   used_tables_cache(item->used_tables_cache),
77
   not_null_tables_cache(item->not_null_tables_cache),
78
   const_item_cache(item->const_item_cache)
79
{
80
  if (arg_count)
81
  {
82
    if (arg_count <=2)
83
      args= tmp_arg;
84
    else
85
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
86
      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)
87
        return;
88
    }
89
    memcpy(args, item->args, sizeof(Item*)*arg_count);
90
  }
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)))
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)
150
        return true;        /* purecov: inspected */
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)
520.1.22 by Brian Aker
Second pass of thd cleanup
286
        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)
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
    break;
472
  case DECIMAL_RESULT:
473
    field= new Field_new_decimal(
474
                       my_decimal_precision_to_length(decimal_precision(),
475
                                                      decimals,
476
                                                      unsigned_flag),
477
                       maybe_null, name, decimals, unsigned_flag);
478
    break;
479
  case ROW_RESULT:
480
  default:
481
    // This case should never be chosen
482
    assert(0);
483
    field= 0;
484
    break;
485
  }
486
  if (field)
487
    field->init(table);
488
  return field;
489
}
490
491
492
my_decimal *Item_func::val_decimal(my_decimal *decimal_value)
493
{
494
  assert(fixed);
495
  int2my_decimal(E_DEC_FATAL_ERROR, val_int(), unsigned_flag, decimal_value);
496
  return decimal_value;
497
}
498
499
500
bool Item_func::agg_arg_collations(DTCollation &c, Item **items,
501
                                   uint32_t nitems, uint32_t flags)
502
{
503
  return agg_item_collations(c, func_name(), items, nitems, flags, 1);
504
}
505
506
507
bool Item_func::agg_arg_collations_for_comparison(DTCollation &c,
508
                                                  Item **items,
509
                                                  uint32_t nitems,
510
                                                  uint32_t flags)
511
{
512
  return agg_item_collations_for_comparison(c, func_name(),
513
                                            items, nitems, flags);
514
}
515
516
517
bool Item_func::agg_arg_charsets(DTCollation &c, Item **items, uint32_t nitems,
518
                                 uint32_t flags, int item_sep)
519
{
520
  return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep);
521
}
522
523
524
double Item_func::fix_result(double value)
525
{
492.3.26 by Lee
Changes to get drizzle building on Solaris 10 (SPARC)
526
  if (isfinite(value))
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)
527
    return value;
528
  null_value=1;
529
  return 0.0;
530
}
629.6.7 by Lee
final clean up of item/func functions moving them to the functions directory
531
532
533
void Item_func::fix_num_length_and_dec()
534
{
535
  uint32_t fl_length= 0;
536
  decimals=0;
537
  for (uint32_t i=0 ; i < arg_count ; i++)
538
  {
539
    set_if_bigger(decimals,args[i]->decimals);
540
    set_if_bigger(fl_length, args[i]->max_length);
541
  }
542
  max_length=float_length(decimals);
543
  if (fl_length > max_length)
544
  {
545
    decimals= NOT_FIXED_DEC;
546
    max_length= float_length(NOT_FIXED_DEC);
547
  }
548
}
549
550
/**
551
  Set max_length/decimals of function if function is fixed point and
552
  result length/precision depends on argument ones.
553
*/
554
555
void Item_func::count_decimal_length()
556
{
557
  int max_int_part= 0;
558
  decimals= 0;
559
  unsigned_flag= 1;
560
  for (uint32_t i=0 ; i < arg_count ; i++)
561
  {
562
    set_if_bigger(decimals, args[i]->decimals);
563
    set_if_bigger(max_int_part, args[i]->decimal_int_part());
564
    set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
565
  }
566
  int precision= cmin(max_int_part + decimals, DECIMAL_MAX_PRECISION);
567
  max_length= my_decimal_precision_to_length(precision, decimals,
568
                                             unsigned_flag);
569
}
570
571
572
/**
573
  Set max_length of if it is maximum length of its arguments.
574
*/
575
576
void Item_func::count_only_length()
577
{
578
  max_length= 0;
579
  unsigned_flag= 0;
580
  for (uint32_t i=0 ; i < arg_count ; i++)
581
  {
582
    set_if_bigger(max_length, args[i]->max_length);
583
    set_if_bigger(unsigned_flag, args[i]->unsigned_flag);
584
  }
585
}
586
587
588
/**
589
  Set max_length/decimals of function if function is floating point and
590
  result length/precision depends on argument ones.
591
*/
592
593
void Item_func::count_real_length()
594
{
595
  uint32_t length= 0;
596
  decimals= 0;
597
  max_length= 0;
598
  for (uint32_t i=0 ; i < arg_count ; i++)
599
  {
600
    if (decimals != NOT_FIXED_DEC)
601
    {
602
      set_if_bigger(decimals, args[i]->decimals);
603
      set_if_bigger(length, (args[i]->max_length - args[i]->decimals));
604
    }
605
    set_if_bigger(max_length, args[i]->max_length);
606
  }
607
  if (decimals != NOT_FIXED_DEC)
608
  {
609
    max_length= length;
610
    length+= decimals;
611
    if (length < max_length)  // If previous operation gave overflow
612
      max_length= UINT32_MAX;
613
    else
614
      max_length= length;
615
  }
616
}
617
618
619
620
void Item_func::signal_divide_by_null()
621
{
622
  Session *session= current_session;
623
  push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, ER_DIVISION_BY_ZERO, ER(ER_DIVISION_BY_ZERO));
624
  null_value= 1;
625
}
626
627
628
Item *Item_func::get_tmp_table_item(Session *session)
629
{
630
  if (!with_sum_func && !const_item() && functype() != SUSERVAR_FUNC)
631
    return new Item_field(result_field);
632
  return copy_or_same(session);
633
}
634
635