18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
#ifdef USE_PRAGMA_IMPLEMENTATION
22
#pragma implementation // gcc: Class implementation
25
#include <drizzled/server_includes.h>
26
29
#include <drizzled/field/double.h>
27
#include <drizzled/drizzled_error_messages.h>
30
#include <drizzled/error.h>
31
#include <drizzled/table.h>
32
#include <drizzled/session.h>
33
#include "drizzled/internal/m_string.h"
29
40
/****************************************************************************
30
41
double precision floating point numbers
31
42
****************************************************************************/
33
int Field_double::store(const char *from,uint len, const CHARSET_INFO * const cs)
44
int Field_double::store(const char *from,uint32_t len, const CHARSET_INFO * const cs)
37
48
double nr= my_strntod(cs,(char*) from, len, &end, &error);
38
if (error || (!len || (((uint) (end-from) != len) && table->in_use->count_cuted_fields)))
50
ASSERT_COLUMN_MARKED_FOR_WRITE;
51
if (error || (!len || (((uint32_t) (end-from) != len) && table->in_use->count_cuted_fields)))
40
53
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
41
54
(error ? ER_WARN_DATA_OUT_OF_RANGE : ER_WARN_DATA_TRUNCATED), 1);
72
If a field has fixed length, truncate the double argument pointed to by 'nr'
74
Also ensure that the argument is within [-max_value; max_value] range.
77
int Field_real::truncate(double *nr, double max_value)
86
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
89
else if (unsigned_flag && res < 0)
92
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
98
uint order= field_length - dec;
99
uint step= array_elements(log_10) - 1;
101
for (; order > step; order-= step)
102
max_value*= log_10[step];
103
max_value*= log_10[order];
104
max_value-= 1.0 / log_10[dec];
106
/* Check for infinity so we don't get NaN in calculations */
109
double tmp= rint((res - floor(res)) * log_10[dec]) / log_10[dec];
110
res= floor(res) + tmp;
114
if (res < -max_value)
117
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
119
else if (res > max_value)
122
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
133
int Field_real::store_decimal(const my_decimal *dm)
136
my_decimal2double(E_DEC_FATAL_ERROR, dm, &dbl);
140
86
double Field_double::val_real(void)
90
ASSERT_COLUMN_MARKED_FOR_READ;
143
92
#ifdef WORDS_BIGENDIAN
144
93
if (table->s->db_low_byte_first)
181
133
char buf[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
182
String tmp(buf, sizeof(buf), &my_charset_latin1), *str;
183
str= val_str(&tmp, 0);
184
push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
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,
185
137
ER_TRUNCATED_WRONG_VALUE,
186
138
ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
193
my_decimal *Field_real::val_decimal(my_decimal *decimal_value)
195
double2my_decimal(E_DEC_FATAL_ERROR, val_real(), decimal_value);
196
return decimal_value;
200
145
String *Field_double::val_str(String *val_buffer,
201
String *val_ptr __attribute__((unused)))
150
ASSERT_COLUMN_MARKED_FOR_READ;
204
152
#ifdef WORDS_BIGENDIAN
205
153
if (table->s->db_low_byte_first)
211
159
doubleget(nr,ptr);
213
uint to_length=max(field_length, (uint32_t)DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE);
161
uint32_t to_length= max(field_length, (uint32_t)DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE);
214
162
val_buffer->alloc(to_length);
215
163
char *to=(char*) val_buffer->ptr();
218
166
if (dec >= NOT_FIXED_DEC)
219
len= my_gcvt(nr, MY_GCVT_ARG_DOUBLE, to_length - 1, to, NULL);
167
len= internal::my_gcvt(nr, internal::MY_GCVT_ARG_DOUBLE, to_length - 1, to, NULL);
221
len= my_fcvt(nr, dec, to, NULL);
169
len= internal::my_fcvt(nr, dec, to, NULL);
223
val_buffer->length((uint) len);
171
val_buffer->length((uint32_t) len);
225
173
return val_buffer;
228
bool Field_double::send_binary(Protocol *protocol)
230
return protocol->store((double) Field_double::val_real(), dec, (String*) 0);
234
int Field_double::cmp(const uchar *a_ptr, const uchar *b_ptr)
176
int Field_double::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
237
179
#ifdef WORDS_BIGENDIAN
253
#define DBL_EXP_DIG (sizeof(double)*8-DBL_MANT_DIG)
255
195
/* The following should work for IEEE */
257
void Field_double::sort_string(uchar *to,uint length __attribute__((unused)))
197
void Field_double::sort_string(unsigned char *to,uint32_t )
260
200
#ifdef WORDS_BIGENDIAN
273
Save the field metadata for double fields.
275
Saves the pack length in the first byte of the field metadata array
276
at index of *metadata_ptr.
278
@param metadata_ptr First byte of field metadata
280
@returns number of bytes written to metadata_ptr
282
int Field_double::do_save_field_metadata(uchar *metadata_ptr)
284
*metadata_ptr= pack_length();
289
212
void Field_double::sql_type(String &res) const
291
214
const CHARSET_INFO * const cs=res.charset();
298
221
res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
299
222
"double(%d,%d)",(int) field_length,dec));
226
} /* namespace drizzled */