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
38
/****************************************************************************
30
39
double precision floating point numbers
31
40
****************************************************************************/
33
int Field_double::store(const char *from,uint len, const CHARSET_INFO * const cs)
42
int Field_double::store(const char *from,uint32_t len, const CHARSET_INFO * const cs)
37
46
double nr= my_strntod(cs,(char*) from, len, &end, &error);
38
if (error || (!len || (((uint) (end-from) != len) && table->in_use->count_cuted_fields)))
48
ASSERT_COLUMN_MARKED_FOR_WRITE;
49
if (error || (!len || (((uint32_t) (end-from) != len) && table->in_use->count_cuted_fields)))
40
51
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
41
52
(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
84
double Field_double::val_real(void)
88
ASSERT_COLUMN_MARKED_FOR_READ;
143
90
#ifdef WORDS_BIGENDIAN
144
91
if (table->s->db_low_byte_first)
181
131
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,
132
String tmp(buf, sizeof(buf), &my_charset_utf8_general_ci), *str;
133
str= val_str(&tmp, &tmp);
134
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
185
135
ER_TRUNCATED_WRONG_VALUE,
186
136
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
143
String *Field_double::val_str(String *val_buffer,
201
String *val_ptr __attribute__((unused)))
148
ASSERT_COLUMN_MARKED_FOR_READ;
204
150
#ifdef WORDS_BIGENDIAN
205
151
if (table->s->db_low_byte_first)
211
157
doubleget(nr,ptr);
213
uint to_length=max(field_length, (uint32_t)DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE);
159
uint32_t to_length= max(field_length, (uint32_t)DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE);
214
160
val_buffer->alloc(to_length);
215
161
char *to=(char*) val_buffer->ptr();
221
167
len= my_fcvt(nr, dec, to, NULL);
223
val_buffer->length((uint) len);
169
val_buffer->length((uint32_t) len);
225
171
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)
174
int Field_double::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
237
177
#ifdef WORDS_BIGENDIAN
253
#define DBL_EXP_DIG (sizeof(double)*8-DBL_MANT_DIG)
255
193
/* The following should work for IEEE */
257
void Field_double::sort_string(uchar *to,uint length __attribute__((unused)))
195
void Field_double::sort_string(unsigned char *to,uint32_t )
260
198
#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
210
void Field_double::sql_type(String &res) const
291
212
const CHARSET_INFO * const cs=res.charset();
298
219
res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
299
220
"double(%d,%d)",(int) field_length,dec));