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,
35
uint32_t len_arg, unsigned char *null_ptr_arg,
36
unsigned char null_bit_arg,
37
enum utype unireg_check_arg,
38
const char *field_name_arg,
39
uint8_t dec_arg,bool zero_arg,
41
:Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
42
unireg_check_arg, field_name_arg, dec_arg, zero_arg, unsigned_arg)
44
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
45
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
46
assert((precision <= DECIMAL_MAX_PRECISION) &&
47
(dec <= DECIMAL_MAX_SCALE));
48
bin_size= my_decimal_get_binary_size(precision, dec);
52
Field_new_decimal::Field_new_decimal(uint32_t len_arg,
57
:Field_num((unsigned char*) 0, len_arg,
58
maybe_null_arg ? (unsigned char*) "": 0, 0,
59
NONE, name, dec_arg, 0, unsigned_arg)
61
precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
62
set_if_smaller(precision, DECIMAL_MAX_PRECISION);
63
assert((precision <= DECIMAL_MAX_PRECISION) &&
64
(dec <= DECIMAL_MAX_SCALE));
65
bin_size= my_decimal_get_binary_size(precision, dec);
69
int Field_new_decimal::reset(void)
87
71
store_value(&decimal_zero);
117
101
@param decimal_value my_decimal
125
bool Field_decimal::store_value(const my_decimal *decimal_value)
109
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))
113
if (warn_if_overflow(my_decimal2binary(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
114
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);
117
set_value_on_overflow(&buff, decimal_value->sign());
118
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)
125
int Field_new_decimal::store(const char *from, uint32_t length,
126
const CHARSET_INFO * const charset_arg)
147
129
my_decimal decimal_value;
149
ASSERT_COLUMN_MARKED_FOR_WRITE;
151
131
if ((err= str2my_decimal(E_DEC_FATAL_ERROR &
152
132
~(E_DEC_OVERFLOW | E_DEC_BAD_NUM),
153
133
from, length, charset_arg,
154
134
&decimal_value)) &&
155
getTable()->in_use->abort_on_warning)
135
table->in_use->abort_on_warning)
157
137
/* Because "from" is not NUL-terminated and we use %s in the ER() */
158
138
String from_as_str;
159
139
from_as_str.copy(from, length, &my_charset_bin);
161
push_warning_printf(getTable()->in_use, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
141
push_warning_printf(table->in_use, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
162
142
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
163
143
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
164
144
"decimal", from_as_str.c_ptr(), field_name,
165
(uint32_t) getTable()->in_use->row_count);
145
(uint32_t) table->in_use->row_count);
171
151
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());
152
set_warning(DRIZZLE_ERROR::WARN_LEVEL_NOTE, ER_WARN_DATA_TRUNCATED, 1);
175
154
case E_DEC_OVERFLOW:
176
155
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
182
161
String from_as_str;
183
162
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),
164
push_warning_printf(table->in_use, DRIZZLE_ERROR::WARN_LEVEL_WARN,
165
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
166
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
188
167
"decimal", from_as_str.c_ptr(), field_name,
189
(uint32_t) getTable()->in_use->row_count);
190
my_decimal_set_zero(&decimal_value);
168
(uint32_t) table->in_use->row_count);
169
my_decimal_set_zero(&decimal_value);
218
195
if (check_overflow(err))
219
196
set_value_on_overflow(&decimal_value, decimal_value.sign());
220
197
/* Only issue a warning if store_value doesn't issue an warning */
221
getTable()->in_use->got_warning= 0;
198
table->in_use->got_warning= 0;
223
200
if (store_value(&decimal_value))
225
else if (err && !getTable()->in_use->got_warning)
202
else if (err && !table->in_use->got_warning)
226
203
err= warn_if_overflow(err);
231
int Field_decimal::store(int64_t nr, bool unsigned_val)
208
int Field_new_decimal::store(int64_t nr, bool unsigned_val)
233
210
my_decimal decimal_value;
236
ASSERT_COLUMN_MARKED_FOR_WRITE;
238
213
if ((err= int2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
239
214
nr, unsigned_val, &decimal_value)))
241
216
if (check_overflow(err))
242
217
set_value_on_overflow(&decimal_value, decimal_value.sign());
243
218
/* Only issue a warning if store_value doesn't issue an warning */
244
getTable()->in_use->got_warning= 0;
219
table->in_use->got_warning= 0;
246
221
if (store_value(&decimal_value))
248
else if (err && not getTable()->in_use->got_warning)
223
else if (err && !table->in_use->got_warning)
249
224
err= warn_if_overflow(err);
254
int Field_decimal::store_decimal(const my_decimal *decimal_value)
229
int Field_new_decimal::store_decimal(const my_decimal *decimal_value)
256
231
return store_value(decimal_value);
260
int Field_decimal::store_time(DRIZZLE_TIME *ltime,
261
enum enum_drizzle_timestamp_type )
235
int Field_new_decimal::store_time(DRIZZLE_TIME *ltime,
236
enum enum_drizzle_timestamp_type )
263
my_decimal decimal_value;
264
return store_value(date2my_decimal(ltime, &decimal_value));
238
my_decimal decimal_value;
239
return store_value(date2my_decimal(ltime, &decimal_value));
268
double Field_decimal::val_real(void)
243
double Field_new_decimal::val_real(void)
271
246
my_decimal decimal_value;
273
ASSERT_COLUMN_MARKED_FOR_READ;
275
247
my_decimal2double(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), &dbl);
281
int64_t Field_decimal::val_int(void)
252
int64_t Field_new_decimal::val_int(void)
284
255
my_decimal decimal_value;
286
ASSERT_COLUMN_MARKED_FOR_READ;
288
256
my_decimal2int(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), false, &i);
294
my_decimal* Field_decimal::val_decimal(my_decimal *decimal_value)
261
my_decimal* Field_new_decimal::val_decimal(my_decimal *decimal_value)
296
ASSERT_COLUMN_MARKED_FOR_READ;
298
263
binary2my_decimal(E_DEC_FATAL_ERROR, ptr, decimal_value,
300
265
return(decimal_value);
304
String *Field_decimal::val_str(String *val_buffer,
269
String *Field_new_decimal::val_str(String *val_buffer,
307
272
my_decimal decimal_value;
309
ASSERT_COLUMN_MARKED_FOR_READ;
311
273
uint32_t fixed_precision= decimal_precision ? precision : 0;
312
274
my_decimal2string(E_DEC_FATAL_ERROR, val_decimal(&decimal_value),
313
275
fixed_precision, dec, '0', val_buffer);
318
int Field_decimal::cmp(const unsigned char *a,const unsigned char*b)
280
int Field_new_decimal::cmp(const unsigned char *a,const unsigned char*b)
320
282
return memcmp(a, b, bin_size);
324
void Field_decimal::sort_string(unsigned char *buff,
286
void Field_new_decimal::sort_string(unsigned char *buff,
327
289
memcpy(buff, ptr, bin_size);
331
void Field_decimal::sql_type(String &str) const
293
void Field_new_decimal::sql_type(String &str) const
333
295
const CHARSET_INFO * const cs= str.charset();
334
296
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)
302
Save the field metadata for new decimal fields.
304
Saves the precision in the first byte and decimals() in the second
305
byte of the field metadata array at index of *metadata_ptr and
308
@param metadata_ptr First byte of field metadata
310
@returns number of bytes written to metadata_ptr
312
int Field_new_decimal::do_save_field_metadata(unsigned char *metadata_ptr)
314
*metadata_ptr= precision;
315
*(metadata_ptr + 1)= decimals();
321
Returns the number of bytes field uses in row-based replication
324
This method is used in row-based replication to determine the number
325
of bytes that the field consumes in the row record format. This is
326
used to skip fields in the master that do not exist on the slave.
328
@param field_metadata Encoded size in field metadata
330
@returns The size of the field based on the field metadata.
332
uint32_t Field_new_decimal::pack_length_from_metadata(uint32_t field_metadata)
353
334
uint32_t const source_precision= (field_metadata >> 8U) & 0x00ff;
354
335
uint32_t const source_decimal= field_metadata & 0x00ff;
355
336
uint32_t const source_size= my_decimal_get_binary_size(source_precision,
357
338
return (source_size);
361
uint32_t Field_decimal::is_equal(CreateField *new_field_ptr)
343
Check to see if field size is compatible with destination.
345
This method is used in row-based replication to verify that the slave's
346
field size is less than or equal to the master's field size. The
347
encoded field metadata (from the master or source) is decoded and compared
348
to the size of this field (the slave or destination).
350
@param field_metadata Encoded size in field metadata
352
@retval 0 if this field's size is < the source field's size
353
@retval 1 if this field's size is >= the source field's size
355
int Field_new_decimal::compatible_field_size(uint32_t field_metadata)
358
uint32_t const source_precision= (field_metadata >> 8U) & 0x00ff;
359
uint32_t const source_decimal= field_metadata & 0x00ff;
360
uint32_t const source_size= my_decimal_get_binary_size(source_precision,
362
uint32_t const destination_size= row_pack_length();
363
compatible= (source_size <= destination_size);
365
compatible= (source_precision <= precision) &&
366
(source_decimal <= decimals());
371
uint32_t Field_new_decimal::is_equal(Create_field *new_field_ptr)
363
373
return ((new_field_ptr->sql_type == real_type()) &&
364
374
((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
384
Unpack a decimal field from row data.
386
This method is used to unpack a decimal or numeric field from a master
387
whose size of the field is less than that of the slave.
389
@param to Destination of the data
390
@param from Source of the data
391
@param param_data Precision (upper) and decimal (lower) values
393
@return New pointer into memory based on from + length of the data
385
395
const unsigned char *
386
Field_decimal::unpack(unsigned char* to,
387
const unsigned char *from,
396
Field_new_decimal::unpack(unsigned char* to,
397
const unsigned char *from,
391
401
if (param_data == 0)
392
402
return Field::unpack(to, from, param_data, low_byte_first);
411
421
conv_dec.len= from_precision;
412
422
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.
424
Note: bin2decimal does not change the length of the field. So it is
425
just the first step the resizing operation. The second step does the
426
resizing using the precision and decimals from the slave.
418
428
bin2decimal((unsigned char *)from, &conv_dec, from_precision, from_decimal);
419
429
decimal2bin(&conv_dec, to, precision, decimals());