~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/decimal.cc

  • Committer: Brian Aker
  • Date: 2009-05-11 17:50:22 UTC
  • Revision ID: brian@gaz-20090511175022-y35q9ky6uh9ldcjt
Replacing Sun employee copyright headers (aka... anything done by a Sun
employee is copyright by Sun).

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
21
 
25
22
#include <drizzled/server_includes.h>
26
 
#include <drizzled/field/fdecimal.h>
27
 
#include <drizzled/drizzled_error_messages.h>
 
23
#include <drizzled/field/decimal.h>
 
24
#include <drizzled/error.h>
 
25
#include <drizzled/table.h>
 
26
#include <drizzled/session.h>
28
27
 
 
28
extern my_decimal decimal_zero;
29
29
 
30
30
/****************************************************************************
31
31
** Field_new_decimal
42
42
             unireg_check_arg, field_name_arg, dec_arg, zero_arg, unsigned_arg)
43
43
{
44
44
  precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
45
 
  set_if_smaller(precision, DECIMAL_MAX_PRECISION);
 
45
  set_if_smaller(precision, (uint32_t)DECIMAL_MAX_PRECISION);
46
46
  assert((precision <= DECIMAL_MAX_PRECISION) &&
47
47
              (dec <= DECIMAL_MAX_SCALE));
48
48
  bin_size= my_decimal_get_binary_size(precision, dec);
59
59
             NONE, name, dec_arg, 0, unsigned_arg)
60
60
{
61
61
  precision= my_decimal_length_to_precision(len_arg, dec_arg, unsigned_arg);
62
 
  set_if_smaller(precision, DECIMAL_MAX_PRECISION);
 
62
  set_if_smaller(precision, (uint32_t)DECIMAL_MAX_PRECISION);
63
63
  assert((precision <= DECIMAL_MAX_PRECISION) &&
64
64
              (dec <= DECIMAL_MAX_SCALE));
65
65
  bin_size= my_decimal_get_binary_size(precision, dec);
85
85
{
86
86
  max_my_decimal(decimal_value, precision, decimals());
87
87
  if (sign)
88
 
  {
89
 
    if (unsigned_flag)
90
 
      my_decimal_set_zero(decimal_value);
91
 
    else
92
 
      decimal_value->sign(true);
93
 
  }
 
88
    decimal_value->sign(true);
 
89
 
94
90
  return;
95
91
}
96
92
 
114
110
{
115
111
  int error= 0;
116
112
 
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
113
  if (warn_if_overflow(my_decimal2binary(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
126
114
                                         decimal_value, ptr, precision, dec)))
127
115
  {
161
149
 
162
150
  switch (err) {
163
151
  case E_DEC_TRUNCATED:
164
 
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_NOTE, ER_WARN_DATA_TRUNCATED, 1);
 
152
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
 
153
    set_value_on_overflow(&decimal_value, decimal_value.sign());
165
154
    break;
166
155
  case E_DEC_OVERFLOW:
167
156
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
245
234
 
246
235
 
247
236
int Field_new_decimal::store_time(DRIZZLE_TIME *ltime,
248
 
                                  enum enum_drizzle_timestamp_type t_type __attribute__((unused)))
 
237
                                  enum enum_drizzle_timestamp_type )
249
238
{
250
239
    my_decimal decimal_value;
251
240
    return store_value(date2my_decimal(ltime, &decimal_value));
265
254
{
266
255
  int64_t i;
267
256
  my_decimal decimal_value;
268
 
  my_decimal2int(E_DEC_FATAL_ERROR, val_decimal(&decimal_value),
269
 
                 unsigned_flag, &i);
 
257
  my_decimal2int(E_DEC_FATAL_ERROR, val_decimal(&decimal_value), false, &i);
270
258
  return i;
271
259
}
272
260
 
280
268
 
281
269
 
282
270
String *Field_new_decimal::val_str(String *val_buffer,
283
 
                                   String *val_ptr __attribute__((unused)))
 
271
                                   String *)
284
272
{
285
273
  my_decimal decimal_value;
286
274
  uint32_t fixed_precision= decimal_precision ? precision : 0;
297
285
 
298
286
 
299
287
void Field_new_decimal::sort_string(unsigned char *buff,
300
 
                                    uint32_t length __attribute__((unused)))
 
288
                                    uint32_t )
301
289
{
302
290
  memcpy(buff, ptr, bin_size);
303
291
}
308
296
  const CHARSET_INFO * const cs= str.charset();
309
297
  str.length(cs->cset->snprintf(cs, (char*) str.ptr(), str.alloced_length(),
310
298
                                "decimal(%d,%d)", precision, (int)dec));
311
 
  add_unsigned(str);
312
299
}
313
300
 
314
301
 
316
303
   Save the field metadata for new decimal fields.
317
304
 
318
305
   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 
 
306
   byte of the field metadata array at index of *metadata_ptr and
320
307
   *(metadata_ptr + 1).
321
308
 
322
309
   @param   metadata_ptr   First byte of field metadata
332
319
 
333
320
 
334
321
/**
335
 
   Returns the number of bytes field uses in row-based replication 
 
322
   Returns the number of bytes field uses in row-based replication
336
323
   row packed size.
337
324
 
338
325
   This method is used in row-based replication to determine the number
346
333
uint32_t Field_new_decimal::pack_length_from_metadata(uint32_t field_metadata)
347
334
{
348
335
  uint32_t const source_precision= (field_metadata >> 8U) & 0x00ff;
349
 
  uint32_t const source_decimal= field_metadata & 0x00ff; 
350
 
  uint32_t const source_size= my_decimal_get_binary_size(source_precision, 
 
336
  uint32_t const source_decimal= field_metadata & 0x00ff;
 
337
  uint32_t const source_size= my_decimal_get_binary_size(source_precision,
351
338
                                                     source_decimal);
352
339
  return (source_size);
353
340
}
357
344
   Check to see if field size is compatible with destination.
358
345
 
359
346
   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 
 
347
   field size is less than or equal to the master's field size. The
361
348
   encoded field metadata (from the master or source) is decoded and compared
362
 
   to the size of this field (the slave or destination). 
 
349
   to the size of this field (the slave or destination).
363
350
 
364
351
   @param   field_metadata   Encoded size in field metadata
365
352
 
370
357
{
371
358
  int compatible= 0;
372
359
  uint32_t const source_precision= (field_metadata >> 8U) & 0x00ff;
373
 
  uint32_t const source_decimal= field_metadata & 0x00ff; 
374
 
  uint32_t const source_size= my_decimal_get_binary_size(source_precision, 
 
360
  uint32_t const source_decimal= field_metadata & 0x00ff;
 
361
  uint32_t const source_size= my_decimal_get_binary_size(source_precision,
375
362
                                                     source_decimal);
376
363
  uint32_t const destination_size= row_pack_length();
377
364
  compatible= (source_size <= destination_size);
382
369
}
383
370
 
384
371
 
385
 
uint32_t Field_new_decimal::is_equal(Create_field *new_field)
 
372
uint32_t Field_new_decimal::is_equal(Create_field *new_field_ptr)
386
373
{
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));
 
374
  return ((new_field_ptr->sql_type == real_type()) &&
 
375
          ((new_field_ptr->flags & UNSIGNED_FLAG) ==
 
376
           (uint32_t) (flags & UNSIGNED_FLAG)) &&
 
377
          ((new_field_ptr->flags & AUTO_INCREMENT_FLAG) ==
 
378
           (uint32_t) (flags & AUTO_INCREMENT_FLAG)) &&
 
379
          (new_field_ptr->length == max_display_length()) &&
 
380
          (new_field_ptr->decimals == dec));
394
381
}
395
382
 
396
383
 
399
386
 
400
387
   This method is used to unpack a decimal or numeric field from a master
401
388
   whose size of the field is less than that of the slave.
402
 
  
 
389
 
403
390
   @param   to         Destination of the data
404
391
   @param   from       Source of the data
405
392
   @param   param_data Precision (upper) and decimal (lower) values
431
418
      a decimal and write that to the raw data buffer.
432
419
    */
433
420
    decimal_digit_t dec_buf[DECIMAL_MAX_PRECISION];
434
 
    decimal_t dec;
435
 
    dec.len= from_precision;
436
 
    dec.buf= dec_buf;
 
421
    decimal_t conv_dec;
 
422
    conv_dec.len= from_precision;
 
423
    conv_dec.buf= dec_buf;
437
424
    /*
438
425
      Note: bin2decimal does not change the length of the field. So it is
439
426
      just the first step the resizing operation. The second step does the
440
427
      resizing using the precision and decimals from the slave.
441
428
    */
442
 
    bin2decimal((unsigned char *)from, &dec, from_precision, from_decimal);
443
 
    decimal2bin(&dec, to, precision, decimals());
 
429
    bin2decimal((unsigned char *)from, &conv_dec, from_precision, from_decimal);
 
430
    decimal2bin(&conv_dec, to, precision, decimals());
444
431
  }
445
432
  else
446
433
    memcpy(to, from, len); // Sizes are the same, just copy the data.