~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/decimal.cc

  • Committer: Brian Aker
  • Date: 2009-01-24 09:43:35 UTC
  • Revision ID: brian@gir-3.local-20090124094335-6qdtvc35gl5fvivz
Adding in an example singe thread scheduler

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, 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, 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,
167
149
 
168
150
  switch (err) {
169
151
  case E_DEC_TRUNCATED:
170
 
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
171
 
    set_value_on_overflow(&decimal_value, decimal_value.sign());
 
152
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_NOTE, ER_WARN_DATA_TRUNCATED, 1);
172
153
    break;
173
154
  case E_DEC_OVERFLOW:
174
155
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
180
161
      String from_as_str;
181
162
      from_as_str.copy(from, length, &my_charset_bin);
182
163
 
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),
 
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),
186
167
                          "decimal", from_as_str.c_ptr(), field_name,
187
 
                          (uint32_t) table->in_use->row_count);
188
 
      my_decimal_set_zero(&decimal_value);
 
168
                        (uint32_t) table->in_use->row_count);
 
169
    my_decimal_set_zero(&decimal_value);
189
170
 
190
 
      break;
 
171
    break;
191
172
    }
192
173
  }
193
174
 
202
183
  will return E_DEC_TRUNCATED always correctly
203
184
*/
204
185
 
205
 
int Field_decimal::store(double nr)
 
186
int Field_new_decimal::store(double nr)
206
187
{
207
188
  my_decimal decimal_value;
208
189
  int err;
209
190
 
210
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
211
 
 
212
191
  err= double2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, nr,
213
192
                         &decimal_value);
214
193
  if (err)
226
205
}
227
206
 
228
207
 
229
 
int Field_decimal::store(int64_t nr, bool unsigned_val)
 
208
int Field_new_decimal::store(int64_t nr, bool unsigned_val)
230
209
{
231
210
  my_decimal decimal_value;
232
211
  int err;
233
212
 
234
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
235
 
 
236
213
  if ((err= int2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
237
214
                           nr, unsigned_val, &decimal_value)))
238
215
  {
249
226
}
250
227
 
251
228
 
252
 
int Field_decimal::store_decimal(const my_decimal *decimal_value)
 
229
int Field_new_decimal::store_decimal(const my_decimal *decimal_value)
253
230
{
254
231
  return store_value(decimal_value);
255
232
}
256
233
 
257
234
 
258
 
int Field_decimal::store_time(DRIZZLE_TIME *ltime,
259
 
                              enum enum_drizzle_timestamp_type )
 
235
int Field_new_decimal::store_time(DRIZZLE_TIME *ltime,
 
236
                                  enum enum_drizzle_timestamp_type t_type __attribute__((unused)))
260
237
{
261
 
  my_decimal decimal_value;
262
 
  return store_value(date2my_decimal(ltime, &decimal_value));
 
238
    my_decimal decimal_value;
 
239
    return store_value(date2my_decimal(ltime, &decimal_value));
263
240
}
264
241
 
265
242
 
266
 
double Field_decimal::val_real(void)
 
243
double Field_new_decimal::val_real(void)
267
244
{
268
245
  double dbl;
269
246
  my_decimal decimal_value;
270
 
 
271
 
  ASSERT_COLUMN_MARKED_FOR_READ;
272
 
 
273
247
  my_decimal2double(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), &dbl);
274
 
 
275
248
  return dbl;
276
249
}
277
250
 
278
251
 
279
 
int64_t Field_decimal::val_int(void)
 
252
int64_t Field_new_decimal::val_int(void)
280
253
{
281
254
  int64_t i;
282
255
  my_decimal decimal_value;
283
 
 
284
 
  ASSERT_COLUMN_MARKED_FOR_READ;
285
 
 
286
256
  my_decimal2int(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), false, &i);
287
 
 
288
257
  return i;
289
258
}
290
259
 
291
260
 
292
 
my_decimal* Field_decimal::val_decimal(my_decimal *decimal_value)
 
261
my_decimal* Field_new_decimal::val_decimal(my_decimal *decimal_value)
293
262
{
294
 
  ASSERT_COLUMN_MARKED_FOR_READ;
295
 
 
296
263
  binary2my_decimal(E_DEC_FATAL_ERROR, ptr, decimal_value,
297
264
                    precision, dec);
298
265
  return(decimal_value);
299
266
}
300
267
 
301
268
 
302
 
String *Field_decimal::val_str(String *val_buffer,
303
 
                               String *)
 
269
String *Field_new_decimal::val_str(String *val_buffer,
 
270
                                   String *val_ptr __attribute__((unused)))
304
271
{
305
272
  my_decimal decimal_value;
306
 
 
307
 
  ASSERT_COLUMN_MARKED_FOR_READ;
308
 
 
309
273
  uint32_t fixed_precision= decimal_precision ? precision : 0;
310
274
  my_decimal2string(E_DEC_FATAL_ERROR, val_decimal(&decimal_value),
311
275
                    fixed_precision, dec, '0', val_buffer);
313
277
}
314
278
 
315
279
 
316
 
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)
317
281
{
318
282
  return memcmp(a, b, bin_size);
319
283
}
320
284
 
321
285
 
322
 
void Field_decimal::sort_string(unsigned char *buff,
323
 
                                uint32_t )
 
286
void Field_new_decimal::sort_string(unsigned char *buff,
 
287
                                    uint32_t length __attribute__((unused)))
