~drizzle-trunk/drizzle/development

642.1.6 by Lee
move functions from item.cc/item.h to item directory
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>
642.1.25 by Lee
more header file cleanup
22
#include <drizzled/item/num.h>
642.1.63 by Lee
more header file cleanup
23
#include <drizzled/item/string.h>
670.4.1 by Monty Taylor
Removed recursive subdirs in drizzled/, which allowed the renaming of ifloat and istring. It's also faster.
24
#include <drizzled/item/float.h>
642.1.6 by Lee
move functions from item.cc/item.h to item directory
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;
895 by Brian Aker
Completion (?) of uint conversion.
45
  return (uint32_t) (str - decimal_point);
642.1.6 by Lee
move functions from item.cc/item.h to item directory
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