22
#include <drizzled/server_includes.h>
23
23
#include <drizzled/field/decimal.h>
24
24
#include <drizzled/error.h>
25
25
#include <drizzled/table.h>
26
26
#include <drizzled/session.h>
31
28
extern my_decimal decimal_zero;
33
30
/****************************************************************************
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)
32
****************************************************************************/
34
Field_new_decimal::Field_new_decimal(unsigned char *ptr_arg,
36
unsigned char *null_ptr_arg,
37
unsigned char null_bit_arg,
38
enum utype unireg_check_arg,
39
const char *field_name_arg,
52
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
53
set_if_smaller(precision, (uint32_t)DECIMAL_MAX_PRECISION);
54
assert((precision <= DECIMAL_MAX_PRECISION) &&
55
(dec <= DECIMAL_MAX_SCALE));
56
bin_size= my_decimal_get_binary_size(precision, dec);
59
Field_new_decimal::Field_new_decimal(uint32_t len_arg,
64
:Field_num((unsigned char*) 0,
66
maybe_null_arg ? (unsigned char*) "": 0,
74
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
75
set_if_smaller(precision, (uint32_t)DECIMAL_MAX_PRECISION);
76
assert((precision <= DECIMAL_MAX_PRECISION) &&
77
(dec <= DECIMAL_MAX_SCALE));
78
bin_size= my_decimal_get_binary_size(precision, dec);
82
int Field_new_decimal::reset(void)
87
84
store_value(&decimal_zero);
117
114
@param decimal_value my_decimal
125
bool Field_decimal::store_value(const my_decimal *decimal_value)
122
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))
126
if (warn_if_overflow(my_decimal2binary(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
127
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);
130
set_value_on_overflow(&buff, decimal_value->sign());
131
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)
138
int Field_new_decimal::store(const char *from, uint32_t length,
139
const CHARSET_INFO * const charset_arg)
147
142
my_decimal decimal_value;
152
147
~(E_DEC_OVERFLOW | E_DEC_BAD_NUM),
153
148
from, length, charset_arg,
154
149
&decimal_value)) &&
155
getTable()->in_use->abort_on_warning)
150
table->in_use->abort_on_warning)
157
152
/* Because "from" is not NUL-terminated and we use %s in the ER() */
158
153
String from_as_str;
159
154
from_as_str.copy(from, length, &my_charset_bin);
161
push_warning_printf(getTable()->in_use, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
156
push_warning_printf(table->in_use, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
162
157
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
163
158
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
164
159
"decimal", from_as_str.c_ptr(), field_name,
165
(uint32_t) getTable()->in_use->row_count);
160
(uint32_t) table->in_use->row_count);
182
177
String from_as_str;
183
178
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),
180
push_warning_printf(table->in_use, DRIZZLE_ERROR::WARN_LEVEL_WARN,
181
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
182
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
188
183
"decimal", from_as_str.c_ptr(), field_name,
189
(uint32_t) getTable()->in_use->row_count);
190
my_decimal_set_zero(&decimal_value);
184
(uint32_t) table->in_use->row_count);
185
my_decimal_set_zero(&decimal_value);
218
213
if (check_overflow(err))
219
214
set_value_on_overflow(&decimal_value, decimal_value.sign());
220
215
/* Only issue a warning if store_value doesn't issue an warning */
221
getTable()->in_use->got_warning= 0;
216
table->in_use->got_warning= 0;
223
218
if (store_value(&decimal_value))
225
else if (err && !getTable()->in_use->got_warning)
220
else if (err && !table->in_use->got_warning)
226
221
err= warn_if_overflow(err);
231
int Field_decimal::store(int64_t nr, bool unsigned_val)
226
int Field_new_decimal::store(int64_t nr, bool unsigned_val)
233
228
my_decimal decimal_value;
241
236
if (check_overflow(err))
242
237
set_value_on_overflow(&decimal_value, decimal_value.sign());
243
238
/* Only issue a warning if store_value doesn't issue an warning */
244
getTable()->in_use->got_warning= 0;
239
table->in_use->got_warning= 0;
246
241
if (store_value(&decimal_value))
248
else if (err && not getTable()->in_use->got_warning)
243
else if (err && !table->in_use->got_warning)
249
244
err= warn_if_overflow(err);
254
int Field_decimal::store_decimal(const my_decimal *decimal_value)
249
int Field_new_decimal::store_decimal(const my_decimal *decimal_value)
256
251
return store_value(decimal_value);
260
int Field_decimal::store_time(DRIZZLE_TIME *ltime,
261
enum enum_drizzle_timestamp_type )
255
int Field_new_decimal::store_time(DRIZZLE_TIME *ltime,
256
enum enum_drizzle_timestamp_type )
263
my_decimal decimal_value;
264
return store_value(date2my_decimal(ltime, &decimal_value));
258
my_decimal decimal_value;
259
return store_value(date2my_decimal(ltime, &decimal_value));
268
double Field_decimal::val_real(void)
263
double Field_new_decimal::val_real(void)
271
266
my_decimal decimal_value;
318
int Field_decimal::cmp(const unsigned char *a,const unsigned char*b)
313
int Field_new_decimal::cmp(const unsigned char *a,const unsigned char*b)
320
315
return memcmp(a, b, bin_size);
324
void Field_decimal::sort_string(unsigned char *buff,
319
void Field_new_decimal::sort_string(unsigned char *buff,
327
322
memcpy(buff, ptr, bin_size);
331
void Field_decimal::sql_type(String &str) const
326
void Field_new_decimal::sql_type(String &str) const
333
328
const CHARSET_INFO * const cs= str.charset();
334
329
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)
335
Save the field metadata for new decimal fields.
337
Saves the precision in the first byte and decimals() in the second
338
byte of the field metadata array at index of *metadata_ptr and
341
@param metadata_ptr First byte of field metadata
343
@returns number of bytes written to metadata_ptr
345
int Field_new_decimal::do_save_field_metadata(unsigned char *metadata_ptr)
347
*metadata_ptr= precision;
348
*(metadata_ptr + 1)= decimals();
354
Returns the number of bytes field uses in row-based replication
357
This method is used in row-based replication to determine the number
358
of bytes that the field consumes in the row record format. This is
359
used to skip fields in the master that do not exist on the slave.
361
@param field_metadata Encoded size in field metadata
363
@returns The size of the field based on the field metadata.
365
uint32_t Field_new_decimal::pack_length_from_metadata(uint32_t field_metadata)
353
367
uint32_t const source_precision= (field_metadata >> 8U) & 0x00ff;
354
368
uint32_t const source_decimal= field_metadata & 0x00ff;
355
369
uint32_t const source_size= my_decimal_get_binary_size(source_precision,
357
371
return (source_size);
361
uint32_t Field_decimal::is_equal(CreateField *new_field_ptr)
376
Check to see if field size is compatible with destination.
378
This method is used in row-based replication to verify that the slave's
379
field size is less than or equal to the master's field size. The
380
encoded field metadata (from the master or source) is decoded and compared
381
to the size of this field (the slave or destination).
383
@param field_metadata Encoded size in field metadata
385
@retval 0 if this field's size is < the source field's size
386
@retval 1 if this field's size is >= the source field's size
388
int Field_new_decimal::compatible_field_size(uint32_t field_metadata)
391
uint32_t const source_precision= (field_metadata >> 8U) & 0x00ff;
392
uint32_t const source_decimal= field_metadata & 0x00ff;
393
uint32_t const source_size= my_decimal_get_binary_size(source_precision,
395
uint32_t const destination_size= row_pack_length();
396
compatible= (source_size <= destination_size);
398
compatible= (source_precision <= precision) &&
399
(source_decimal <= decimals());
404
uint32_t Field_new_decimal::is_equal(CreateField *new_field_ptr)
363
406
return ((new_field_ptr->sql_type == real_type()) &&
364
407
((new_field_ptr->flags & UNSIGNED_FLAG) ==
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
417
Unpack a decimal field from row data.
419
This method is used to unpack a decimal or numeric field from a master
420
whose size of the field is less than that of the slave.
422
@param to Destination of the data
423
@param from Source of the data
424
@param param_data Precision (upper) and decimal (lower) values
426
@return New pointer into memory based on from + length of the data
385
428
const unsigned char *
386
Field_decimal::unpack(unsigned char* to,
387
const unsigned char *from,
429
Field_new_decimal::unpack(unsigned char* to,
430
const unsigned char *from,
391
434
if (param_data == 0)
392
435
return Field::unpack(to, from, param_data, low_byte_first);
411
454
conv_dec.len= from_precision;
412
455
conv_dec.buf= dec_buf;
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.
457
Note: bin2decimal does not change the length of the field. So it is
458
just the first step the resizing operation. The second step does the
459
resizing using the precision and decimals from the slave.
418
461
bin2decimal((unsigned char *)from, &conv_dec, from_precision, from_decimal);
419
462
decimal2bin(&conv_dec, to, precision, decimals());