~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/decimal.cc

  • Committer: Padraig O'Sullivan
  • Date: 2009-07-08 04:26:02 UTC
  • mto: (1089.3.4 merge)
  • mto: This revision was merged to the branch mainline in revision 1092.
  • Revision ID: osullivan.padraig@gmail.com-20090708042602-x4hmf9ny8dcpvb22
Replaced an instance where a uint8_t type was being used to hold a
collection of flags. Converted it to a std::bitset<2> instead.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 */
20
20
 
21
21
 
22
 
#include "config.h"
 
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>
27
27
 
28
 
namespace drizzled
29
 
{
30
 
 
31
28
extern my_decimal decimal_zero;
32
29
 
33
30
/****************************************************************************
34
 
 ** File_decimal
35
 
 ****************************************************************************/
36
 
 
37
 
Field_decimal::Field_decimal(unsigned char *ptr_arg,
38
 
                             uint32_t len_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,
43
 
                             uint8_t dec_arg,
44
 
                             bool zero_arg,
45
 
                             bool unsigned_arg)
46
 
:Field_num(ptr_arg,
47
 
           len_arg,
48
 
           null_ptr_arg,
49
 
           null_bit_arg,
50
 
           unireg_check_arg,
51
 
           field_name_arg,
52
 
           dec_arg, zero_arg,
53
 
           unsigned_arg)
54
 
{
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);
60
 
}
61
 
 
62
 
Field_decimal::Field_decimal(uint32_t len_arg,
63
 
                             bool maybe_null_arg,
64
 
                             const char *name,
65
 
                             uint8_t dec_arg,
66
 
                             bool unsigned_arg)
67
 
:Field_num((unsigned char*) 0,
68
 
           len_arg,
69
 
           maybe_null_arg ? (unsigned char*) "": 0,
70
 
           0,
71
 
           NONE,
72
 
           name,
73
 
           dec_arg,
74
 
           0,
75
 
           unsigned_arg)
76
 
{
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);
82
 
}
83
 
 
84
 
 
85
 
int Field_decimal::reset(void)
 
31
** Field_new_decimal
 
32
****************************************************************************/
 
33
 
 
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,
 
40
                                     bool unsigned_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)
 
43
{
 
44
  precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
 
45
  set_if_smaller(precision, (uint32_t)DECIMAL_MAX_PRECISION);
 
46
  assert((precision <= DECIMAL_MAX_PRECISION) &&
 
47
              (dec <= DECIMAL_MAX_SCALE));
 
48
  bin_size= my_decimal_get_binary_size(precision, dec);
 
49
}
 
50
 
 
51
 
 
52
Field_new_decimal::Field_new_decimal(uint32_t len_arg,
 
53
                                     bool maybe_null_arg,
 
54
                                     const char *name,
 
55
                                     uint8_t dec_arg,
 
56
                                     bool unsigned_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)
 
60
{
 
61
  precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
 
62
  set_if_smaller(precision, (uint32_t)DECIMAL_MAX_PRECISION);
 
63
  assert((precision <= DECIMAL_MAX_PRECISION) &&
 
64
              (dec <= DECIMAL_MAX_SCALE));
 
65
  bin_size= my_decimal_get_binary_size(precision, dec);
 
66
}
 
