~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/decimal.h

Merge Joe, plus I updated the tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
 
#ifndef DRIZZLED_TYPE_DECIMAL_H
17
 
#define DRIZZLED_TYPE_DECIMAL_H
 
16
#ifndef DRIZZLED_DECIMAL_H
 
17
#define DRIZZLED_DECIMAL_H
18
18
#include <assert.h>
19
19
#include <drizzled/sql_string.h>
20
20
#include "drizzled/definitions.h"
21
 
#include "drizzled/type/time.h"
 
21
#include "drizzled/drizzle_time.h"
22
22
namespace drizzled
23
23
{
24
24
 
25
25
typedef enum
26
 
{
27
 
  TRUNCATE= 0,
28
 
  HALF_EVEN,
29
 
  HALF_UP,
30
 
  CEILING,
31
 
  FLOOR
32
 
} decimal_round_mode;
 
26
{TRUNCATE=0, HALF_EVEN, HALF_UP, CEILING, FLOOR}
 
27
  decimal_round_mode;
33
28
typedef int32_t decimal_digit_t;
34
29
 
35
 
struct decimal_t {
 
30
typedef struct st_decimal_t {
36
31
  int    intg, frac, len;
37
32
  bool sign;
38
33
  decimal_digit_t *buf;
39
 
 
40
 
  /* set a decimal_t to zero */
41
 
  inline void set_zero()
42
 
  {                                                         
43
 
    buf[0]= 0;
44
 
    intg= 1;
45
 
    frac= 0;
46
 
    sign= 0; 
47
 
  }
48
 
 
49
 
  /* negate a decimal */
50
 
  inline void negate()
51
 
  {
52
 
    sign^=1;
53
 
  }
54
 
 
55
 
  int isZero() const;
56
 
 
57
 
};
 
34
} decimal_t;
58
35
 
59
36
int internal_str2dec(char *from, decimal_t *to, char **end,
60
37
                     bool fixed);
83
60
int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to);
84
61
int decimal_round(const decimal_t *from, decimal_t *to, int new_scale,
85
62
                  decimal_round_mode mode);
 
63
int decimal_is_zero(const decimal_t *from);
86
64
void max_decimal(int precision, int frac, decimal_t *to);
87
65
 
88
 
inline int string2decimal(char *from, decimal_t *to, char **end)
89
 
{
90
 
  return internal_str2dec(from, to, end, false);
91
 
}
 
66
#define string2decimal(A,B,C) internal_str2dec((A), (B), (C), 0)
 
67
 
 
68
/* set a decimal_t to zero */
 
69
 
 
70
#define decimal_make_zero(dec)        do {                \
 
71
                                        (dec)->buf[0]=0;    \
 
72
                                        (dec)->intg=1;      \
 
73
                                        (dec)->frac=0;      \
 
74
                                        (dec)->sign=0;      \
 
75
                                      } while(0)
92
76
 
93
77
/*
94
78
  returns the length of the buffer to hold string representation
95
79
  of the decimal (including decimal dot, possible sign and \0)
96
80
*/
97
81
 
98
 
inline int decimal_string_size(const decimal_t *dec)
99
 
{
100
 
  return (dec->intg ? dec->intg : 1) + dec->frac + (dec->frac > 0) + 2;
101
 
}
 
82
#define decimal_string_size(dec) (((dec)->intg ? (dec)->intg : 1) + \
 
83
                                  (dec)->frac + ((dec)->frac > 0) + 2)
 
84
 
 
85
/* negate a decimal */
 
86
#define decimal_neg(dec) do { (dec)->sign^=1; } while(0)
102
87
 
103
88
/*
104
89
  conventions:
119
104
 
120
105
#define E_DEC_ERROR            31
121
106
#define E_DEC_FATAL_ERROR      30
122
 
 
123
 
 
124
107
#define DECIMAL_LONGLONG_DIGITS 22
125
108
#define DECIMAL_LONG_DIGITS 10
126
109
#define DECIMAL_LONG3_DIGITS 8
128
111
/** maximum length of buffer in our big digits (uint32_t). */
129
112
#define DECIMAL_BUFF_LENGTH 9
130
113
 
131
 
/* the number of digits that type::Decimal can possibly contain */
 
