~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/double.cc

Removed/replaced DBUG symbols and TRUE/FALSE

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 MySQL
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; either version 2 of the License, or
9
 
 *  (at your option) any later version.
10
 
 *
11
 
 *  This program is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *  GNU General Public License for more details.
15
 
 *
16
 
 *  You should have received a copy of the GNU General Public License
17
 
 *  along with this program; if not, write to the Free Software
18
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 
 */
20
 
 
21
 
 
22
 
#include "config.h"
23
 
 
24
 
#include <float.h>
25
 
#include <math.h>
26
 
 
27
 
#include <algorithm>
28
 
 
29
 
#include <drizzled/field/double.h>
30
 
#include <drizzled/error.h>
31
 
#include <drizzled/table.h>
32
 
#include <drizzled/session.h>
33
 
#include "drizzled/internal/m_string.h"
34
 
 
35
 
using namespace std;
36
 
 
37
 
namespace drizzled
38
 
{
39
 
 
40
 
/****************************************************************************
41
 
  double precision floating point numbers
42
 
****************************************************************************/
43
 
 
44
 
int Field_double::store(const char *from,uint32_t len, const CHARSET_INFO * const cs)
45
 
{
46
 
  int error;
47
 
  char *end;
48
 
  double nr= my_strntod(cs,(char*) from, len, &end, &error);
49
 
 
50
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
51
 
  if (error || (!len || (((uint32_t) (end-from) != len) && getTable()->in_use->count_cuted_fields)))
52
 
  {
53
 
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
54
 
                (error ? ER_WARN_DATA_OUT_OF_RANGE : ER_WARN_DATA_TRUNCATED), 1);
55
 
    error= error ? 1 : 2;
56
 
  }
57
 
  Field_double::store(nr);
58
 
  return error;
59
 
}
60
 
 
61
 
 
62
 
int Field_double::store(double nr)
63
 
{
64
 
  int error= truncate(&nr, DBL_MAX);
65
 
 
66
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
67
 
 
68
 
#ifdef WORDS_BIGENDIAN
69
 
  if (getTable()->getShare()->db_low_byte_first)
70
 
  {
71
 
    float8store(ptr,nr);
72
 
  }
73
 
  else
74
 
#endif
75
 
    doublestore(ptr,nr);
76
 
  return error;
77
 
}
78
 
 
79
 
 
80
 
int Field_double::store(int64_t nr, bool unsigned_val)
81
 
{
82
 
  return Field_double::store(unsigned_val ? uint64_t2double((uint64_t) nr) :
83
 
                             (double) nr);
84
 
}
85
 
 
86
 
double Field_double::val_real(void)
87
 
{
88
 
  double j;
89
 
 
90
 
  ASSERT_COLUMN_MARKED_FOR_READ;
91
 
 
92
 
#ifdef WORDS_BIGENDIAN
93
 
  if (getTable()->s->db_low_byte_first)
94
 
  {
95
 
    float8get(j,ptr);
96
 
  }
97
 
  else
98
 
#endif
99
 
    doubleget(j,ptr);
100
 
  return j;
101
 
}
102
 
 
103
 
int64_t Field_double::val_int(void)
104
 
{
105
 
  double j;
106
 
  int64_t res;
107
 
 
108
 
  ASSERT_COLUMN_MARKED_FOR_READ;
109
 
 
110
 
#ifdef WORDS_BIGENDIAN
111
 
  if (getTable()->s->db_low_byte_first)
112
 
  {
113
 
    float8get(j,ptr);
114
 
  }
115
 
  else
116
 
#endif
117
 
    doubleget(j,ptr);
118
 
  /* Check whether we fit into int64_t range */
119
 
  if (j <= (double) INT64_MIN)
120
 
  {
121
 
    res= (int64_t) INT64_MIN;
122
 
    goto warn;
123
 
  }
124
 
  if (j >= (double) (uint64_t) INT64_MAX)
125
 
  {
126
 
    res= (int64_t) INT64_MAX;
127
 
    goto warn;
128
 
  }
129
 
  return (int64_t) rint(j);
130
 
 
131
 
warn:
132
 
  {
133
 
    char buf[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
134
 
    String tmp(buf, sizeof(buf), &my_charset_utf8_general_ci), *str;
135
 
    str= val_str(&tmp, &tmp);
136
 
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
137
 
                        ER_TRUNCATED_WRONG_VALUE,
138
 
                        ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
139
 
                        str->c_ptr());
140
 
  }
141
 
  return res;
142
 
}
143
 
 
144
 
 
145
 
String *Field_double::val_str(String *val_buffer,
146
 
                              String *)
147
 
{
148
 
  double nr;
149
 
 
150
 
  ASSERT_COLUMN_MARKED_FOR_READ;
151
 
 
152
 
#ifdef WORDS_BIGENDIAN
153
 
  if (getTable()->s->db_low_byte_first)
154
 
  {
155
 
    float8get(nr,ptr);
156
 
  }
157
 
  else
158
 
#endif
159
 
    doubleget(nr,ptr);
160
 
 
161
 
  uint32_t to_length= max(field_length, (uint32_t)DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE);
162
 
  val_buffer->alloc(to_length);
163
 
  char *to=(char*) val_buffer->ptr();
164
 
  size_t len;
165
 
 
166
 
  if (dec >= NOT_FIXED_DEC)
167
 
    len= internal::my_gcvt(nr, internal::MY_GCVT_ARG_DOUBLE, to_length - 1, to, NULL);
168
 
  else
169
 
    len= internal::my_fcvt(nr, dec, to, NULL);
170
 
 
171
 
  val_buffer->length((uint32_t) len);
172
 
 
173
 
  return val_buffer;
174
 
}
175
 
 
176
 
int Field_double::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
177
 
{
178
 
  double a,b;
179
 
#ifdef WORDS_BIGENDIAN
180
 
  if (getTable()->s->db_low_byte_first)
181
 
  {
182
 
    float8get(a,a_ptr);
183
 
    float8get(b,b_ptr);
184
 
  }
185
 
  else
186
 
#endif
187
 
  {
188
 
    doubleget(a, a_ptr);
189
 
    doubleget(b, b_ptr);
190
 
  }
191
 
  return (a < b) ? -1 : (a > b) ? 1 : 0;
192
 
}
193
 
 
194
 
 
195
 
/* The following should work for IEEE */
196
 
 
197
 
void Field_double::sort_string(unsigned char *to,uint32_t )
198
 
{
199
 
  double nr;
200
 
#ifdef WORDS_BIGENDIAN
201
 
  if (getTable()->s->db_low_byte_first)
202
 
  {
203
 
    float8get(nr,ptr);
204
 
  }
205
 
  else
206
 
#endif
207
 
    doubleget(nr,ptr);
208
 
  change_double_for_sort(nr, to);
209
 
}
210
 
 
211
 
 
212
 
void Field_double::sql_type(String &res) const
213
 
{
214
 
  const CHARSET_INFO * const cs=res.charset();
215
 
  if (dec == NOT_FIXED_DEC)
216
 
  {
217
 
    res.set_ascii(STRING_WITH_LEN("double"));
218
 
  }
219
 
  else
220
 
  {
221
 
    res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
222
 
                            "double(%d,%d)",(int) field_length,dec));
223
 
  }
224
 
}
225
 
 
226
 
} /* namespace drizzled */