~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/decimal.cc

  • Committer: Brian Aker
  • Date: 2009-11-12 16:13:04 UTC
  • mfrom: (1211.1.7 staging)
  • Revision ID: brian@gaz-20091112161304-opamiauv36fg0n6u
Rollup of Brian, Padraig, and Stewart patches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
extern my_decimal decimal_zero;
29
29
 
30
30
/****************************************************************************
31
 
** Field_new_decimal
32
 
****************************************************************************/
33
 
 
34
 
Field_new_decimal::Field_new_decimal(unsigned char *ptr_arg,
35
 
                                     uint32_t len_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,
40
 
                                     uint8_t dec_arg,
41
 
                                     bool zero_arg,
42
 
                                     bool unsigned_arg)
43
 
  :Field_num(ptr_arg,
44
 
             len_arg,
45
 
             null_ptr_arg,
46
 
             null_bit_arg,
47
 
             unireg_check_arg,
48
 
             field_name_arg,
49
 
             dec_arg, zero_arg,
50
 
             unsigned_arg)
51
 
{
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);
57
 
}
58
 
 
59
 
Field_new_decimal::Field_new_decimal(uint32_t len_arg,
60
 
                                     bool maybe_null_arg,
61
 
                                     const char *name,
62
 
                                     uint8_t dec_arg,
63
 
                                     bool unsigned_arg)
64
 
  :Field_num((unsigned char*) 0,
65
 
             len_arg,
66
 
             maybe_null_arg ? (unsigned char*) "": 0,
67
 
             0,
68
 
             NONE,
69
 
             name,
70
 
             dec_arg,
71
 
             0,
72
 
             unsigned_arg)
73
 
{
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);
79
 
}
80
 
 
81
 
 
82
 
int Field_new_decimal::reset(void)
 
31
 ** File_decimal
 
32
 ****************************************************************************/
 
33
 
 
34
Field_decimal::Field_decimal(unsigned char *ptr_arg,
 
35
                             uint32_t len_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,
 
40
                             uint8_t dec_arg,
 
41
                             bool zero_arg,
 
42
                             bool unsigned_arg)
 
43
:Field_num(ptr_arg,
 
44
           len_arg,
 
45
           null_ptr_arg,
 
46
           null_bit_arg,
 
47
           unireg_check_arg,
 
48
           field_name_arg,
 
49
           dec_arg, zero_arg,
 
50
           unsigned_arg)
 
51
{
 
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);
 
57
}
 
58
 
 
59
Field_decimal::Field_decimal(uint32_t len_arg,
 
60
                             bool maybe_null_arg,
 
61
                             const char *name,
 
62
                             uint8_t dec_arg,
 
63
                             bool unsigned_arg)
 
64
:Field_num((unsigned char*) 0,
 
65
           len_arg,
 
66
           maybe_null_arg ? (unsigned char*) "": 0,
 
67
           0,
 
68
           NONE,
 
69
           name,
 
70
           dec_arg,
 
71
           0,
 
72
           unsigned_arg)
 
73
{
 
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);
 
79
}
 
80
 
 
81
 
 
82
int Field_decimal::reset(void)
83
83
{
84
84
  store_value(&decimal_zero);
85
85
  return 0;
93
93
  @param sign              sign of value which caused overflow
94
94
*/
95
95
 
96
 
void Field_new_decimal::set_value_on_overflow(my_decimal *decimal_value,
97
 
                                              bool sign)
 
96
void Field_decimal::set_value_on_overflow(my_decimal *decimal_value,
 
97
                                          bool sign)
98
98
{
99
99
  max_my_decimal(decimal_value, precision, decimals());
100
100
  if (sign)
114
114
  @param decimal_value   my_decimal
115
115
 
116
116
  @retval
117
 
    0 ok
 
117
  0 ok
118
118
  @retval
119
 
    1 error
 
119
  1 error
120
120
*/
121
121
 
122
 
bool Field_new_decimal::store_value(const my_decimal *decimal_value)
 
122
bool Field_decimal::store_value(const my_decimal *decimal_value)
123
123
{
124
124
  int error= 0;
125
125
 
135
135
}
136
136
 
137
137
 
138
 
int Field_new_decimal::store(const char *from, uint32_t length,
139
 
                             const CHARSET_INFO * const charset_arg)
 
138
int Field_decimal::store(const char *from, uint32_t length,
 
139
                         const CHARSET_INFO * const charset_arg)
140
140
{
141
141
  int err;
142
142
  my_decimal decimal_value;
177
177
      String from_as_str;
178
178
      from_as_str.copy(from, length, &my_charset_bin);
179
179
 
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),
 
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),
183
183
                          "decimal", from_as_str.c_ptr(), field_name,
184
 
                        (uint32_t) table->in_use->row_count);
