~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/decimal.cc

  • Committer: Eric Day
  • Date: 2009-11-10 21:50:22 UTC
  • mto: This revision was merged to the branch mainline in revision 1218.
  • Revision ID: eday@oddments.org-20091110215022-0b2nqmurv7b2l6wo
Duplicated oldlibdrizzle module, one for Drizzle protocol and one for MySQL, per Brian's request from merge proposal. Port options are now --drizzle-protocol-port and --mysql-protocol-port.

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,
 
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)
86
83
{
87
84
  store_value(&decimal_zero);
88
85
  return 0;
96
93
  @param sign              sign of value which caused overflow
97
94
*/
98
95
 
99
 
void Field_decimal::set_value_on_overflow(my_decimal *decimal_value,
100
 
                                          bool sign)
 
96
void Field_new_decimal::set_value_on_overflow(my_decimal *decimal_value,
 
97
                                              bool sign)
101
98
{
102
99
  max_my_decimal(decimal_value, precision, decimals());
103
100
  if (sign)
117
114
  @param decimal_value   my_decimal
118
115
 
119
116
  @retval
120
 
  0 ok
 
117
    0 ok
121
118
  @retval
122
 
  1 error
 
119
    1 error
123
120
*/
124
121
 
125
 
bool Field_decimal::store_value(const my_decimal *decimal_value)
 
122
bool Field_new_decimal::store_value(const my_decimal *decimal_value)
126
123
{
127
 
  int error= my_decimal2binary(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
128
 
                                         decimal_value, ptr, precision, dec);
129
 
  if (warn_if_overflow(error))
 
124
  int error= 0;
 
125
 
 
126
  if (warn_if_overflow(my_decimal2binary(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
 
127
                                         decimal_value, ptr, precision, dec)))
130
128
  {
131
 
    if (error != E_DEC_TRUNCATED)
132
 
    {
133
 
      my_decimal buff;
134
 
      set_value_on_overflow(&buff, decimal_value->sign());
135
 
      my_decimal2binary(E_DEC_FATAL_ERROR, &buff, ptr, precision, dec);
136
 
    }
 
129
    my_decimal buff;
 
130
    set_value_on_overflow(&buff, decimal_value->sign());
 
131
    my_decimal2binary(E_DEC_FATAL_ERROR, &buff, ptr, precision, dec);
137
132
    error= 1;
138
133
  }
139
134
  return(error);
140
135
}
141
136
 
142
137
 
143
 
int Field_decimal::store(const char *from, uint32_t length,
144
 
                         const CHARSET_INFO * const charset_arg)
 
138
int Field_new_decimal::store(const char *from, uint32_t length,
 
139
                             const CHARSET_INFO * const charset_arg)
145
140
{
146
141
  int err;
147
142
  my_decimal decimal_value;
152
147
                           ~(E_DEC_OVERFLOW | E_DEC_BAD_NUM),
153
148
                           from, length, charset_arg,
154
149
                           &decimal_value)) &&
155
 
      getTable()->in_use->abort_on_warning)
 
150
      table->in_use->abort_on_warning)
156
151
  {
157
152
    /* Because "from" is not NUL-terminated and we use %s in the ER() */
158
153
    String from_as_str;
159
154
    from_as_str.copy(from, length, &my_charset_bin);
160
155
 
161
 
    push_warning_printf(getTable()->in_use, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
156
    push_warning_printf(table->in_use, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
162
157
                        ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
163
158
                        ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
164
159
                        "decimal", from_as_str.c_ptr(), field_name,
165
 
                        (uint32_t) getTable()->in_use->row_count);
 
160
                        (uint32_t) table->in_use->row_count);
166
161
 
167
162
    return(err);
168
163
  }
182
177
      String from_as_str;
183
178
      from_as_str.copy(from, length, &my_charset_bin);
184
179
 
185
 
      push_warning_printf(getTable()->in_use, DRIZZLE_ERROR::WARN_LEVEL_WARN,
186
 
                          ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
187
 
                          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),
188
183
                          "decimal", from_as_str.c_ptr(), field_name,
189
 
                          (uint32_t) getTable()->in_use->row_count);
190
 
      my_decimal_set_zero(&decimal_value);
 
184
                        (uint32_t) table->in_use->row_count);
 
185
    my_decimal_set_zero(&decimal_value);
191
186
 
192
 
      break;
 
187
    break;
193
188
    }
194
189
  }
195
190
 
204
199
  will return E_DEC_TRUNCATED always correctly
205
200
*/
206
201
 
207
 
int Field_decimal::store(double nr)
 
