~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/function/func.cc

Merge Revision revid:marko.makela@oracle.com-20100514133144-fe0l0b89tea4x4uu from MySQL InnoDB

Original revid:marko.makela@oracle.com-20100514133144-fe0l0b89tea4x4uu

Original Authors: Marko Mkel <marko.makela@oracle.com>
Original commit message:
Merge from mysql-5.1-innodb:

Post-merge fixes: Remove the MYSQL_VERSION_ID checks, because they only
apply to the InnoDB Plugin. Fix potential race condition accessing
trx->op_info and trx->detailed_error.
------------------------------------------------------------
revno: 3466
revision-id: marko.makela@oracle.com-20100514130815-ym7j7cfu88ro6km4
parent: marko.makela@oracle.com-20100514130228-n3n42nw7ht78k0wn
committer: Marko Mkel <marko.makela@oracle.com>
branch nick: mysql-5.1-innodb2
timestamp: Fri 2010-05-14 16:08:15 +0300
message:
  Make the InnoDB FOREIGN KEY parser understand multi-statements. (Bug #48024)
  Also make InnoDB thinks that /*/ only starts a comment. (Bug #53644).

  This fixes the bugs in the InnoDB Plugin.

  ha_innodb.h: Use trx_query_string() instead of trx_query() when
  available (MySQL 5.1.42 or later).

  innobase_get_stmt(): New function, to retrieve the currently running
  SQL statement.

  struct trx_struct: Remove mysql_query_str. Use innobase_get_stmt() instead.

  dict_strip_comments(): Add and observe the parameter sql_length. Treat
  /*/ as the start of a comment.

  dict_create_foreign_constraints(), row_table_add_foreign_constraints():
  Add the parameter sql_length.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
 
using namespace std;
21
 
#include <drizzled/server_includes.h>
22
 
 
23
 
#include CSTDINT_H
24
 
#include <cassert>
 
20
#include "config.h"
25
21
 
26
22
#include <drizzled/sql_string.h>
27
23
#include <drizzled/sql_list.h>
28
24
 
29
 
#include <drizzled/functions/int.h>
 
25
#include <drizzled/function/math/int.h>
30
26
#include <drizzled/field/int64_t.h>
31
27
#include <drizzled/field/long.h>
32
28
#include <drizzled/field/double.h>
33
 
#include <drizzled/field/fdecimal.h>
34
 
#include CMATH_H
35
 
#include <drizzled/util/math.h>
 
29
#include <drizzled/field/decimal.h>
36
30
#include <drizzled/session.h>
37
 
 
38
 
#if defined(CMATH_NAMESPACE)
39
 
using namespace CMATH_NAMESPACE;
40
 
#endif
41
 
 
 
31
#include <drizzled/error.h>
 
32
#include <drizzled/check_stack_overrun.h>
 
33
#include <limits>
 
34
#include <algorithm>
 
35
 
 
36
using namespace std;
 
37
 
 
38
namespace drizzled
 
39
{
42
40
 
43
41
 
44
42
void Item_func::set_arguments(List<Item> &list)
46
44
  allowed_arg_cols= 1;
47
45
  arg_count=list.elements;
48
46
  args= tmp_arg;                                // If 2 arguments
49
 
  if (arg_count <= 2 || (args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
 
47
  if (arg_count <= 2 || (args=(Item**) memory::sql_alloc(sizeof(Item*)*arg_count)))
50
48
  {
51
49
    List_iterator_fast<Item> li(list);
52
50
    Item *item;
61
59
  list.empty();          // Fields are used
62
60
}
63
61
 
64
 
Item_func::Item_func(List<Item> &list)
65
 
  :allowed_arg_cols(1)
 
62
Item_func::Item_func(List<Item> &list) :
 
63
  _session(*current_session),
 
64
  allowed_arg_cols(1)
66
65
{
 
66
  collation.set(DERIVATION_SYSCONST);
67
67
  set_arguments(list);
68
68
}
69
69
 
70
 
Item_func::Item_func(Session *session, Item_func *item)
71
 
  :Item_result_field(session, item),
72
 
   allowed_arg_cols(item->allowed_arg_cols),
73
 
   arg_count(item->arg_count),
74
 
   used_tables_cache(item->used_tables_cache),
75
 
   not_null_tables_cache(item->not_null_tables_cache),
76
 
   const_item_cache(item->const_item_cache)
 
70
Item_func::Item_func(Session *session, Item_func *item) :
 
71
  Item_result_field(session, item),
 
72
  _session(*current_session),
 
73
  allowed_arg_cols(item->allowed_arg_cols),
 
74
  arg_count(item->arg_count),
 
75
  used_tables_cache(item->used_tables_cache),
 
76
  not_null_tables_cache(item->not_null_tables_cache),
 
77
  const_item_cache(item->const_item_cache)
77
78
{
78
79
  if (arg_count)
79
80
  {
86
87
    }
87
88
    memcpy(args, item->args, sizeof(Item*)*arg_count);
88
89
  }
 
90
  collation.set(DERIVATION_SYSCONST);
89
91
}
90
92
 
91
93
 
123
125
*/
124
126
 
125
127
bool
126
 
Item_func::fix_fields(Session *session, Item **ref __attribute__((unused)))
 
128
Item_func::fix_fields(Session *session, Item **)
127
129
{
128
130
  assert(fixed == 0);
129
131
  Item **arg,**arg_end;
145
147
        We shouldn't call fix_fields() twice, so check 'fixed' field first
146
148
      */
147
149
      if ((!(*arg)->fixed && (*arg)->fix_fields(session, arg)))
148
 
        return true;        /* purecov: inspected */
 
150
        return true;
149
151
      item= *arg;
150
152
 
151
153
      if (allowed_arg_cols)
180
182
}
181
183
 
182
184
 
183
 
void Item_func::fix_after_pullout(st_select_lex *new_parent,
184
 
                                  Item **ref __attribute__((unused)))
 
185
void Item_func::fix_after_pullout(Select_Lex *new_parent,
 
186
                                  Item **)
185
187
{
186
188
  Item **arg,**arg_end;
187
189
 
226
228
    Item **arg,**arg_end;
227
229
 
228
230
    switch (order) {
229
 
    case(PREFIX):
 
231
    case (T_PREFIX):
230
232
      (*traverser)(this, argument);
231
233
      for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
232
234
      {
233
235
        (*arg)->traverse_cond(traverser, argument, order);
234
236
      }
235
237
      break;
236
 
    case (POSTFIX):
 
238
    case (T_POSTFIX):
237
239
      for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
238
240
      {
239
241
        (*arg)->traverse_cond(traverser, argument, order);
281
283
        change records at each execution.
282
284
      */
283
285
      if (*arg != new_item)
284
 
        current_session->change_item_tree(arg, new_item);
 
286
        getSession().change_item_tree(arg, new_item);
285
287
    }
286
288
  }
287
289
  return (this->*transformer)(argument);
466
468
    break;
467
469
  case STRING_RESULT:
468
470
    return make_string_field(table);
469
 
    break;
470
471
  case DECIMAL_RESULT:
471
 
    field= new Field_new_decimal(
472
 
                       my_decimal_precision_to_length(decimal_precision(),
473
 
                                                      decimals,
474
 
                                                      unsigned_flag),
475
 
                       maybe_null, name, decimals, unsigned_flag);
 
472
    field= new Field_decimal(my_decimal_precision_to_length(decimal_precision(),
 
473
                                                            decimals,
 
474
                                                            unsigned_flag),
 
475
                             maybe_null,
 
476
                             name,
 
477
                             decimals,
 
478
                             unsigned_flag);
476
479
    break;
477
480
  case ROW_RESULT:
478
481
  default:
521
524
 
522
525
double Item_func::fix_result(double value)
523
526
{
524
 
  if (isfinite(value))
 
527
  static double fix_infinity= numeric_limits<double>::infinity();
 
528
 
 
529
  if (value != fix_infinity && value != -fix_infinity)
525
530
    return value;
526
531
  null_value=1;
527
532
  return 0.0;
528
533
}
 
534
 
 
535
 
 
536
void Item_func::fix_num_length_and_dec()
 
537
{
 
538
  uint32_t fl_length= 0;
 
539
  decimals=0;
 
540
  for (uint32_t i=0 ; i < arg_count ; i++)
 
541
  {
 
542
    set_if_bigger(decimals,args[i]->decimals);
 
543
    set_if_bigger(fl_length, args[i]->max_length);
 
544
  }
 
545
  max_length=float_length(decimals);
 
546
  if (fl_length > max_length)
 
547
  {
 
548
    decimals= NOT_FIXED_DEC;
 
549
    max_length= float_length(NOT_FIXED_DEC);
 
550
  }
 
551
}
 
552
 
 
553
/**
 
554
  Set max_length/decimals of function if function is fixed point and
 
555
  result length/precision depends on argument ones.
 
556
*/
 
557
 
 
558
void Item_func::count_decimal_length()
 
559
{
 
560
  int max_int_part= 0;
 
561
  decimals= 0;
 
562
  unsigned_flag= 1;
 
563
  for (uint32_t i= 0 ; i < arg_count ; i++)
 
564
  {
 
565
    set_if_bigger(decimals, args[i]->decimals);
 
566
    set_if_bigger(max_int_part, args[i]->decimal_int_part());
 
567
    set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
 
568
  }
 
569
  int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
 
570
  max_length= my_decimal_precision_to_length(precision, decimals,
 
571
                                             unsigned_flag);
 
572
}
 
573
 
 
574
 
 
575
/**
 
576
  Set max_length of if it is maximum length of its arguments.
 
577
*/
 
578
 
 
579
void Item_func::count_only_length()
 
580
{
 
581
  max_length= 0;
 
582
  unsigned_flag= 0;
 
583
  for (uint32_t i=0 ; i < arg_count ; i++)
 
584
  {
 
585
    set_if_bigger(max_length, args[i]->max_length);
 
586
    set_if_bigger(unsigned_flag, args[i]->unsigned_flag);
 
587
  }
 
588
}
 
589
 
 
590
 
 
591
/**
 
592
  Set max_length/decimals of function if function is floating point and
 
593
  result length/precision depends on argument ones.
 
594
*/
 
595
 
 
596
void Item_func::count_real_length()
 
597
{
 
598
  uint32_t length= 0;
 
599
  decimals= 0;
 
600
  max_length= 0;
 
601
  for (uint32_t i=0 ; i < arg_count ; i++)
 
602
  {
 
603
    if (decimals != NOT_FIXED_DEC)
 
604
    {
 
605
      set_if_bigger(decimals, args[i]->decimals);
 
606
      set_if_bigger(length, (args[i]->max_length - args[i]->decimals));
 
607
    }
 
608
    set_if_bigger(max_length, args[i]->max_length);
 
609
  }
 
610
  if (decimals != NOT_FIXED_DEC)
 
611
  {
 
612
    max_length= length;
 
613
    length+= decimals;
 
614
    if (length < max_length)  // If previous operation gave overflow
 
615
      max_length= UINT32_MAX;
 
616
    else
 
617
      max_length= length;
 
618
  }
 
619
}
 
620
 
 
621
 
 
622
 
 
623
void Item_func::signal_divide_by_null()
 
624
{
 
625
  my_error(ER_DIVISION_BY_ZERO, MYF(0));
 
626
  null_value= 0;
 
627
}
 
628
 
 
629
 
 
630
Item *Item_func::get_tmp_table_item(Session *session)
 
631
{
 
632
  if (!with_sum_func && !const_item() && functype() != SUSERVAR_FUNC)
 
633
    return new Item_field(result_field);
 
634
  return copy_or_same(session);
 
635
}
 
636
 
 
637
 
 
638
} /* namespace drizzled */