185
 
    my_decimal_set_zero(&decimal_value);
 
184
                          (uint32_t) table->in_use->row_count);
 
185
      my_decimal_set_zero(&decimal_value);
186
186
 
187
 
    break;
 
187
      break;
188
188
    }
189
189
  }
190
190
 
199
199
  will return E_DEC_TRUNCATED always correctly
200
200
*/
201
201
 
202
 
int Field_new_decimal::store(double nr)
 
202
int Field_decimal::store(double nr)
203
203
{
204
204
  my_decimal decimal_value;
205
205
  int err;
223
223
}
224
224
 
225
225
 
226
 
int Field_new_decimal::store(int64_t nr, bool unsigned_val)
 
226
int Field_decimal::store(int64_t nr, bool unsigned_val)
227
227
{
228
228
  my_decimal decimal_value;
229
229
  int err;
246
246
}
247
247
 
248
248
 
249
 
int Field_new_decimal::store_decimal(const my_decimal *decimal_value)
 
249
int Field_decimal::store_decimal(const my_decimal *decimal_value)
250
250
{
251
251
  return store_value(decimal_value);
252
252
}
253
253
 
254
254
 
255
 
int Field_new_decimal::store_time(DRIZZLE_TIME *ltime,
256
 
                                  enum enum_drizzle_timestamp_type )
 
255
int Field_decimal::store_time(DRIZZLE_TIME *ltime,
 
256
                              enum enum_drizzle_timestamp_type )
257
257
{
258
 
    my_decimal decimal_value;
259
 
    return store_value(date2my_decimal(ltime, &decimal_value));
 
258
  my_decimal decimal_value;
 
259
  return store_value(date2my_decimal(ltime, &decimal_value));
260
260
}
261
261
 
262
262
 
263
 
double Field_new_decimal::val_real(void)
 
263
double Field_decimal::val_real(void)
264
264
{
265
265
  double dbl;
266
266
  my_decimal decimal_value;
273
273
}
274
274
 
275
275
 
276
 
int64_t Field_new_decimal::val_int(void)
 
276
int64_t Field_decimal::val_int(void)
277
277
{
278
278
  int64_t i;
279
279
  my_decimal decimal_value;
286
286
}
287
287
 
288
288
 
289
 
my_decimal* Field_new_decimal::val_decimal(my_decimal *decimal_value)
 
289
my_decimal* Field_decimal::val_decimal(my_decimal *decimal_value)
290
290
{
291
291
  ASSERT_COLUMN_MARKED_FOR_READ;
292
292
 
296
296
}
297
297
 
298
298
 
299
 
String *Field_new_decimal::val_str(String *val_buffer,
300
 
                                   String *)
 
299
String *Field_decimal::val_str(String *val_buffer,
 
300
                               String *)
301
301
{
302
302
  my_decimal decimal_value;
303
303
 
310
310
}
311
311
 
312
312
 
313
 
int Field_new_decimal::cmp(const unsigned char *a,const unsigned char*b)
 
313
int Field_decimal::cmp(const unsigned char *a,const unsigned char*b)
314
314
{
315
315
  return memcmp(a, b, bin_size);
316
316
}
317
317
 
318
318
 
319
 
void Field_new_decimal::sort_string(unsigned char *buff,
320
 
                                    uint32_t )
 
319
void Field_decimal::sort_string(unsigned char *buff,
 
320
                                uint32_t )
321
321
{
322
322
  memcpy(buff, ptr, bin_size);
323
323
}
324
324
 
325
325
 
326
 
void Field_new_decimal::sql_type(String &str) const
 
