~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/float.cc

  • Committer: Brian Aker
  • Date: 2009-06-05 05:40:36 UTC
  • mfrom: (1046.1.15 merge)
  • Revision ID: brian@gaz-20090605054036-1024tm3gv0oloipw
Merge of Brian

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#include <drizzled/error.h>
 
22
#include <drizzled/item/num.h>
 
23
#include <drizzled/item/string.h>
 
24
#include <drizzled/item/float.h>
 
25
 
 
26
static uint32_t nr_of_decimals(const char *str, const char *end)
 
27
{
 
28
  const char *decimal_point;
 
29
 
 
30
  /* Find position for '.' */
 
31
  for (;;)
 
32
  {
 
33
    if (str == end)
 
34
      return 0;
 
35
    if (*str == 'e' || *str == 'E')
 
36
      return NOT_FIXED_DEC;
 
37
    if (*str++ == '.')
 
38
      break;
 
39
  }
 
40
  decimal_point= str;
 
41
  for (; my_isdigit(system_charset_info, *str) ; str++)
 
42
    ;
 
43
  if (*str == 'e' || *str == 'E')
 
44
    return NOT_FIXED_DEC;
 
45
  return (uint32_t) (str - decimal_point);
 
46
}
 
47
 
 
48
String *Item_float::val_str(String *str)
 
49
{
 
50
  // following assert is redundant, because fixed=1 assigned in constructor
 
51
  assert(fixed == 1);
 
52
  str->set_real(value,decimals,&my_charset_bin);
 
53
  return str;
 
54
}
 
55
 
 
56
 
 
57
int64_t Item_float::val_int()
 
58
{
 
59
  assert(fixed == 1);
 
60
  if (value <= (double) INT64_MIN)
 
61
  {
 
62
     return INT64_MIN;
 
63
  }
 
64
  else if (value >= (double) (uint64_t) INT64_MAX)
 
65
  {
 
66
    return INT64_MAX;
 
67
  }
 
68
  return (int64_t) rint(value);
 
69
}
 
70
 
 
71
my_decimal *Item_float::val_decimal(my_decimal *decimal_value)
 
72
{
 
73
  // following assert is redundant, because fixed=1 assigned in constructor
 
74
  assert(fixed == 1);
 
75
  double2my_decimal(E_DEC_FATAL_ERROR, value, decimal_value);
 
76
  return (decimal_value);
 
77
}
 
78
 
 
79
/**
 
80
  This function is only called during parsing. We will signal an error if
 
81
  value is not a true double value (overflow)
 
82
*/
 
83
 
 
84
Item_float::Item_float(const char *str_arg, uint32_t length)
 
85
{
 
86
  int error;
 
87
  char *end_not_used;
 
88
  value= my_strntod(&my_charset_bin, (char*) str_arg, length, &end_not_used,
 
89
                    &error);
 
90
  if (error)
 
91
  {
 
92
    /*
 
93
      Note that we depend on that str_arg is null terminated, which is true
 
94
      when we are in the parser
 
95
    */
 
96
    assert(str_arg[length] == 0);
 
97
    my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "double", (char*) str_arg);
 
98
  }
 
99
  presentation= name=(char*) str_arg;
 
100
  decimals=(uint8_t) nr_of_decimals(str_arg, str_arg+length);
 
101
  max_length=length;
 
102
  fixed= 1;
 
103
}
 
104
 
 
105
int Item_float::save_in_field(Field *field, bool)
 
106
{
 
107
  double nr= val_real();
 
108
  if (null_value)
 
109
    return set_field_to_null(field);
 
110
  field->set_notnull();
 
111
  return field->store(nr);
 
112
}
 
113
 
 
114
 
 
115
void Item_float::print(String *str, enum_query_type)
 
116
{
 
117
  if (presentation)
 
118
  {
 
119
    str->append(presentation);
 
120
    return;
 
121
  }
 
122
  char buffer[20];
 
123
  String num(buffer, sizeof(buffer), &my_charset_bin);
 
124
  num.set_real(value, decimals, &my_charset_bin);
 
125
  str->append(num);
 
126
}
 
127
 
 
128
/*
 
129
  hex item
 
130
  In string context this is a binary string.
 
131
  In number context this is a int64_t value.
 
132
*/
 
133
 
 
134
bool Item_float::eq(const Item *arg, bool) const
 
135
{
 
136
  if (arg->basic_const_item() && arg->type() == type())
 
137
  {
 
138
    /*
 
139
      We need to cast off const to call val_int(). This should be OK for
 
140
      a basic constant.
 
141
    */
 
142
    Item *item= (Item*) arg;
 
143
    return item->val_real() == value;
 
144
  }
 
145
  return false;
 
146
}
 
147
 
 
148
Item *Item_static_float_func::safe_charset_converter(const CHARSET_INFO * const)
 
149
{
 
150
  Item_string *conv;
 
151
  char buf[64];
 
152
  String *s, tmp(buf, sizeof(buf), &my_charset_bin);
 
153
  s= val_str(&tmp);
 
154
  if ((conv= new Item_static_string_func(func_name, s->ptr(), s->length(),
 
155
                                         s->charset())))
 
156
  {
 
157
    conv->str_value.copy();
 
158
    conv->str_value.mark_as_const();
 
159
  }
 
160
  return conv;
 
161
}
 
162
 
 
163