324
288
{
325
289
  memcpy(buff, ptr, bin_size);
326
290
}
327
291
 
328
292
 
329
 
void Field_decimal::sql_type(String &str) const
 
293
void Field_new_decimal::sql_type(String &str) const
330
294
{
331
295
  const CHARSET_INFO * const cs= str.charset();
332
296
  str.length(cs->cset->snprintf(cs, (char*) str.ptr(), str.alloced_length(),
335
299
 
336
300
 
337
301
/**
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)
 
302
   Save the field metadata for new decimal fields.
 
303
 
 
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
 
306
   *(metadata_ptr + 1).
 
307
 
 
308
   @param   metadata_ptr   First byte of field metadata
 
309
 
 
310
   @returns number of bytes written to metadata_ptr
 
311
*/
 
312
int Field_new_decimal::do_save_field_metadata(unsigned char *metadata_ptr)
 
313
{
 
314
  *metadata_ptr= precision;
 
315
  *(metadata_ptr + 1)= decimals();
 
316
  return 2;
 
317
}
 
318
 
 
319
 
 
320
/**
 
321
   Returns the number of bytes field uses in row-based replication
 
322
   row packed size.
 
323
 
 
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.
 
327
 
 
328
   @param   field_metadata   Encoded size in field metadata
 
329
 
 
330
   @returns The size of the field based on the field metadata.
 
331
*/
 
332
uint32_t Field_new_decimal::pack_length_from_metadata(uint32_t field_metadata)
350
333
{
351
334
  uint32_t const source_precision= (field_metadata >> 8U) & 0x00ff;
352
335
  uint32_t const source_decimal= field_metadata & 0x00ff;
353
336
  uint32_t const source_size= my_decimal_get_binary_size(source_precision,
354
 
                                                         source_decimal);
 
337
                                                     source_decimal);
355
338
  return (source_size);
356
339
}
357
340
 
358
341
 
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
 
342
/**
 
343
   Check to see if field size is compatible with destination.
 
344
 
 
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).
 
349
 
 
350
   @param   field_metadata   Encoded size in field metadata
 
351
 
 
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
 
354
*/
 
355
int Field_new_decimal::compatible_field_size(uint32_t field_metadata)
 
356
{
 
357
  int compatible= 0;
 
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,
 
361
                                                     source_decimal);
 
362
  uint32_t const destination_size= row_pack_length();
 
363
  compatible= (source_size <= destination_size);
 
364
  if (compatible)
 
365
    compatible= (source_precision <= precision) &&
 
366
                (source_decimal <= decimals());
 
367
  return (compatible);
 
368
}
 
369
 
 
370
 
 
371
uint32_t Field_new_decimal::is_equal(Create_field *new_field)
 
372
{
 
373
  return ((new_field->sql_type == real_type()) &&
 
374
          ((new_field->flags & UNSIGNED_FLAG) ==
 
375
           (uint) (flags & UNSIGNED_FLAG)) &&
 
376
          ((new_field->flags & AUTO_INCREMENT_FLAG) ==
 
377
           (uint) (flags & AUTO_INCREMENT_FLAG)) &&
 
378
          (new_field->length == max_display_length()) &&
 
379
          (new_field->decimals == dec));
 
380
}
 
381
 
 
382
 
 
383
/**
 
384
   Unpack a decimal field from row data.
 
385
 
 
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.
 
388
 
 
389
   @param   to         Destination of the data
 
390
   @param   from       Source of the data
 
391
   @param   param_data Precision (upper) and decimal (lower) values
 
392
 
 
393
   @return  New pointer into memory based on from + length of the data
382
394
*/
383
395
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)
 
396
Field_new_decimal::unpack(unsigned char* to,
 
397
                          const unsigned char *from,
 
398
                          uint32_t param_data,
 
399
                          bool low_byte_first)
388
400
{
389
401
  if (param_data == 0)
390
402
    return Field::unpack(to, from, param_data, low_byte_first);
394
406
  uint32_t length=pack_length();
395
407
  uint32_t from_pack_len= my_decimal_get_binary_size(from_precision, from_decimal);
396
408
  uint32_t len= (param_data && (from_pack_len < length)) ?
397
 
    from_pack_len : length;
 
409
            from_pack_len : length;
398
410
  if ((from_pack_len && (from_pack_len < length)) ||
399
411
      (from_precision < precision) ||
400
412
      (from_decimal < decimals()))
405
417
      a decimal and write that to the raw data buffer.
406
418
    */
407
419
    decimal_digit_t dec_buf[DECIMAL_MAX_PRECISION];
408
 
    decimal_t conv_dec;
409
 
    conv_dec.len= from_precision;
410
 
    conv_dec.buf= dec_buf;
 
420
    decimal_t dec;
 
421
    dec.len= from_precision;
 
422
    dec.buf= dec_buf;
411
423
    /*
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.
 
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.
415
427
    */
416
 
    bin2decimal((unsigned char *)from, &conv_dec, from_precision, from_decimal);
417
 
    decimal2bin(&conv_dec, to, precision, decimals());
 
428
    bin2decimal((unsigned char *)from, &dec, from_precision, from_decimal);
 
429
    decimal2bin(&dec, to, precision, decimals());
418
430
  }
419
431
  else
420
432
    memcpy(to, from, len); // Sizes are the same, just copy the data.
421
433
  return from+len;
422
434
}
423
435
 
424
 
} /* namespace drizzled */