202
int Field_new_decimal::store(double nr)
208
203
{
209
204
  my_decimal decimal_value;
210
205
  int err;
218
213
    if (check_overflow(err))
219
214
      set_value_on_overflow(&decimal_value, decimal_value.sign());
220
215
    /* Only issue a warning if store_value doesn't issue an warning */
221
 
    getTable()->in_use->got_warning= 0;
 
216
    table->in_use->got_warning= 0;
222
217
  }
223
218
  if (store_value(&decimal_value))
224
219
    err= 1;
225
 
  else if (err && !getTable()->in_use->got_warning)
 
220
  else if (err && !table->in_use->got_warning)
226
221
    err= warn_if_overflow(err);
227
222
  return(err);
228
223
}
229
224
 
230
225
 
231
 
int Field_decimal::store(int64_t nr, bool unsigned_val)
 
226
int Field_new_decimal::store(int64_t nr, bool unsigned_val)
232
227
{
233
228
  my_decimal decimal_value;
234
229
  int err;
241
236
    if (check_overflow(err))
242
237
      set_value_on_overflow(&decimal_value, decimal_value.sign());
243
238
    /* Only issue a warning if store_value doesn't issue an warning */
244
 
    getTable()->in_use->got_warning= 0;
 
239
    table->in_use->got_warning= 0;
245
240
  }
246
241
  if (store_value(&decimal_value))
247
242
    err= 1;
248
 
  else if (err && not getTable()->in_use->got_warning)
 
243
  else if (err && !table->in_use->got_warning)
249
244
    err= warn_if_overflow(err);
250
245
  return err;
251
246
}
252
247
 
253
248
 
254
 
int Field_decimal::store_decimal(const my_decimal *decimal_value)
 
249
int Field_new_decimal::store_decimal(const my_decimal *decimal_value)
255
250
{
256
251
  return store_value(decimal_value);
257
252
}
258
253
 
259
254
 
260
 
int Field_decimal::store_time(DRIZZLE_TIME *ltime,
261
 
                              enum enum_drizzle_timestamp_type )
 
255
int Field_new_decimal::store_time(DRIZZLE_TIME *ltime,
 
256
                                  enum enum_drizzle_timestamp_type )
262
257
{
263
 
  my_decimal decimal_value;
264
 
  return store_value(date2my_decimal(ltime, &decimal_value));
 
258
    my_decimal decimal_value;
 
259
    return store_value(date2my_decimal(ltime, &decimal_value));
265
260
}
266
261
 
267
262
 
268
 
double Field_decimal::val_real(void)
 
263
double Field_new_decimal::val_real(void)
269
264
{
270
265
  double dbl;
271
266
  my_decimal decimal_value;
278
273
}
279
274
 
280
275
 
281
 
int64_t Field_decimal::val_int(void)
 
276
int64_t Field_new_decimal::val_int(void)
282
277
{
283
278
  int64_t i;
284
279
  my_decimal decimal_value;
291
286
}
292
287
 
293
288
 
294
 
my_decimal* Field_decimal::val_decimal(my_decimal *decimal_value)
 
289
my_decimal* Field_new_decimal::val_decimal(my_decimal *decimal_value)
295
290
{
296
291
  ASSERT_COLUMN_MARKED_FOR_READ;
297
292
 
301
296
}
302
297
 
303
298
 
304
 
String *Field_decimal::val_str(String *val_buffer,
305
 
                               String *)
 
299
String *Field_new_decimal::val_str(String *val_buffer,
 
300
                                   String *)
306
301
{
307
302
  my_decimal decimal_value;
308
303
 
315
310
}
316
311
 
317
312
 
318
 
int Field_decimal::cmp(const unsigned char *a,const unsigned char*b)
 
313
int Field_new_decimal::cmp(const unsigned char *a,const unsigned char*b)
319
314
{
320
315
  return memcmp(a, b, bin_size);
321
316
}
322
317
 
323
318
 
324
 
void Field_decimal::sort_string(unsigned char *buff,
325
 
                                uint32_t )
 
319
void Field_new_decimal::sort_string(unsigned char *buff,
 
320
                                    uint32_t )
326
321
{
327
322
  memcpy(buff, ptr, bin_size);
328
323
}
329
324
 
330
325
 
331
 
void Field_decimal::sql_type(String &str) const
 
