~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/decimal.cc

  • Committer: Brian Aker
  • Date: 2010-05-27 01:25:56 UTC
  • mfrom: (1567.1.4 new-staging)
  • Revision ID: brian@gaz-20100527012556-5zgkirkl7swbigd6
Merge of Brian, Paul. PBXT compile issue, and test framework cleanup. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
1
/* - mode: c++ c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
4
 *  Copyright (C) 2008 MySQL
18
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
19
 */
20
20
 
21
 
#ifdef USE_PRAGMA_IMPLEMENTATION
22
 
#pragma implementation                          // gcc: Class implementation
23
 
#endif
24
 
 
25
 
#include <drizzled/server_includes.h>
26
 
#include <drizzled/field/fdecimal.h>
27
 
#include <drizzled/drizzled_error_messages.h>
28
 
 
 
21
 
 
22
#include "config.h"
 
23
#include <drizzled/field/decimal.h>
 
24
#include <drizzled/error.h>
 
25
#include <drizzled/table.h>
 
26
#include <drizzled/session.h>
 
27
 
 
28
namespace drizzled
 
29
{
 
30
 
 
31
extern my_decimal decimal_zero;
29
32
 
30
33
/****************************************************************************
31
 
** Field_new_decimal
32
 
****************************************************************************/
33
 
 
34
 
Field_new_decimal::Field_new_decimal(uchar *ptr_arg,
35
 
                                     uint32_t len_arg, uchar *null_ptr_arg,
36
 
                                     uchar 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, 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((uchar*) 0, len_arg,
58
 
             maybe_null_arg ? (uchar*) "": 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, 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)
 
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)
70
86
{
71
87
  store_value(&decimal_zero);
72
88
  return 0;
80
96
  @param sign              sign of value which caused overflow
81
97
*/
82
98
 
83
 
void Field_new_decimal::set_value_on_overflow(my_decimal *decimal_value,
84
 
                                              bool sign)
 
99
void Field_decimal::set_value_on_overflow(my_decimal *decimal_value,
 
100
                                          bool sign)
85
101
{
86
102
  max_my_decimal(decimal_value, precision, decimals());
87
103
  if (sign)
88
 
  {
89
 
    if (unsigned_flag)
90
 
      my_decimal_set_zero(decimal_value);
91
 
    else
92
 
      decimal_value->sign(true);
93
 
  }
 
104
    decimal_value->sign(true);
 
105
 
94
106
  return;
95
107
}
96
108
 
105
117
  @param decimal_value   my_decimal
106
118
 
107
119
  @retval
108
 
    0 ok
 
120
  0 ok
109
121
  @retval
110
 
    1 error
 
122
  1 error
111
123
*/
112
124
 
113
 
bool Field_new_decimal::store_value(const my_decimal *decimal_value)
 
125
bool Field_decimal::store_value(const my_decimal *decimal_value)
114
126
{
115
127
  int error= 0;
116
128
 
117
 
  /* check that we do not try to write negative value in unsigned field */
118
 
  if (unsigned_flag && decimal_value->sign())
119
 
  {
120
 
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
121
 
    error= 1;
122
 
    decimal_value= &decimal_zero;
123
 
  }
124
 
 
125
129
  if (warn_if_overflow(my_decimal2binary(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
126
130
                                         decimal_value, ptr, precision, dec)))
127
131
  {
134
138
}
135
139
 
136
140
 
137
 
int Field_new_decimal::store(const char *from, uint length,
138
 
                             const CHARSET_INFO * const charset_arg)
 
141
int Field_decimal::store(const char *from, uint32_t length,
 
142
                         const CHARSET_INFO * const charset_arg)
139
143
{
140
144
  int err;
141
145
  my_decimal decimal_value;
142
146
 
 
147
  ASSERT_COLUMN_MARKED_FOR_WRITE;
 
148
 
143
149
  if ((err= str2my_decimal(E_DEC_FATAL_ERROR &
144
150
                           ~(E_DEC_OVERFLOW | E_DEC_BAD_NUM),
145
151
                           from, length, charset_arg,
161
167
 
162
168
  switch (err) {
163
169
  case E_DEC_TRUNCATED:
164
 
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_NOTE, ER_WARN_DATA_TRUNCATED, 1);
 
170
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
 
171
    set_value_on_overflow(&decimal_value, decimal_value.sign());
165
172
    break;
166
173
  case E_DEC_OVERFLOW:
167
174
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
173
180
      String from_as_str;
174
181
      from_as_str.copy(from, length, &my_charset_bin);
175
182
 
176
 
    push_warning_printf(table->in_use, DRIZZLE_ERROR::WARN_LEVEL_WARN,
177
 
                        ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
178
 
                        ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
 
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),
179
186
                          "decimal", from_as_str.c_ptr(), field_name,
180
 
                        (uint32_t) table->in_use->row_count);
181
 
    my_decimal_set_zero(&decimal_value);
 
187
                          (uint32_t) table->in_use->row_count);
 
188
      my_decimal_set_zero(&decimal_value);
182
189
 
183
 
    break;
 
190
      break;
184
191
    }
185
192
  }
186
193
 
195
202
  will return E_DEC_TRUNCATED always correctly
196
203
*/
197
204
 
198
 
int Field_new_decimal::store(double nr)
 
205
int Field_decimal::store(double nr)
199
206
{
200
207
  my_decimal decimal_value;
201
208
  int err;
202
209
 
 
210
  ASSERT_COLUMN_MARKED_FOR_WRITE;
 
211
 
203
212
  err= double2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, nr,
204
213
                         &decimal_value);
205
214
  if (err)
217
226
}
218
227
 
219
228
 
220
 
int Field_new_decimal::store(int64_t nr, bool unsigned_val)
 
229
int Field_decimal::store(int64_t nr, bool unsigned_val)
221
230
{
222
231
  my_decimal decimal_value;
223
232
  int err;
224
233
 
 
234
  ASSERT_COLUMN_MARKED_FOR_WRITE;
 
235
 
225
236
  if ((err= int2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
226
237
                           nr, unsigned_val, &decimal_value)))
227
238
  {
238
249
}
239
250
 
240
251
 
241
 
int Field_new_decimal::store_decimal(const my_decimal *decimal_value)
 
252
int Field_decimal::store_decimal(const my_decimal *decimal_value)
242
253
{
243
254
  return store_value(decimal_value);
244
255
}
245
256
 
246
257
 
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 )
249
260
{
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));
252
263
}
253
264
 