114
/* the number of digits that my_decimal can possibly contain */
132
115
#define DECIMAL_MAX_POSSIBLE_PRECISION (DECIMAL_BUFF_LENGTH * 9)
133
116
 
134
117
 
153
136
*/
154
137
#define DECIMAL_MAX_FIELD_SIZE DECIMAL_MAX_PRECISION
155
138
 
156
 
namespace type {
157
 
class Decimal;
158
 
}
159
 
 
160
 
inline int class_decimal_int_part(uint32_t precision, uint32_t decimals)
 
139
inline int my_decimal_int_part(uint32_t precision, uint32_t decimals)
161
140
{
162
141
  return precision - ((decimals == DECIMAL_NOT_SPECIFIED) ? 0 : decimals);
163
142
}
164
143
 
165
 
int decimal_operation_results(int result);
166
 
 
167
 
inline void max_Decimal(type::Decimal *to, int precision, int frac)
168
 
{
169
 
  assert((precision <= DECIMAL_MAX_PRECISION)&&
170
 
              (frac <= DECIMAL_MAX_SCALE));
171
 
  max_decimal(precision, frac, (decimal_t*) to);
172
 
}
173
 
 
174
 
inline void max_internal_decimal(type::Decimal *to)
175
 
{
176
 
  max_Decimal(to, DECIMAL_MAX_PRECISION, 0);
177
 
}
178
 
 
179
 
inline int check_result(uint32_t mask, int result)
180
 
{
181
 
  if (result & mask)
182
 
    decimal_operation_results(result);
183
 
  return result;
184
 
}
185
 
 
186
 
namespace type {
 
144
 
187
145
/**
188
 
  type Decimal class limits 'decimal_t' type to what we need in MySQL.
 
146
  my_decimal class limits 'decimal_t' type to what we need in MySQL.
189
147
 
190
148
  It contains internally all necessary space needed by the instance so
191
149
  no extra memory is needed. One should call fix_buffer_pointer() function
192
 
  when he moves type::Decimal objects in memory.
 
150
  when he moves my_decimal objects in memory.
193
151
*/
194
152
 
195
 
class Decimal : public decimal_t
 
153
class my_decimal :public decimal_t
196
154
{
197
155
  decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
198
156
 
202
160
  {
203
161
    len= DECIMAL_BUFF_LENGTH;
204
162
    buf= buffer;
205
 
#if !defined (HAVE_VALGRIND)
206
 
    /* Set buffer to 'random' value to find wrong buffer usage */
207
 
    for (uint32_t i= 0; i < DECIMAL_BUFF_LENGTH; i++)
208
 
      buffer[i]= i;
209
 
#endif
 
163
        #if !defined (HAVE_purify)
 
164
                /* Set buffer to 'random' value to find wrong buffer usage */
 
165
                for (uint32_t i= 0; i < DECIMAL_BUFF_LENGTH; i++)
 
166
                  buffer[i]= i;
 
167
        #endif
210
168
  }
211
 
 
212
 
  Decimal()
 
169
  my_decimal()
213
170
  {
214
171
    init();
215
172
  }
216
 
 
217
173
  void fix_buffer_pointer() { buf= buffer; }
218
174
  bool sign() const { return decimal_t::sign; }
219
175
  void sign(bool s) { decimal_t::sign= s; }
220
176
  uint32_t precision() const { return intg + frac; }
221
 
 
222
 
  int val_int32(uint32_t mask, bool unsigned_flag, int64_t *l) const
223
 
  {
224
 
    type::Decimal rounded;
225
 
    /* decimal_round can return only E_DEC_TRUNCATED */
226
 
    decimal_round(static_cast<const decimal_t*>(this), &rounded, 0, HALF_UP);
227
 
    return check_result(mask, (unsigned_flag ?
228
 
                               decimal2uint64_t(&rounded, reinterpret_cast<uint64_t *>(l)) :
229
 
                               decimal2int64_t(&rounded, l)));
230
 
  }
231
 
 
232
 
  int string_length() const
233
 
  {
234
 
    return decimal_string_size(this);
235
 
  }
236
 
 
237
 
  int val_binary(uint32_t mask, unsigned char *bin, int prec, int scale) const;
238
 
 
239
 
  int store(uint32_t mask, const char *from, uint32_t length, const CHARSET_INFO * charset);
240
 
 
241
 
  int store(uint32_t mask, char *str, char **end)
242
 
  {
243
 
    return check_result_and_overflow(mask, string2decimal(str, static_cast<decimal_t*>(this), end));
244
 
  }
245
 
 
246
 
  int store(uint32_t mask, const String *str)
247
 
  {
248
 
    return store(mask, str->ptr(), str->length(), str->charset());
249
 
  }
250
 
 
251
 
  int check_result_and_overflow(uint32_t mask, int result)
252
 
  {
253
 
    if (check_result(mask, result) & E_DEC_OVERFLOW)
254
 
    {
255
 
      bool _sign= sign();
256
 
      fix_buffer_pointer();
257
 
      max_internal_decimal(this);
258
 
      sign(_sign);
259
 
    }
260
 
    return result;
261
 
  }
262
 
 
263
 
  void convert(double &value) const;
264
177
};
265
178
 
266
 
} // type
267
 
 
268
 
