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
#include <drizzled/field/fdecimal.h>
27
#include <drizzled/drizzled_error_messages.h>
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;
30
33
/****************************************************************************
32
****************************************************************************/
34
Field_new_decimal::Field_new_decimal(uchar *ptr_arg,
35
uint32_t len_arg, uchar *null_ptr_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((uchar*) 0, len_arg,
58
maybe_null_arg ? (uchar*) "": 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)
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)
71
87
store_value(&decimal_zero);
241
int Field_new_decimal::store_decimal(const my_decimal *decimal_value)
252
int Field_decimal::store_decimal(const my_decimal *decimal_value)
243
254
return store_value(decimal_value);
247
int Field_new_decimal::store_time(DRIZZLE_TIME *ltime,
248
timestamp_type t_type __attribute__((unused)))
258
int Field_decimal::store_time(DRIZZLE_TIME *ltime,
259
enum enum_drizzle_timestamp_type )
250
my_decimal decimal_value;
251
return store_value(date2my_decimal(ltime, &decimal_value));
261
my_decimal decimal_value;
262
return store_value(date2my_decimal(ltime, &decimal_value));
255
double Field_new_decimal::val_real(void)
266
double Field_decimal::val_real(void)
258
269
my_decimal decimal_value;
271
ASSERT_COLUMN_MARKED_FOR_READ;
259
273
my_decimal2double(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), &dbl);
264
int64_t Field_new_decimal::val_int(void)
279
int64_t Field_decimal::val_int(void)
267
282
my_decimal decimal_value;
268
my_decimal2int(E_DEC_FATAL_ERROR, val_decimal(&decimal_value),
284
ASSERT_COLUMN_MARKED_FOR_READ;
286
my_decimal2int(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), false, &i);
274
my_decimal* Field_new_decimal::val_decimal(my_decimal *decimal_value)
292
my_decimal* Field_decimal::val_decimal(my_decimal *decimal_value)
294
ASSERT_COLUMN_MARKED_FOR_READ;
276
296
binary2my_decimal(E_DEC_FATAL_ERROR, ptr, decimal_value,
278
298
return(decimal_value);
282
String *Field_new_decimal::val_str(String *val_buffer,
283
String *val_ptr __attribute__((unused)))
302
String *Field_decimal::val_str(String *val_buffer,
285
305
my_decimal decimal_value;
286
uint fixed_precision= decimal_precision ? precision : 0;
307
ASSERT_COLUMN_MARKED_FOR_READ;
309
uint32_t fixed_precision= decimal_precision ? precision : 0;
287
310
my_decimal2string(E_DEC_FATAL_ERROR, val_decimal(&decimal_value),
288
311
fixed_precision, dec, '0', val_buffer);
289
312
return val_buffer;
293
int Field_new_decimal::cmp(const uchar *a,const uchar*b)
316
int Field_decimal::cmp(const unsigned char *a,const unsigned char*b)
295
318
return memcmp(a, b, bin_size);
299
void Field_new_decimal::sort_string(uchar *buff,
300
uint length __attribute__((unused)))
322
void Field_decimal::sort_string(unsigned char *buff,
302
325
memcpy(buff, ptr, bin_size);
306
void Field_new_decimal::sql_type(String &str) const
329
void Field_decimal::sql_type(String &str) const
308
331
const CHARSET_INFO * const cs= str.charset();
309
332
str.length(cs->cset->snprintf(cs, (char*) str.ptr(), str.alloced_length(),
310
333
"decimal(%d,%d)", precision, (int)dec));
316
Save the field metadata for new decimal fields.
318
Saves the precision in the first byte and decimals() in the second
319
byte of the field metadata array at index of *metadata_ptr and
322
@param metadata_ptr First byte of field metadata
324
@returns number of bytes written to metadata_ptr
326
int Field_new_decimal::do_save_field_metadata(uchar *metadata_ptr)
328
*metadata_ptr= precision;
329
*(metadata_ptr + 1)= decimals();
335
Returns the number of bytes field uses in row-based replication
338
This method is used in row-based replication to determine the number
339
of bytes that the field consumes in the row record format. This is
340
used to skip fields in the master that do not exist on the slave.
342
@param field_metadata Encoded size in field metadata
344
@returns The size of the field based on the field metadata.
346
uint Field_new_decimal::pack_length_from_metadata(uint field_metadata)
348
uint const source_precision= (field_metadata >> 8U) & 0x00ff;
349
uint const source_decimal= field_metadata & 0x00ff;
350
uint const source_size= my_decimal_get_binary_size(source_precision,
338
Returns the number of bytes field uses in row-based replication
341
This method is used in row-based replication to determine the number
342
of bytes that the field consumes in the row record format. This is
343
used to skip fields in the master that do not exist on the slave.
345
@param field_metadata Encoded size in field metadata
347
@returns The size of the field based on the field metadata.
349
uint32_t Field_decimal::pack_length_from_metadata(uint32_t field_metadata)
351
uint32_t const source_precision= (field_metadata >> 8U) & 0x00ff;
352
uint32_t const source_decimal= field_metadata & 0x00ff;
353
uint32_t const source_size= my_decimal_get_binary_size(source_precision,
352
355
return (source_size);
357
Check to see if field size is compatible with destination.
359
This method is used in row-based replication to verify that the slave's
360
field size is less than or equal to the master's field size. The
361
encoded field metadata (from the master or source) is decoded and compared
362
to the size of this field (the slave or destination).
364
@param field_metadata Encoded size in field metadata
366
@retval 0 if this field's size is < the source field's size
367
@retval 1 if this field's size is >= the source field's size
369
int Field_new_decimal::compatible_field_size(uint field_metadata)
372
uint const source_precision= (field_metadata >> 8U) & 0x00ff;
373
uint const source_decimal= field_metadata & 0x00ff;
374
uint const source_size= my_decimal_get_binary_size(source_precision,
376
uint const destination_size= row_pack_length();
377
compatible= (source_size <= destination_size);
379
compatible= (source_precision <= precision) &&
380
(source_decimal <= decimals());
385
uint Field_new_decimal::is_equal(Create_field *new_field)
387
return ((new_field->sql_type == real_type()) &&
388
((new_field->flags & UNSIGNED_FLAG) ==
389
(uint) (flags & UNSIGNED_FLAG)) &&
390
((new_field->flags & AUTO_INCREMENT_FLAG) ==
391
(uint) (flags & AUTO_INCREMENT_FLAG)) &&
392
(new_field->length == max_display_length()) &&
393
(new_field->decimals == dec));
398
Unpack a decimal field from row data.
400
This method is used to unpack a decimal or numeric field from a master
401
whose size of the field is less than that of the slave.
403
@param to Destination of the data
404
@param from Source of the data
405
@param param_data Precision (upper) and decimal (lower) values
407
@return New pointer into memory based on from + length of the data
410
Field_new_decimal::unpack(uchar* to,
359
uint32_t Field_decimal::is_equal(CreateField *new_field_ptr)
361
return ((new_field_ptr->sql_type == real_type()) &&
362
((new_field_ptr->flags & UNSIGNED_FLAG) ==
363
(uint32_t) (flags & UNSIGNED_FLAG)) &&
364
((new_field_ptr->flags & AUTO_INCREMENT_FLAG) ==
365
(uint32_t) (flags & AUTO_INCREMENT_FLAG)) &&
366
(new_field_ptr->length == max_display_length()) &&
367
(new_field_ptr->decimals == dec));
372
Unpack a decimal field from row data.
374
This method is used to unpack a decimal or numeric field from a master
375
whose size of the field is less than that of the slave.
377
@param to Destination of the data
378
@param from Source of the data
379
@param param_data Precision (upper) and decimal (lower) values
381
@return New pointer into memory based on from + length of the data
383
const unsigned char *
384
Field_decimal::unpack(unsigned char* to,
385
const unsigned char *from,
415
389
if (param_data == 0)
416
390
return Field::unpack(to, from, param_data, low_byte_first);
418
uint from_precision= (param_data & 0xff00) >> 8U;
419
uint from_decimal= param_data & 0x00ff;
420
uint length=pack_length();
421
uint from_pack_len= my_decimal_get_binary_size(from_precision, from_decimal);
422
uint len= (param_data && (from_pack_len < length)) ?
423
from_pack_len : length;
392
uint32_t from_precision= (param_data & 0xff00) >> 8U;
393
uint32_t from_decimal= param_data & 0x00ff;
394
uint32_t length=pack_length();
395
uint32_t from_pack_len= my_decimal_get_binary_size(from_precision, from_decimal);
396
uint32_t len= (param_data && (from_pack_len < length)) ?
397
from_pack_len : length;
424
398
if ((from_pack_len && (from_pack_len < length)) ||
425
399
(from_precision < precision) ||
426
400
(from_decimal < decimals()))