254
265
 
255
 
double Field_new_decimal::val_real(void)
 
266
double Field_decimal::val_real(void)
256
267
{
257
268
  double dbl;
258
269
  my_decimal decimal_value;
 
270
 
 
271
  ASSERT_COLUMN_MARKED_FOR_READ;
 
272
 
259
273
  my_decimal2double(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), &dbl);
 
274
 
260
275
  return dbl;
261
276
}
262
277
 
263
278
 
264
 
int64_t Field_new_decimal::val_int(void)
 
279
int64_t Field_decimal::val_int(void)
265
280
{
266
281
  int64_t i;
267
282
  my_decimal decimal_value;
268
 
  my_decimal2int(E_DEC_FATAL_ERROR, val_decimal(&decimal_value),
269
 
                 unsigned_flag, &i);
 
283
 
 
284
  ASSERT_COLUMN_MARKED_FOR_READ;
 
285
 
 
286
  my_decimal2int(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), false, &i);
 
287
 
270
288
  return i;
271
289
}
272
290
 
273
291
 
274
 
my_decimal* Field_new_decimal::val_decimal(my_decimal *decimal_value)
 
292
my_decimal* Field_decimal::val_decimal(my_decimal *decimal_value)
275
293
{
 
294
  ASSERT_COLUMN_MARKED_FOR_READ;
 
295
 
276
296
  binary2my_decimal(E_DEC_FATAL_ERROR, ptr, decimal_value,
277
297
                    precision, dec);
278
298
  return(decimal_value);
279
299
}
280
300
 
281
301
 
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,
 
303
                               String *)
284
304
{
285
305
  my_decimal decimal_value;
286
 
  uint fixed_precision= decimal_precision ? precision : 0;
 
306
 
 
307
  ASSERT_COLUMN_MARKED_FOR_READ;
 
308
 
 
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;
290
313
}
291
314
 
292
315
 
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)
294
317
{
295
318
  return memcmp(a, b, bin_size);
296
319
}
297
320
 
298
321
 
299
 
void Field_new_decimal::sort_string(uchar *buff,
300
 
                                    uint length __attribute__((unused)))
 
322
void Field_decimal::sort_string(unsigned char *buff,
 
323
                                uint32_t )
301
324
{
302
325
  memcpy(buff, ptr, bin_size);
303
326
}
304
327
 
305
328
 
306
 