std::ostream& operator<<(std::ostream& output, const type::Decimal &dec);
269
 
 
270
 
inline uint32_t class_decimal_length_to_precision(uint32_t length, uint32_t scale,
271
 
                                                  bool unsigned_flag)
 
179
int decimal_operation_results(int result);
 
180
 
 
181
inline void max_my_decimal(my_decimal *to, int precision, int frac)
 
182
{
 
183
  assert((precision <= DECIMAL_MAX_PRECISION)&&
 
184
              (frac <= DECIMAL_MAX_SCALE));
 
185
  max_decimal(precision, frac, (decimal_t*) to);
 
186
}
 
187
 
 
188
inline void max_internal_decimal(my_decimal *to)
 
189
{
 
190
  max_my_decimal(to, DECIMAL_MAX_PRECISION, 0);
 
191
}
 
192
 
 
193
inline int check_result(uint32_t mask, int result)
 
194
{
 
195
  if (result & mask)
 
196
    decimal_operation_results(result);
 
197
  return result;
 
198
}
 
199
 
 
200
inline int check_result_and_overflow(uint32_t mask, int result, my_decimal *val)
 
201
{
 
202
  if (check_result(mask, result) & E_DEC_OVERFLOW)
 
203
  {
 
204
    bool sign= val->sign();
 
205
    val->fix_buffer_pointer();
 
206
    max_internal_decimal(val);
 
207
    val->sign(sign);
 
208
  }
 
209
  return result;
 
210
}
 
211
 
 
212
inline uint32_t my_decimal_length_to_precision(uint32_t length, uint32_t scale,
 
213
                                           bool unsigned_flag)
272
214
{
273
215
  return (uint32_t) (length - (scale>0 ? 1:0) - (unsigned_flag ? 0:1));
274
216
}
275
217
 
276
 
inline uint32_t class_decimal_precision_to_length(uint32_t precision, uint8_t scale,
277
 
                                                  bool unsigned_flag)
 
218
inline uint32_t my_decimal_precision_to_length(uint32_t precision, uint8_t scale,
 
219
                                             bool unsigned_flag)
278
220
{
279
221
  set_if_smaller(precision, (uint32_t)DECIMAL_MAX_PRECISION);
280
222
  return static_cast<uint32_t>(precision + (scale>0 ? 1:0) + (unsigned_flag ? 0:1));
281
223
}
282
224
 
283
 
 
284
 
inline
285
 
int class_decimal_max_length(const type::Decimal *d)
 
225
inline
 
226
int my_decimal_string_length(const my_decimal *d)
 
227
{
 
228
  return decimal_string_size(d);
 
229
}
 
230
 
 
231
 
 
232
inline
 