326
void Field_new_decimal::sql_type(String &str) const
332
327
{
333
328
  const CHARSET_INFO * const cs= str.charset();
334
329
  str.length(cs->cset->snprintf(cs, (char*) str.ptr(), str.alloced_length(),
337
332
 
338
333
 
339
334
/**
340
 
  Returns the number of bytes field uses in row-based replication
341
 
  row packed size.
342
 
 
343
 
  This method is used in row-based replication to determine the number
344
 
  of bytes that the field consumes in the row record format. This is
345
 
  used to skip fields in the master that do not exist on the slave.
346
 
 
347
 
  @param   field_metadata   Encoded size in field metadata
348
 
 
349
 
  @returns The size of the field based on the field metadata.
350
 
*/
351
 
uint32_t Field_decimal::pack_length_from_metadata(uint32_t field_metadata)
 
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
*/
 
345
int Field_new_decimal::do_save_field_metadata(unsigned char *metadata_ptr)
 
346
{
 
347
  *metadata_ptr= precision;
 
348
  *(metadata_ptr + 1)= decimals();
 
349
  return 2;
 
350
}
 
351
 
 
352
 
 
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.
 
364
*/
 
365
uint32_t Field_new_decimal::pack_length_from_metadata(uint32_t field_metadata)
352
366
{
353
367
  uint32_t const source_precision= (field_metadata >> 8U) & 0x00ff;
354
368
  uint32_t const source_decimal= field_metadata & 0x00ff;
355
369
  uint32_t const source_size= my_decimal_get_binary_size(source_precision,
356
 
                                                         source_decimal);
 
370
                                                     source_decimal);
357
371
  return (source_size);
358
372
}
359
373
 
360
374
 
361
 
uint32_t Field_decimal::is_equal(CreateField *new_field_ptr)
 
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
 
387
*/
 
388
int Field_new_decimal::compatible_field_size(uint32_t field_metadata)
 
389
{
 
390
  int compatible= 0;
 
391
  uint32_t const source_precision= (field_metadata >> 8U) & 0x00ff;
 
392
  uint32_t const source_decimal= field_metadata & 0x00ff;
 
393
  uint32_t const source_size= my_decimal_get_binary_size(source_precision,
 
394
                                                     source_decimal);
 
395
  uint32_t const destination_size= row_pack_length();
 
396
  compatible= (source_size <= destination_size);
 
397
  if (compatible)
 
398
    compatible= (source_precision <= precision) &&
 
399
                (source_decimal <= decimals());
 
400
  return (compatible);
 
401
}
 
402
 
 
403
 
 
404
uint32_t Field_new_decimal::is_equal(CreateField *new_field_ptr)
362
405
{
363
406
  return ((new_field_ptr->sql_type == real_type()) &&
364
407
          ((new_field_ptr->flags & UNSIGNED_FLAG) ==
371
414
 
372
415
 
373
416
/**
374
 
  Unpack a decimal field from row data.
375
 
 
376
 
  This method is used to unpack a decimal or numeric field from a master
377
 
  whose size of the field is less than that of the slave.
378
 
 
379
 
  @param   to         Destination of the data
380
 
  @param   from       Source of the data
381
 
  @param   param_data Precision (upper) and decimal (lower) values
382
 
 
383
 
  @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
384
427
*/
385
428
const unsigned char *
386
 
Field_decimal::unpack(unsigned char* to,
387
 
                      const unsigned char *from,
388
 
                      uint32_t param_data,
389
 
                      bool low_byte_first)
 
429
Field_new_decimal::unpack(unsigned char* to,
 
430
                          const unsigned char *from,
 
431
                          uint32_t param_data,
 
432
                          bool low_byte_first)
390
433
{
391
434
  if (param_data == 0)
392
435
    return Field::unpack(to, from, param_data, low_byte_first);
396
439
  uint32_t length=pack_length();
397
440
  uint32_t from_pack_len= my_decimal_get_binary_size(from_precision, from_decimal);
398
441
  uint32_t len= (param_data && (from_pack_len < length)) ?
399
 
    from_pack_len : length;
 
442
            from_pack_len : length;
400
443
  if ((from_pack_len && (from_pack_len < length)) ||
401
444
      (from_precision < precision) ||
402
445
      (from_decimal < decimals()))
411
454
    conv_dec.len= from_precision;
412
455
    conv_dec.buf= dec_buf;
413
456
    /*
414
 
Note: bin2decimal does not change the length of the field. So it is
415
 
just the first step the resizing operation. The second step does the
416
 
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.
417
460
    */
418
461
    bin2decimal((unsigned char *)from, &conv_dec, from_precision, from_decimal);
419
462
    decimal2bin(&conv_dec, to, precision, decimals());
423
466
  return from+len;
424
467
}
425
468
 
426
 
} /* namespace drizzled */