~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item/float.cc

  • Committer: Brian Aker
  • Date: 2008-10-06 06:47:29 UTC
  • Revision ID: brian@tangent.org-20081006064729-2i9mhjkzyvow9xsm
Remove uint.

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