~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/double.cc

  • Committer: Jay Pipes
  • Date: 2008-07-17 18:48:58 UTC
  • mto: This revision was merged to the branch mainline in revision 182.
  • Revision ID: jay@mysql.com-20080717184858-2mbouxl8xi41gcge
Removed DBUG from CSV and Blackhole storage engines

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/current_session.h>
34
 
#include <drizzled/internal/m_string.h>
35
 
 
36
 
using namespace std;
37
 
 
38
 
namespace drizzled
39
 
{
40
 
 
41
 
/****************************************************************************
42
 
  double precision floating point numbers
43
 
****************************************************************************/
44
 
 
45
 
int Field_double::store(const char *from,uint32_t len, const CHARSET_INFO * const cs)
46
 
{
47
 
  int error;
48
 
  char *end;
49
 
  double nr= my_strntod(cs,(char*) from, len, &end, &error);
50
 
 
51
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
52
 
  if (error || (!len || (((uint32_t) (end-from) != len) && getTable()->in_use->count_cuted_fields)))
53
 
  {
54
 
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
55
 
                (error ? ER_WARN_DATA_OUT_OF_RANGE : ER_WARN_DATA_TRUNCATED), 1);
56
 
    error= error ? 1 : 2;
57
 
  }
58
 
  Field_double::store(nr);
59
 
  return error;
60
 
}
61
 
 
62
 
 
63
 
int Field_double::store(double nr)
64
 
{
65
 
  int error= truncate(&nr, DBL_MAX);
66
 
 
67
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
68
 
 
69
 
#ifdef WORDS_BIGENDIAN
70
 
  if (getTable()->getShare()->db_low_byte_first)
71
 
  {
72
 
    float8store(ptr,nr);
73
 
  }
74
 
  else
75
 
#endif
76
 
    doublestore(ptr,nr);
77
 
  return error;
78
 
}
79
 
 
80
 
 
81
 
int Field_double::store(int64_t nr, bool unsigned_val)
82
 
{
83
 
  return Field_double::store(unsigned_val ? uint64_t2double((uint64_t) nr) :
84
 
                             (double) nr);
85
 
}
86
 
 
87
 
double Field_double::val_real(void) const
88
 
{
89
 
  double j;
90
 
 
91
 
  ASSERT_COLUMN_MARKED_FOR_READ;
92
 
 
93
 
#ifdef WORDS_BIGENDIAN
94
 
  if (getTable()->getShare()->db_low_byte_first)
95
 
  {
96
 
    float8get(j,ptr);
97
 
  }
98
 
  else
99
 
#endif
100
 
    doubleget(j,ptr);
101
 
  return j;
102
 
}
103
 
 
104
 
int64_t Field_double::val_int(void) const
105
 
{
106
 
  double j;
107
 
  int64_t res;
108
 
 
109
 
  ASSERT_COLUMN_MARKED_FOR_READ;
110
 
 
111
 
#ifdef WORDS_BIGENDIAN
112
 
  if (getTable()->getShare()->db_low_byte_first)
113
 
  {
114
 
    float8get(j,ptr);
115
 
  }
116
 
  else
117
 
#endif
118
 
    doubleget(j,ptr);
119
 
  /* Check whether we fit into int64_t range */
120
 
  if (j <= (double) INT64_MIN)
121
 
  {
122
 
    res= (int64_t) INT64_MIN;
123
 
    goto warn;
124
 
  }
125
 
  if (j >= (double) (uint64_t) INT64_MAX)
126
 
  {
127
 
    res= (int64_t) INT64_MAX;
128
 
    goto warn;
129
 
  }
130
 
  return (int64_t) rint(j);
131
 
 
132
 
warn:
133
 
  {
134
 
    char buf[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
135
 
    String tmp(buf, sizeof(buf), &my_charset_utf8_general_ci), *str;
136
 
    str= val_str(&tmp, &tmp);
137
 
    Session *session= getTable() ? getTable()->in_use : current_session;
138
 
    push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
139
 
                        ER_TRUNCATED_WRONG_VALUE,
140
 
                        ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
141
 
                        str->c_ptr());
142
 
  }
143
 
  return res;
144
 
}
145
 
 
146
 
 
147
 
String *Field_double::val_str(String *val_buffer, String *) const
148
 
{
149
 
  double nr;
150
 
 
151
 
  ASSERT_COLUMN_MARKED_FOR_READ;
152
 
 
153
 
#ifdef WORDS_BIGENDIAN
154
 
  if (getTable()->getShare()->db_low_byte_first)
155
 
  {
156
 
    float8get(nr,ptr);
157
 
  }
158
 
  else
159
 
#endif
160
 
    doubleget(nr,ptr);
161
 
 
162
 
  uint32_t to_length= max(field_length, (uint32_t)DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE);
163
 
  val_buffer->alloc(to_length);
164
 
  char *to=(char*) val_buffer->ptr();
165
 
  size_t len;
166
 
 
167
 
  if (dec >= NOT_FIXED_DEC)
168
 
    len= internal::my_gcvt(nr, internal::MY_GCVT_ARG_DOUBLE, to_length - 1, to, NULL);
169
 
  else
170
 
    len= internal::my_fcvt(nr, dec, to, NULL);
171
 
 
172
 
  val_buffer->length((uint32_t) len);
173
 
 
174
 
  return val_buffer;
175
 
}
176
 
 
177
 
int Field_double::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
178
 
{
179
 
  double a,b;
180
 
#ifdef WORDS_BIGENDIAN
181
 
  if (getTable()->getShare()->db_low_byte_first)
182
 
  {
183
 
    float8get(a,a_ptr);
184
 
    float8get(b,b_ptr);
185
 
  }
186
 
  else
187
 
#endif
188
 
  {
189
 
    doubleget(a, a_ptr);
190
 
    doubleget(b, b_ptr);
191
 
  }
192
 
  return (a < b) ? -1 : (a > b) ? 1 : 0;
193
 
}
194
 
 
195
 
 
196
 
/* The following should work for IEEE */
197
 
 
198
 
void Field_double::sort_string(unsigned char *to,uint32_t )
199
 
{
200
 
  double nr;
201
 
#ifdef WORDS_BIGENDIAN
202
 
  if (getTable()->getShare()->db_low_byte_first)
203
 
  {
204
 
    float8get(nr,ptr);
205
 
  }
206
 
  else
207
 
#endif
208
 
    doubleget(nr,ptr);
209
 
  change_double_for_sort(nr, to);
210
 
}
211
 
 
212
 
 
213
 
void Field_double::sql_type(String &res) const
214
 
{
215
 
  const CHARSET_INFO * const cs=res.charset();
216
 
  if (dec == NOT_FIXED_DEC)
217
 
  {
218
 
    res.set_ascii(STRING_WITH_LEN("double"));
219
 
  }
220
 
  else
221
 
  {
222
 
    res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
223
 
                            "double(%d,%d)",(int) field_length,dec));
224
 
  }
225
 
}
226
 
 
227
 
} /* namespace drizzled */