23
#include <drizzled/field/decimal.h>
24
#include <drizzled/error.h>
25
#include <drizzled/table.h>
26
#include <drizzled/session.h>
31
extern my_decimal decimal_zero;
22
#include <drizzled/server_includes.h>
23
#include <drizzled/field/fdecimal.h>
24
#include <drizzled/drizzled_error_messages.h>
33
27
/****************************************************************************
35
****************************************************************************/
37
Field_decimal::Field_decimal(unsigned char *ptr_arg,
39
unsigned char *null_ptr_arg,
40
unsigned char null_bit_arg,
41
enum utype unireg_check_arg,
42
const char *field_name_arg,
55
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
56
set_if_smaller(precision, (uint32_t)DECIMAL_MAX_PRECISION);
57
assert((precision <= DECIMAL_MAX_PRECISION) &&
58
(dec <= DECIMAL_MAX_SCALE));
59
bin_size= my_decimal_get_binary_size(precision, dec);
62
Field_decimal::Field_decimal(uint32_t len_arg,
67
:Field_num((unsigned char*) 0,
69
maybe_null_arg ? (unsigned char*) "": 0,
77
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
78
set_if_smaller(precision, (uint32_t)DECIMAL_MAX_PRECISION);
79
assert((precision <= DECIMAL_MAX_PRECISION) &&
80
(dec <= DECIMAL_MAX_SCALE));
81
bin_size= my_decimal_get_binary_size(precision, dec);
85
int Field_decimal::reset(void)
29
****************************************************************************/
31
Field_new_decimal::Field_new_decimal(unsigned char *ptr_arg,
32
uint32_t len_arg, unsigned char *null_ptr_arg,
33
unsigned char null_bit_arg,
34
enum utype unireg_check_arg,
35
const char *field_name_arg,
36
uint8_t dec_arg,bool zero_arg,
38
:Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
39
unireg_check_arg, field_name_arg, dec_arg, zero_arg, unsigned_arg)
41
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
42
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
43
assert((precision <= DECIMAL_MAX_PRECISION) &&
44
(dec <= DECIMAL_MAX_SCALE));
45
bin_size= my_decimal_get_binary_size(precision, dec);
49
Field_new_decimal::Field_new_decimal(uint32_t len_arg,
54
:Field_num((unsigned char*) 0, len_arg,
55
maybe_null_arg ? (unsigned char*) "": 0, 0,
56
NONE, name, dec_arg, 0, unsigned_arg)
58
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
59
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
60
assert((precision <= DECIMAL_MAX_PRECISION) &&
61
(dec <= DECIMAL_MAX_SCALE));
62
bin_size= my_decimal_get_binary_size(precision, dec);
66
int Field_new_decimal::reset(void)
87
68
store_value(&decimal_zero);
117
98
@param decimal_value my_decimal
125
bool Field_decimal::store_value(const my_decimal *decimal_value)
106
bool Field_new_decimal::store_value(const my_decimal *decimal_value)
127
int error= my_decimal2binary(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
128
decimal_value, ptr, precision, dec);
129
if (warn_if_overflow(error))
110
if (warn_if_overflow(my_decimal2binary(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
111
decimal_value, ptr, precision, dec)))
131
if (error != E_DEC_TRUNCATED)
134
set_value_on_overflow(&buff, decimal_value->sign());
135
my_decimal2binary(E_DEC_FATAL_ERROR, &buff, ptr, precision, dec);
114
set_value_on_overflow(&buff, decimal_value->sign());
115
my_decimal2binary(E_DEC_FATAL_ERROR, &buff, ptr, precision, dec);
143
int Field_decimal::store(const char *from, uint32_t length,
144
const CHARSET_INFO * const charset_arg)
122
int Field_new_decimal::store(const char *from, uint32_t length,
123
const CHARSET_INFO * const charset_arg)
147
126
my_decimal decimal_value;
149
ASSERT_COLUMN_MARKED_FOR_WRITE;
151
128
if ((err= str2my_decimal(E_DEC_FATAL_ERROR &
152
129
~(E_DEC_OVERFLOW | E_DEC_BAD_NUM),
153
130
from, length, charset_arg,
154
131
&decimal_value)) &&
155
getTable()->in_use->abort_on_warning)
132
table->in_use->abort_on_warning)
157
134
/* Because "from" is not NUL-terminated and we use %s in the ER() */
158
135
String from_as_str;
159
136
from_as_str.copy(from, length, &my_charset_bin);
161
push_warning_printf(getTable()->in_use, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
138
push_warning_printf(table->in_use, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
162
139
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
163
140
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
164
141
"decimal", from_as_str.c_ptr(), field_name,
165
(uint32_t) getTable()->in_use->row_count);
142
(uint32_t) table->in_use->row_count);
171
148
case E_DEC_TRUNCATED:
172
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
173
set_value_on_overflow(&decimal_value, decimal_value.sign());
149
set_warning(DRIZZLE_ERROR::WARN_LEVEL_NOTE, ER_WARN_DATA_TRUNCATED, 1);
175
151
case E_DEC_OVERFLOW:
176
152
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
182
158
String from_as_str;
183
159
from_as_str.copy(from, length, &my_charset_bin);
185
push_warning_printf(getTable()->in_use, DRIZZLE_ERROR::WARN_LEVEL_WARN,
186
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
187
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
161
push_warning_printf(table->in_use, DRIZZLE_ERROR::WARN_LEVEL_WARN,
162
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
163
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
188
164
"decimal", from_as_str.c_ptr(), field_name,
189
(uint32_t) getTable()->in_use->row_count);
190
my_decimal_set_zero(&decimal_value);
165
(uint32_t) table->in_use->row_count);
166
my_decimal_set_zero(&decimal_value);
218
192
if (check_overflow(err))
219
193
set_value_on_overflow(&decimal_value, decimal_value.sign());
220
194
/* Only issue a warning if store_value doesn't issue an warning */
221
getTable()->in_use->got_warning= 0;
195
table->in_use->got_warning= 0;
223
197
if (store_value(&decimal_value))
225
else if (err && !getTable()->in_use->got_warning)
199
else if (err && !table->in_use->got_warning)
226
200
err= warn_if_overflow(err);
231
int Field_decimal::store(int64_t nr, bool unsigned_val)
205
int Field_new_decimal::store(int64_t nr, bool unsigned_val)
233
207
my_decimal decimal_value;
236
ASSERT_COLUMN_MARKED_FOR_WRITE;
238
210
if ((err= int2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
239
211
nr, unsigned_val, &decimal_value)))
241
213
if (check_overflow(err))
242
214
set_value_on_overflow(&decimal_value, decimal_value.sign());
243
215
/* Only issue a warning if store_value doesn't issue an warning */
244
getTable()->in_use->got_warning= 0;
216
table->in_use->got_warning= 0;
246
218
if (store_value(&decimal_value))
248
else if (err && not getTable()->in_use->got_warning)
220
else if (err && !table->in_use->got_warning)
249
221
err= warn_if_overflow(err);
254
int Field_decimal::store_decimal(const my_decimal *decimal_value)
226
int Field_new_decimal::store_decimal(const my_decimal *decimal_value)
256
228
return store_value(decimal_value);
260
int Field_decimal::store_time(DRIZZLE_TIME *ltime,
261
enum enum_drizzle_timestamp_type )
232
int Field_new_decimal::store_time(DRIZZLE_TIME *ltime,
233
enum enum_drizzle_timestamp_type t_type __attribute__((unused)))
263
my_decimal decimal_value;
264
return store_value(date2my_decimal(ltime, &decimal_value));
235
my_decimal decimal_value;
236
return store_value(date2my_decimal(ltime, &decimal_value));
268
double Field_decimal::val_real(void)
240
double Field_new_decimal::val_real(void)
271
243
my_decimal decimal_value;
273
ASSERT_COLUMN_MARKED_FOR_READ;
275
244
my_decimal2double(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), &dbl);
281
int64_t Field_decimal::val_int(void)
249
int64_t Field_new_decimal::val_int(void)
284
252
my_decimal decimal_value;
286
ASSERT_COLUMN_MARKED_FOR_READ;
288
253
my_decimal2int(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), false, &i);
294
my_decimal* Field_decimal::val_decimal(my_decimal *decimal_value)
258
my_decimal* Field_new_decimal::val_decimal(my_decimal *decimal_value)
296
ASSERT_COLUMN_MARKED_FOR_READ;
298
260
binary2my_decimal(E_DEC_FATAL_ERROR, ptr, decimal_value,
300
262
return(decimal_value);
304
String *Field_decimal::val_str(String *val_buffer,
266
String *Field_new_decimal::val_str(String *val_buffer,
267
String *val_ptr __attribute__((unused)))
307
269
my_decimal decimal_value;
309
ASSERT_COLUMN_MARKED_FOR_READ;
311
270
uint32_t fixed_precision= decimal_precision ? precision : 0;
312
271
my_decimal2string(E_DEC_FATAL_ERROR, val_decimal(&decimal_value),
313
272
fixed_precision, dec, '0', val_buffer);
318
int Field_decimal::cmp(const unsigned char *a,const unsigned char*b)
277
int Field_new_decimal::cmp(const unsigned char *a,const unsigned char*b)
320
279
return memcmp(a, b, bin_size);
324
void Field_decimal::sort_string(unsigned char *buff,
283
void Field_new_decimal::sort_string(unsigned char *buff,
284
uint32_t length __attribute__((unused)))
327
286
memcpy(buff, ptr, bin_size);
331
void Field_decimal::sql_type(String &str) const
290
void Field_new_decimal::sql_type(String &str) const
333
292
const CHARSET_INFO * const cs= str.charset();
334
293
str.length(cs->cset->snprintf(cs, (char*) str.ptr(), str.alloced_length(),
340
Returns the number of bytes field uses in row-based replication
343
This method is used in row-based replication to determine the number
344
of bytes that the field consumes in the row record format. This is
345
used to skip fields in the master that do not exist on the slave.
347
@param field_metadata Encoded size in field metadata
349
@returns The size of the field based on the field metadata.
351
uint32_t Field_decimal::pack_length_from_metadata(uint32_t field_metadata)
299
Save the field metadata for new decimal fields.
301
Saves the precision in the first byte and decimals() in the second
302
byte of the field metadata array at index of *metadata_ptr and
305
@param metadata_ptr First byte of field metadata
307
@returns number of bytes written to metadata_ptr
309
int Field_new_decimal::do_save_field_metadata(unsigned char *metadata_ptr)
311
*metadata_ptr= precision;
312
*(metadata_ptr + 1)= decimals();
318
Returns the number of bytes field uses in row-based replication
321
This method is used in row-based replication to determine the number
322
of bytes that the field consumes in the row record format. This is
323
used to skip fields in the master that do not exist on the slave.
325
@param field_metadata Encoded size in field metadata
327
@returns The size of the field based on the field metadata.
329
uint32_t Field_new_decimal::pack_length_from_metadata(uint32_t field_metadata)
353
331
uint32_t const source_precision= (field_metadata >> 8U) & 0x00ff;
354
uint32_t const source_decimal= field_metadata & 0x00ff;
355
uint32_t const source_size= my_decimal_get_binary_size(source_precision,
332
uint32_t const source_decimal= field_metadata & 0x00ff;
333
uint32_t const source_size= my_decimal_get_binary_size(source_precision,
357
335
return (source_size);
361
uint32_t Field_decimal::is_equal(CreateField *new_field_ptr)
363
return ((new_field_ptr->sql_type == real_type()) &&
364
((new_field_ptr->flags & UNSIGNED_FLAG) ==
365
(uint32_t) (flags & UNSIGNED_FLAG)) &&
366
((new_field_ptr->flags & AUTO_INCREMENT_FLAG) ==
367
(uint32_t) (flags & AUTO_INCREMENT_FLAG)) &&
368
(new_field_ptr->length == max_display_length()) &&
369
(new_field_ptr->decimals == dec));
374
Unpack a decimal field from row data.
376
This method is used to unpack a decimal or numeric field from a master
377
whose size of the field is less than that of the slave.
379
@param to Destination of the data
380
@param from Source of the data
381
@param param_data Precision (upper) and decimal (lower) values
383
@return New pointer into memory based on from + length of the data
340
Check to see if field size is compatible with destination.
342
This method is used in row-based replication to verify that the slave's
343
field size is less than or equal to the master's field size. The
344
encoded field metadata (from the master or source) is decoded and compared
345
to the size of this field (the slave or destination).
347
@param field_metadata Encoded size in field metadata
349
@retval 0 if this field's size is < the source field's size
350
@retval 1 if this field's size is >= the source field's size
352
int Field_new_decimal::compatible_field_size(uint32_t field_metadata)
355
uint32_t const source_precision= (field_metadata >> 8U) & 0x00ff;
356
uint32_t const source_decimal= field_metadata & 0x00ff;
357
uint32_t const source_size= my_decimal_get_binary_size(source_precision,
359
uint32_t const destination_size= row_pack_length();
360
compatible= (source_size <= destination_size);
362
compatible= (source_precision <= precision) &&
363
(source_decimal <= decimals());
368
uint32_t Field_new_decimal::is_equal(Create_field *new_field)
370
return ((new_field->sql_type == real_type()) &&
371
((new_field->flags & UNSIGNED_FLAG) ==
372
(uint) (flags & UNSIGNED_FLAG)) &&
373
((new_field->flags & AUTO_INCREMENT_FLAG) ==
374
(uint) (flags & AUTO_INCREMENT_FLAG)) &&
375
(new_field->length == max_display_length()) &&
376
(new_field->decimals == dec));
381
Unpack a decimal field from row data.
383
This method is used to unpack a decimal or numeric field from a master
384
whose size of the field is less than that of the slave.
386
@param to Destination of the data
387
@param from Source of the data
388
@param param_data Precision (upper) and decimal (lower) values
390
@return New pointer into memory based on from + length of the data
385
392
const unsigned char *
386
Field_decimal::unpack(unsigned char* to,
387
const unsigned char *from,
393
Field_new_decimal::unpack(unsigned char* to,
394
const unsigned char *from,
391
398
if (param_data == 0)
392
399
return Field::unpack(to, from, param_data, low_byte_first);
407
414
a decimal and write that to the raw data buffer.
409
416
decimal_digit_t dec_buf[DECIMAL_MAX_PRECISION];
411
conv_dec.len= from_precision;
412
conv_dec.buf= dec_buf;
418
dec.len= from_precision;
414
Note: bin2decimal does not change the length of the field. So it is
415
just the first step the resizing operation. The second step does the
416
resizing using the precision and decimals from the slave.
421
Note: bin2decimal does not change the length of the field. So it is
422
just the first step the resizing operation. The second step does the
423
resizing using the precision and decimals from the slave.
418
bin2decimal((unsigned char *)from, &conv_dec, from_precision, from_decimal);
419
decimal2bin(&conv_dec, to, precision, decimals());
425
bin2decimal((unsigned char *)from, &dec, from_precision, from_decimal);
426
decimal2bin(&dec, to, precision, decimals());
422
429
memcpy(to, from, len); // Sizes are the same, just copy the data.
426
} /* namespace drizzled */