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