67
 
 
68
 
 
69
int Field_new_decimal::reset(void)
86
70
{
87
71
  store_value(&decimal_zero);
88
72
  return 0;
96
80
  @param sign              sign of value which caused overflow
97
81
*/
98
82
 
99
 
void Field_decimal::set_value_on_overflow(my_decimal *decimal_value,
100
 
                                          bool sign)
 
83
void Field_new_decimal::set_value_on_overflow(my_decimal *decimal_value,
 
84
                                              bool sign)
101
85
{
102
86
  max_my_decimal(decimal_value, precision, decimals());
103
87
  if (sign)
117
101
  @param decimal_value   my_decimal
118
102
 
119
103
  @retval
120
 
  0 ok
 
104
    0 ok
121
105
  @retval
122
 
  1 error
 
106
    1 error
123
107
*/
124
108
 
125
 
bool Field_decimal::store_value(const my_decimal *decimal_value)
 
109
bool Field_new_decimal::store_value(const my_decimal *decimal_value)
126
110
{
127
111
  int error= 0;
128
112
 
138
122
}
139
123
 
140
124
 
141
 
int Field_decimal::store(const char *from, uint32_t length,
142
 
                         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)
143
127
{
144
128
  int err;
145
129
  my_decimal decimal_value;
146
130
 
147
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
148
 
 
149
131
  if ((err= str2my_decimal(E_DEC_FATAL_ERROR &
150
132
                           ~(E_DEC_OVERFLOW | E_DEC_BAD_NUM),
151
133
                           from, length, charset_arg,
180
162
      String from_as_str;
181
163
      from_as_str.copy(from, length, &my_charset_bin);
182
164
 
183
 
      push_warning_printf(table->in_use, DRIZZLE_ERROR::WARN_LEVEL_WARN,
184
 
                          ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
185
 
                          ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
 
165
    push_warning_printf(table->in_use, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
166
                        ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
 
167
                        ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
186
168
                          "decimal", from_as_str.c_ptr(), field_name,
187
 
                          (uint32_t) table->in_use->row_count);
188
 
      my_decimal_set_zero(&decimal_value);
 
169
                        (uint32_t) table->in_use->row_count);
 
170
    my_decimal_set_zero(&decimal_value);
189
171
 
190
 
      break;
 
172
    break;
191
173
    }
192
174
  }
193
175
 
202
184
  will return E_DEC_TRUNCATED always correctly
203
185
*/
204
186
 
205
 
int Field_decimal::store(double nr)
 
187
int Field_new_decimal::store(double nr)
206
188
{
207
189
  my_decimal decimal_value;
208
190
  int err;
209
191
 
210
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
211
 
 
212
192
  err= double2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, nr,
213
193
                         &decimal_value);
214
194
  if (err)
226
206
}
227
207
 
228
208
 
229
 
int Field_decimal::store(int64_t nr, bool unsigned_val)
 
209
int Field_new_decimal::store(int64_t nr, bool unsigned_val)
230
210
{
231
211
  my_decimal decimal_value;
232
212
  int err;
233
213
 
234
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
235
 
 
236
214
  if ((err= int2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
237
215
                           nr, unsigned_val, &decimal_value)))
238
216
  {
249
227
}
250
228
 
251
229
 
252
 
int Field_decimal::store_decimal(const my_decimal *decimal_value)
 
230
int Field_new_decimal::store_decimal(const my_decimal *decimal_value)
253
231
{
254
232
  return store_value(decimal_value);
255
233
}
256
234
 
257
235
 
258
 
int Field_decimal::store_time(DRIZZLE_TIME *ltime,
259
 
                              enum enum_drizzle_timestamp_type )
 
236
int Field_new_decimal::store_time(DRIZZLE_TIME *ltime,
 
237
                                  enum enum_drizzle_timestamp_type )
260
238
{
261
 
  my_decimal decimal_value;
262
 
  return store_value(date2my_decimal(ltime, &decimal_value));
 
239
    my_decimal decimal_value;
 
240
    return store_value(date2my_decimal(ltime, &decimal_value));
263
241
}
264
242
 
265
243
 
266
 
double Field_decimal::val_real(void)
 
244
double Field_new_decimal::val_real(void)
267
245
{
268
246
  double dbl;
269
247
  my_decimal decimal_value;
270
 
 
271
 
  ASSERT_COLUMN_MARKED_FOR_READ;
272
 
 
273
248
  my_decimal2double(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), &dbl);
274
 
 
275
249
  return dbl;
276
250
}
277
251
 
278
252
 
279
 
int64_t Field_decimal::val_int(void)
 
253
int64_t Field_new_decimal::val_int(void)
280
254
{
281
255
  int64_t i;
282
256
  my_decimal decimal_value;
283
 
 
284
 
  ASSERT_COLUMN_MARKED_FOR_READ;
285
 
 
286
257
  my_decimal2int(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), false, &i);
287
 
 
288
258
  return i;
289
259
}
290
260
 
291
261
 
292
 
my_decimal* Field_decimal::val_decimal(my_decimal *decimal_value)
 
262
my_decimal* Field_new_decimal::val_decimal(my_decimal *decimal_value)
293
263
{
294
 
  ASSERT_COLUMN_MARKED_FOR_READ;
295
 
 
296
264
  binary2my_decimal(E_DEC_FATAL_ERROR, ptr, decimal_value,
297
265
                    precision, dec);
298
266
  return(decimal_value);
299
267
}
300
268
 
301
269
 
302
 
String *Field_decimal::val_str(String *val_buffer,
303
 
                               String *)
 
270
String *Field_new_decimal::val_str(String *val_buffer,
 
271
                                   String *)
304
272
{
305
273
  my_decimal decimal_value;
306
 
 
307
 
  ASSERT_COLUMN_MARKED_FOR_READ;
308
 
 
309
274
  uint32_t fixed_precision= decimal_precision ? precision : 0;
310
275
  my_decimal2string(E_DEC_FATAL_ERROR, val_decimal(&decimal_value),
311
276
                    fixed_precision, dec, '0', val_buffer);
313
278
}
314
279
 
315
280
 
316
 
int Field_decimal::cmp(const unsigned char *a,const unsigned char*b)
 
281
int Field_new_decimal::cmp(const unsigned char *a,const unsigned char*b)
317
282
{
318
283
  return memcmp(a, b, bin_size);
319
284
}
320
285
 
321
286
 
322
 
void Field_decimal::sort_string(unsigned char *buff,
323
 
                                uint32_t )
 
287
void Field_new_decimal::sort_string(unsigned char *buff,
 
288
                                    uint32_t )
324
289
{
325
290
  memcpy(buff, ptr, bin_size);
326
291
}
327
292
 
328
293
 
329
 
void Field_decimal::sql_type(String &str) const
 
294
void Field_new_decimal::sql_type(String &str) const
330
295
{
331
296
  const CHARSET_INFO * const cs= str.charset();
332
297
  str.length(cs->cset->snprintf(cs, (char*) str.ptr(), str.alloced_length(),
335
300
 
336
301
 
337
302
/**
338
 
  Returns the number of bytes field uses in row-based replication
339
 
  row packed size.
340
 
 
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.
344
 
 
345
 
  @param   field_metadata   Encoded size in field metadata
346
 
 
347
 
  @returns The size of the field based on the field metadata.
348
 
*/
349
 
uint32_t Field_decimal::pack_length_from_metadata(uint32_t field_metadata)
 
303
   Save the field metadata for new decimal fields.
 
304
 
 
305
   Saves the precision in the first byte and decimals() in the second
 
306
   byte of the field metadata array at index of *metadata_ptr and
 
307
   *(metadata_ptr + 1).
 
308
 
 
309
   @param   metadata_ptr   First byte of field metadata
 
310
 
 
311
   @returns number of bytes written to metadata_ptr
 
312
*/
 
313
int Field_new_decimal::do_save_field_metadata(unsigned char *metadata_ptr)
 
314
{
 
315
  *metadata_ptr= precision;
 
316
  *(metadata_ptr + 1)= decimals();
 
317
  return 2;
 
318
}
 
319
 
 
320
 
 
321
/**
 
322
   Returns the number of bytes field uses in row-based replication
 
323
   row packed size.
 
324
 
 
325
   This method is used in row-based replication to determine the number
 
326
   of bytes that the field consumes in the row record format. This is
 
327
   used to skip fields in the master that do not exist on the slave.
 
328
 
 
329
   @param   field_metadata   Encoded size in field metadata
 
330
 
 
331
   @returns The size of the field based on the field metadata.
 
332
*/
 
333
uint32_t Field_new_decimal::pack_length_from_metadata(uint32_t field_metadata)
350
334
{
351
335
  uint32_t const source_precision= (field_metadata >> 8U) & 0x00ff;
352
336
  uint32_t const source_decimal= field_metadata & 0x00ff;
353
337
  uint32_t const source_size= my_decimal_get_binary_size(source_precision,
354
 
                                                         source_decimal);
 
338
                                                     source_decimal);
355
339
  return (source_size);
356
340
}
357
341
 
358
342
 
359
 
uint32_t Field_decimal::is_equal(CreateField *new_field_ptr)
 
343
/**
 
344
   Check to see if field size is compatible with destination.
 
345
 
 
346
   This method is used in row-based replication to verify that the slave's
 
347
   field size is less than or equal to the master's field size. The
 
348
   encoded field metadata (from the master or source) is decoded and compared
 
349
   to the size of this field (the slave or destination).
 
350
 
 
351
   @param   field_metadata   Encoded size in field metadata
 
352
 
 
353
   @retval 0 if this field's size is < the source field's size
 
354
   @retval 1 if this field's size is >= the source field's size
 
355
*/
 
356
int Field_new_decimal::compatible_field_size(uint32_t field_metadata)
 
357
{
 
358
  int compatible= 0;
 
359
  uint32_t const source_precision= (field_metadata >> 8U) & 0x00ff;
 
360
  uint32_t const source_decimal= field_metadata & 0x00ff;
 
361
  uint32_t const source_size= my_decimal_get_binary_size(source_precision,
 
362
                                                     source_decimal);
 
363
  uint32_t const destination_size= row_pack_length();
 
364
  compatible= (source_size <= destination_size);
 
365
  if (compatible)
 
366
    compatible= (source_precision <= precision) &&
 
367
                (source_decimal <= decimals());
 
368
  return (compatible);
 
369
}
 
370
 
 
371
 
 
372
uint32_t Field_new_decimal::is_equal(CreateField *new_field_ptr)
360
373
{
361
374
  return ((new_field_ptr->sql_type == real_type()) &&
362
375
          ((new_field_ptr->flags & UNSIGNED_FLAG) ==
369
382
 
370
383
 
371
384
/**
372
 
  Unpack a decimal field from row data.
373
 
 
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.
376
 
 
377
 
  @param   to         Destination of the data
378
 
  @param   from       Source of the data
379
 
  @param   param_data Precision (upper) and decimal (lower) values
380
 
 
381
 
  @return  New pointer into memory based on from + length of the data
 
385
   Unpack a decimal field from row data.
 
386
 
 
387
   This method is used to unpack a decimal or numeric field from a master
 
388
   whose size of the field is less than that of the slave.
 
389
 
 
390
   @param   to         Destination of the data
 
391
   @param   from       Source of the data
 
392
   @param   param_data Precision (upper) and decimal (lower) values
 
393
 
 
394
   @return  New pointer into memory based on from + length of the data
382
395
*/
383
396
const unsigned char *
384
 
Field_decimal::unpack(unsigned char* to,
385
 
                      const unsigned char *from,
386
 
                      uint32_t param_data,
387
 
                      bool low_byte_first)
 
397
Field_new_decimal::unpack(unsigned char* to,
 
398
                          const unsigned char *from,
 
399
                          uint32_t param_data,
 
400
                          bool low_byte_first)
388
401
{
389
402
  if (param_data == 0)
390
403
    return Field::unpack(to, from, param_data, low_byte_first);
394
407
  uint32_t length=pack_length();
395
408
  uint32_t from_pack_len= my_decimal_get_binary_size(from_precision, from_decimal);
396
409
  uint32_t len= (param_data && (from_pack_len < length)) ?
397
 
    from_pack_len : length;
 
410
            from_pack_len : length;
398
411
  if ((from_pack_len && (from_pack_len < length)) ||
399
412
      (from_precision < precision) ||
400
413
      (from_decimal < decimals()))
409
422
    conv_dec.len= from_precision;
410
423
    conv_dec.buf= dec_buf;
411
424
    /*
412
 
Note: bin2decimal does not change the length of the field. So it is
413
 
just the first step the resizing operation. The second step does the
414
 
resizing using the precision and decimals from the slave.
 
425
      Note: bin2decimal does not change the length of the field. So it is
 
426
      just the first step the resizing operation. The second step does the
 
427
      resizing using the precision and decimals from the slave.
415
428
    */
416
429
    bin2decimal((unsigned char *)from, &conv_dec, from_precision, from_decimal);
417
430
    decimal2bin(&conv_dec, to, precision, decimals());
421
434
  return from+len;
422
435
}
423
436
 
424
 
} /* namespace drizzled */