233
int my_decimal_max_length(const my_decimal *d)
286
234
{
287
235
  /* -1 because we do not count \0 */
288
236
  return decimal_string_size(d) - 1;
290
238
 
291
239
 
292
240
inline
293
 
int class_decimal_get_binary_size(uint32_t precision, uint32_t scale)
 
241
int my_decimal_get_binary_size(uint32_t precision, uint32_t scale)
294
242
{
295
243
  return decimal_bin_size(static_cast<int>(precision), static_cast<int>(scale));
296
244
}
297
245
 
298
246
 
299
247
inline
300
 
void class_decimal2decimal(const type::Decimal *from, type::Decimal *to)
 
248
void my_decimal2decimal(const my_decimal *from, my_decimal *to)
301
249
{
302
250
  *to= *from;
303
251
  to->fix_buffer_pointer();
304
252
}
305
253
 
306
254
 
 
255
int my_decimal2binary(uint32_t mask, const my_decimal *d, unsigned char *bin, int prec,
 
256
                      int scale);
 
257
 
 
258
 
307
259
inline
308
 
int binary2_class_decimal(uint32_t mask, const unsigned char *bin, type::Decimal *d, int prec,
 
260
int binary2my_decimal(uint32_t mask, const unsigned char *bin, my_decimal *d, int prec,
309
261
                      int scale)
310
262
{
311
263
  return check_result(mask, bin2decimal(bin, static_cast<decimal_t*>(d), prec, scale));
313
265
 
314
266
 
315
267
inline
316
 
int class_decimal_round(uint32_t mask, const type::Decimal *from, int scale,
317
 
                     bool truncate, type::Decimal *to)
 
268
int my_decimal_set_zero(my_decimal *d)
 
269
{
 
270
  decimal_make_zero(static_cast<decimal_t*> (d));
 
271
  return 0;
 
272
}
 
273
 
 
274
 
 
275
inline
 
276
bool my_decimal_is_zero(const my_decimal *decimal_value)
 
277
{
 
278
  return decimal_is_zero(static_cast<const decimal_t*>(decimal_value));
 
279
}
 
280
 
 
281
 
 
282
inline
 
283
int my_decimal_round(uint32_t mask, const my_decimal *from, int scale,
 
284
                     bool truncate, my_decimal *to)
318
285
{
319
286
  return check_result(mask, decimal_round(static_cast<const decimal_t*>(from), to, scale,
320
287
                                          (truncate ? TRUNCATE : HALF_UP)));
322
289
 
323
290
 
324
291
inline
325
 
int class_decimal_floor(uint32_t mask, const type::Decimal *from, type::Decimal *to)
 
292
int my_decimal_floor(uint32_t mask, const my_decimal *from, my_decimal *to)
326
293
{
327
294
  return check_result(mask, decimal_round(static_cast<const decimal_t*>(from), to, 0, FLOOR));
328
295
}
329
296
 
330
297
 
331
298
inline
332
 
int class_decimal_ceiling(uint32_t mask, const type::Decimal *from, type::Decimal *to)
 
299
int my_decimal_ceiling(uint32_t mask, const my_decimal *from, my_decimal *to)
333
300
{
334
301
  return check_result(mask, decimal_round(static_cast<const decimal_t*>(from), to, 0, CEILING));
335
302
}
336
303
 
337
304
 
338
 
int class_decimal2string(const type::Decimal *d,
339
 
                         uint32_t fixed_dec, String *str);
340
 
 
341
 
 
342
 
inline
343
 
int class_decimal2double(uint32_t, const type::Decimal *d, double *result)
 
305
int my_decimal2string(uint32_t mask, const my_decimal *d, uint32_t fixed_prec,
 
306
                      uint32_t fixed_dec, char filler, String *str);
 
307
 
 
308
inline
 
309
int my_decimal2int(uint32_t mask, const my_decimal *d, bool unsigned_flag,
 
310
                   int64_t *l)
 
311
{
 
312
  my_decimal rounded;
 
313
  /* decimal_round can return only E_DEC_TRUNCATED */
 
314
  decimal_round(static_cast<const decimal_t*>(d), &rounded, 0, HALF_UP);
 
315
  return check_result(mask, (unsigned_flag ?
 
316
                             decimal2uint64_t(&rounded, reinterpret_cast<uint64_t *>(l)) :
 
317
                             decimal2int64_t(&rounded, l)));
 
318
}
 
319
 
 
320
 
 
321
inline
 
322
int my_decimal2double(uint32_t, const my_decimal *d, double *result)
344
323
{
345
324
  /* No need to call check_result as this will always succeed */
346
325
  return decimal2double(static_cast<const decimal_t*>(d), result);
347
326
}
348
327
 
349
328
 
350
 
type::Decimal *date2_class_decimal(type::Time *ltime, type::Decimal *dec);
351
 
 
352
 
 
353
 
inline
354
 
int double2_class_decimal(uint32_t mask, double val, type::Decimal *d)
355
 
{
356
 
  return d->check_result_and_overflow(mask, double2decimal(val, static_cast<decimal_t*>(d)));
357
 
}
358
 
 
359
 
 
360
 
inline
361
 
int int2_class_decimal(uint32_t mask, int64_t i, bool unsigned_flag, type::Decimal *d)
 
329
inline
 
330
int str2my_decimal(uint32_t mask, char *str, my_decimal *d, char **end)
 
331
{
 
332
  return check_result_and_overflow(mask, string2decimal(str, static_cast<decimal_t*>(d),end),
 
333
                                   d);
 
334
}
 
335
 
 
336
 
 
337
int str2my_decimal(uint32_t mask, const char *from, uint32_t length,
 
338
                   const CHARSET_INFO * charset, my_decimal *decimal_value);
 
339
 
 
340
inline
 
341
int string2my_decimal(uint32_t mask, const String *str, my_decimal *d)
 
342
{
 
343
  return str2my_decimal(mask, str->ptr(), str->length(), str->charset(), d);
 
344
}
 
345
 
 
346
 
 
347
my_decimal *date2my_decimal(DRIZZLE_TIME *ltime, my_decimal *dec);
 
348
 
 
349
 
 
350
inline
 
351
int double2my_decimal(uint32_t mask, double val, my_decimal *d)
 
352
{
 
353
  return check_result_and_overflow(mask, double2decimal(val, static_cast<decimal_t*>(d)), d);
 
354
}
 
355
 
 
356
 
 
357
inline
 
358
int int2my_decimal(uint32_t mask, int64_t i, bool unsigned_flag, my_decimal *d)
362
359
{
363
360
  return check_result(mask, (unsigned_flag ?
364
361
                             uint64_t2decimal(static_cast<uint64_t>(i), d) :
367
364
 
368
365
 
369
366
inline
370
 
void class_decimal_neg(decimal_t *arg)
 
367
void my_decimal_neg(decimal_t *arg)
371
368
{
372
 
  if (arg->isZero())
 
369
  if (decimal_is_zero(arg))
373
370
  {
374
371
    arg->sign= 0;
375
372
    return;
376
373
  }
377
 
  arg->negate();
378
 
}
379
 
 
380
 
 
381
 
inline
382
 
int class_decimal_add(uint32_t mask, type::Decimal *res, const type::Decimal *a,
383
 
                   const type::Decimal *b)
384
 
{
385
 
  return res->check_result_and_overflow(mask,
386
 
                                        decimal_add(static_cast<const decimal_t*>(a),
387
 
                                                    static_cast<const decimal_t*>(b), res));
388
 
}
389
 
 
390
 
 
391
 
inline
392
 
int class_decimal_sub(uint32_t mask, type::Decimal *res, const type::Decimal *a,
393
 
                   const type::Decimal *b)
394
 
{
395
 
  return res->check_result_and_overflow(mask,
396
 
                                        decimal_sub(static_cast<const decimal_t*>(a),
397
 
                                                    static_cast<const decimal_t*>(b), res));
398
 
}
399
 
 
400
 
 
401
 
inline
402
 
int class_decimal_mul(uint32_t mask, type::Decimal *res, const type::Decimal *a,
403
 
                   const type::Decimal *b)
404
 
{
405
 
  return res->check_result_and_overflow(mask,
406
 
                                        decimal_mul(static_cast<const decimal_t*>(a),
407
 
                                                    static_cast<const decimal_t*>(b),res));
408
 
}
409
 
 
410
 
 
411
 
inline
412
 
int class_decimal_div(uint32_t mask, type::Decimal *res, const type::Decimal *a,
413
 
                   const type::Decimal *b, int div_scale_inc)
414
 
{
415
 
  return res->check_result_and_overflow(mask,
416
 
                                        decimal_div(static_cast<const decimal_t*>(a),
417
 
                                                    static_cast<const decimal_t*>(b),res,
418
 
                                                    div_scale_inc));
419
 
}
420
 
 
421
 
 
422
 
inline
423
 
int class_decimal_mod(uint32_t mask, type::Decimal *res, const type::Decimal *a,
424
 
                   const type::Decimal *b)
425
 
{
426
 
  return res->check_result_and_overflow(mask,
427
 
                                        decimal_mod(static_cast<const decimal_t*>(a),
428
 
                                                    static_cast<const decimal_t*>(b),res));
 
374
  decimal_neg(arg);
 
375
}
 
376
 
 
377
 
 
378
inline
 
379
int my_decimal_add(uint32_t mask, my_decimal *res, const my_decimal *a,
 
380
                   const my_decimal *b)
 
381
{
 
382
  return check_result_and_overflow(mask,
 
383
                                   decimal_add(static_cast<const decimal_t*>(a),
 
384
                                               static_cast<const decimal_t*>(b), res),
 
385
                                   res);
 
386
}
 
387
 
 
388
 
 
389
inline
 
390
int my_decimal_sub(uint32_t mask, my_decimal *res, const my_decimal *a,
 
391
                   const my_decimal *b)
 
392
{
 
393
  return check_result_and_overflow(mask,
 
394
                                   decimal_sub(static_cast<const decimal_t*>(a),
 
395
                                               static_cast<const decimal_t*>(b), res),
 
396
                                   res);
 
397
}
 
398
 
 
399
 
 
400
inline
 
401
int my_decimal_mul(uint32_t mask, my_decimal *res, const my_decimal *a,
 
402
                   const my_decimal *b)
 
403
{
 
404
  return check_result_and_overflow(mask,
 
405
                                   decimal_mul(static_cast<const decimal_t*>(a),
 
406
                                               static_cast<const decimal_t*>(b),res),
 
407
                                   res);
 
408
}
 
409
 
 
410
 
 
411
inline
 
412
int my_decimal_div(uint32_t mask, my_decimal *res, const my_decimal *a,
 
413
                   const my_decimal *b, int div_scale_inc)
 
414
{
 
415
  return check_result_and_overflow(mask,
 
416
                                   decimal_div(static_cast<const decimal_t*>(a),
 
417
                                               static_cast<const decimal_t*>(b),res,
 
418
                                               div_scale_inc),
 
419
                                   res);
 
420
}
 
421
 
 
422
 
 
423
inline
 
424
int my_decimal_mod(uint32_t mask, my_decimal *res, const my_decimal *a,
 
425
                   const my_decimal *b)
 
426
{
 
427
  return check_result_and_overflow(mask,
 
428
                                   decimal_mod(static_cast<const decimal_t*>(a),
 
429
                                               static_cast<const decimal_t*>(b),res),
 
430
                                   res);
429
431
}
430
432
 
431
433
 
434
436
    -1 if a<b, 1 if a>b and 0 if a==b
435
437
*/
436
438
inline
437
 
int class_decimal_cmp(const type::Decimal *a, const type::Decimal *b)
 
439
int my_decimal_cmp(const my_decimal *a, const my_decimal *b)
438
440
{
439
441
  return decimal_cmp(static_cast<const decimal_t*>(a),
440
442
                     static_cast<const decimal_t*>(b));
442
444
 
443
445
 
444
446
inline
445
 
int class_decimal_intg(const type::Decimal *a)
 
447
int my_decimal_intg(const my_decimal *a)
446
448
{
447
449
  return decimal_intg(static_cast<const decimal_t*>(a));
448
450
}
449
451
 
450
452
 
451
 
void class_decimal_trim(uint32_t *precision, uint32_t *scale);
452
 
 
453
 
inline type::Decimal &decimal_zero_const()
454
 
{
455
 
  static type::Decimal _decimal_zero;
456
 
  return _decimal_zero;
457
 
}
458
 
 
459
 
double my_double_round(double value, int64_t dec, bool dec_unsigned,
460
 
                       bool truncate);
461
 
 
462
 
 
463
 
#define decimal_zero decimal_zero_const()
 
453
void my_decimal_trim(uint32_t *precision, uint32_t *scale);
464
454
 
465
455
} /* namespace drizzled */
466
456
 
467
 
#endif /* DRIZZLED_TYPE_DECIMAL_H */
 
457
#endif /* DRIZZLED_DECIMAL_H */
468
458