void Field_new_decimal::sql_type(String &str) const
 
329
void Field_decimal::sql_type(String &str) const
307
330
{
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));
311
 
  add_unsigned(str);
312
 
}
313
 
 
314
 
 
315
 
/**
316
 
   Save the field metadata for new decimal fields.
317
 
 
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 
320
 
   *(metadata_ptr + 1).
321
 
 
322
 
   @param   metadata_ptr   First byte of field metadata
323
 
 
324
 
   @returns number of bytes written to metadata_ptr
325
 
*/
326
 
int Field_new_decimal::do_save_field_metadata(uchar *metadata_ptr)
327
 
{
328
 
  *metadata_ptr= precision;
329
 
  *(metadata_ptr + 1)= decimals();
330
 
  return 2;
331
 
}
332
 
 
333
 
 
334
 
/**
335
 
   Returns the number of bytes field uses in row-based replication 
336
 
   row packed size.
337
 
 
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.
341
 
 
342
 
   @param   field_metadata   Encoded size in field metadata
343
 
 
344
 
   @returns The size of the field based on the field metadata.
345
 
*/
346
 
uint Field_new_decimal::pack_length_from_metadata(uint field_metadata)
347
 
{
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, 
351
 
                                                     source_decimal);
 
334
}
 
335
 
 
336
 
 
337
/**
 
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)
 
350
{
 
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,
 
354
                                                         source_decimal);
352
355
  return (source_size);
353
356
}
354
357
 
355
358
 
356
 
/**
357
 
   Check to see if field size is compatible with destination.
358
 
 
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). 
363
 
 
364
 
   @param   field_metadata   Encoded size in field metadata
365
 
 
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
368
 
*/
369
 
int Field_new_decimal::compatible_field_size(uint field_metadata)
370
 
{
371
 
  int compatible= 0;
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, 
375
 
                                                     source_decimal);
376
 
  uint const destination_size= row_pack_length();
377
 
  compatible= (source_size <= destination_size);
378
 
  if (compatible)
379
 
    compatible= (source_precision <= precision) &&
380
 
                (source_decimal <= decimals());
381
 
  return (compatible);
382
 
}
383
 
 
384
 
 
385
 
uint Field_new_decimal::is_equal(Create_field *new_field)
386
 
{
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));
394
 
}
395
 
 
396
 
 
397
 
/**
398
 
   Unpack a decimal field from row data.
399
 
 
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.
402
 
  
403
 
   @param   to         Destination of the data
404
 
   @param   from       Source of the data
405
 
   @param   param_data Precision (upper) and decimal (lower) values
406
 
 
407
 
   @return  New pointer into memory based on from + length of the data
408
 
*/
409
 
const uchar *
410
 
Field_new_decimal::unpack(uchar* to,
411
 
                          const uchar *from,
412
 
                          uint param_data,
413
 
                          bool low_byte_first)
 
359
uint32_t Field_decimal::is_equal(CreateField *new_field_ptr)
 
360
{
 
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));
 
368
}
 
369
 
 
370
 
 
371
/**
 
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
 
382
*/
 
383
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)
414
388
{
415
389
  if (param_data == 0)
416
390
    return Field::unpack(to, from, param_data, low_byte_first);
417
391
 
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()))
431
405
      a decimal and write that to the raw data buffer.
432
406
    */
433
407
    decimal_digit_t dec_buf[DECIMAL_MAX_PRECISION];
434
 
    decimal_t dec;
435
 
    dec.len= from_precision;
436
 
    dec.buf= dec_buf;
 
408
    decimal_t conv_dec;
 
409
    conv_dec.len= from_precision;
 
410
    conv_dec.buf= dec_buf;
437
411
    /*
438
 
      Note: bin2decimal does not change the length of the field. So it is
439
 
      just the first step the resizing operation. The second step does the
440
 
      resizing using the precision and decimals from the slave.
 
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.
441
415
    */
442
 
    bin2decimal((uchar *)from, &dec, from_precision, from_decimal);
443
 
    decimal2bin(&dec, to, precision, decimals());
 
416
    bin2decimal((unsigned char *)from, &conv_dec, from_precision, from_decimal);
 
417
    decimal2bin(&conv_dec, to, precision, decimals());
444
418
  }
445
419
  else
446
420
    memcpy(to, from, len); // Sizes are the same, just copy the data.
447
421
  return from+len;
448
422
}
449
423
 
 
424
} /* namespace drizzled */