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