326
void Field_decimal::sql_type(String &str) const
327
327
{
328
328
  const CHARSET_INFO * const cs= str.charset();
329
329
  str.length(cs->cset->snprintf(cs, (char*) str.ptr(), str.alloced_length(),
332
332
 
333
333
 
334
334
/**
335
 
   Save the field metadata for new decimal fields.
336
 
 
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
339
 
   *(metadata_ptr + 1).
340
 
 
341
 
   @param   metadata_ptr   First byte of field metadata
342
 
 
343
 
   @returns number of bytes written to metadata_ptr
 
335
  Save the field metadata for new decimal fields.
 
336
 
 
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
 
339
 *(metadata_ptr + 1).
 
340
 
 
341
 @param   metadata_ptr   First byte of field metadata
 
342
 
 
343
 @returns number of bytes written to metadata_ptr
344
344
*/
345
 
int Field_new_decimal::do_save_field_metadata(unsigned char *metadata_ptr)
 
345
int Field_decimal::do_save_field_metadata(unsigned char *metadata_ptr)
346
346
{
347
347
  *metadata_ptr= precision;
348
348
  *(metadata_ptr + 1)= decimals();
351
351
 
352
352
 
353
353
/**
354
 
   Returns the number of bytes field uses in row-based replication
355
 
   row packed size.
356
 
 
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.
360
 
 
361
 
   @param   field_metadata   Encoded size in field metadata
362
 
 
363
 
   @returns The size of the field based on the field metadata.
 
354
  Returns the number of bytes field uses in row-based replication
 
355
  row packed size.
 
356
 
 
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.
 
360
 
 
361
  @param   field_metadata   Encoded size in field metadata
 
362
 
 
363
  @returns The size of the field based on the field metadata.
364
364
*/
365
 
uint32_t Field_new_decimal::pack_length_from_metadata(uint32_t field_metadata)
 
365
uint32_t Field_decimal::pack_length_from_metadata(uint32_t field_metadata)
366
366
{
367
367
  uint32_t const source_precision= (field_metadata >> 8U) & 0x00ff;
368
368
  uint32_t const source_decimal= field_metadata & 0x00ff;
369
369
  uint32_t const source_size= my_decimal_get_binary_size(source_precision,
370
 
                                                     source_decimal);
 
370
                                                         source_decimal);
371
371
  return (source_size);
372
372
}
373
373
 
374
374
 
375
375
/**
376
 
   Check to see if field size is compatible with destination.
377
 
 
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).
382
 
 
383
 
   @param   field_metadata   Encoded size in field metadata
384
 
 
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
 
376
  Check to see if field size is compatible with destination.
 
377
 
 
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).
 
382
 
 
383
  @param   field_metadata   Encoded size in field metadata
 
384
 
 
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
387
387
*/
388
 
int Field_new_decimal::compatible_field_size(uint32_t field_metadata)
 
388
int Field_decimal::compatible_field_size(uint32_t field_metadata)
389
389
{
390
390
  int compatible= 0;
391
391
  uint32_t const source_precision= (field_metadata >> 8U) & 0x00ff;
392
392
  uint32_t const source_decimal= field_metadata & 0x00ff;
393
393
  uint32_t const source_size= my_decimal_get_binary_size(source_precision,
394
 
                                                     source_decimal);
 
394
                                                         source_decimal);
395
395
  uint32_t const destination_size= row_pack_length();
396
396
  compatible= (source_size <= destination_size);
397
397
  if (compatible)
398
398
    compatible= (source_precision <= precision) &&
399
 
                (source_decimal <= decimals());
 
399
      (source_decimal <= decimals());
400
400
  return (compatible);
401
401
}
402
402
 
403
403
 
404
 
uint32_t Field_new_decimal::is_equal(CreateField *new_field_ptr)
 
404
uint32_t Field_decimal::is_equal(CreateField *new_field_ptr)
405
405
{
406
406
  return ((new_field_ptr->sql_type == real_type()) &&
407
407
          ((new_field_ptr->flags & UNSIGNED_FLAG) ==
414
414
 
415
415
 
416
416
/**
417
 
   Unpack a decimal field from row data.
418
 
 
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.
421
 
 
422
 
   @param   to         Destination of the data
423
 
   @param   from       Source of the data
424
 
   @param   param_data Precision (upper) and decimal (lower) values
425
 
 
426
 
   @return  New pointer into memory based on from + length of the data
 
417
  Unpack a decimal field from row data.
 
418
 
 
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.
 
421
 
 
422
  @param   to         Destination of the data
 
423
  @param   from       Source of the data
 
424
  @param   param_data Precision (upper) and decimal (lower) values
 
425
 
 
426
  @return  New pointer into memory based on from + length of the data
427
427
*/
428
428
const unsigned char *
429
 
Field_new_decimal::unpack(unsigned char* to,
430
 
                          const unsigned char *from,
431
 
                          uint32_t param_data,
432
 
                          bool low_byte_first)
 
429
Field_decimal::unpack(unsigned char* to,
 
430
                      const unsigned char *from,
 
431
                      uint32_t param_data,
 
432
                      bool low_byte_first)
433
433
{
434
434
  if (param_data == 0)
435
435
    return Field::unpack(to, from, param_data, low_byte_first);
439
439
  uint32_t length=pack_length();
440
440
  uint32_t from_pack_len= my_decimal_get_binary_size(from_precision, from_decimal);
441
441
  uint32_t len= (param_data && (from_pack_len < length)) ?
442
 
            from_pack_len : length;
 
442
    from_pack_len : length;
443
443
  if ((from_pack_len && (from_pack_len < length)) ||
444
444
      (from_precision < precision) ||
445
445
      (from_decimal < decimals()))
454
454
    conv_dec.len= from_precision;
455
455
    conv_dec.buf= dec_buf;
456
456
    /*
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.
 
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.
460
460
    */
461
461
    bin2decimal((unsigned char *)from, &conv_dec, from_precision, from_decimal);
462
462
    decimal2bin(&conv_dec, to, precision, decimals());