Merge lp:~dedzone/drizzle/ded-decimal into lp:~drizzle-trunk/drizzle/development

Proposed by Djellel E. Difallah
Status: Merged
Merged at revision: not available
Proposed branch: lp:~dedzone/drizzle/ded-decimal
Merge into: lp:~drizzle-trunk/drizzle/development
Diff against target: 1360 lines (+579/-647)
11 files modified
drizzled/cached_item.h (+1/-1)
drizzled/decimal.cc (+223/-0)
drizzled/decimal.h (+351/-1)
drizzled/field.h (+1/-1)
drizzled/hybrid_type.h (+1/-1)
drizzled/include.am (+0/-2)
drizzled/item.h (+1/-1)
drizzled/my_decimal.cc (+0/-243)
drizzled/my_decimal.h (+0/-395)
drizzled/temporal.cc (+1/-1)
support-files/drizzle.spec.in (+0/-1)
To merge this branch: bzr merge lp:~dedzone/drizzle/ded-decimal
Reviewer Review Type Date Requested Status
Monty Taylor Approve
Review via email: mp+22314@code.launchpad.net

This proposal supersedes a proposal from 2010-03-27.

Description of the change

Have just merged decimal and my_decimal, and updated the references then tested it.

To post a comment you must log in.
Revision history for this message
Monty Taylor (mordred) wrote : Posted in a previous version of this proposal

Wonderful. Looks like you left in a commentted out section of code:

 +//#include "drizzled/error.h"
 +//#include "drizzled/field.h"

Could you remove those? Otherwise, looks fantastic.

review: Needs Fixing
Revision history for this message
Monty Taylor (mordred) wrote :

Awesome. Looks great!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'drizzled/cached_item.h'
--- drizzled/cached_item.h 2010-02-04 08:14:46 +0000
+++ drizzled/cached_item.h 2010-03-28 01:34:23 +0000
@@ -22,7 +22,7 @@
2222
23#include "drizzled/memory/sql_alloc.h"23#include "drizzled/memory/sql_alloc.h"
24#include "drizzled/sql_string.h"24#include "drizzled/sql_string.h"
25#include "drizzled/my_decimal.h"25#include "drizzled/decimal.h"
2626
27namespace drizzled27namespace drizzled
28{28{
2929
=== modified file 'drizzled/decimal.cc'
--- drizzled/decimal.cc 2010-02-04 08:14:46 +0000
+++ drizzled/decimal.cc 2010-03-28 01:34:23 +0000
@@ -112,11 +112,233 @@
112#endif112#endif
113113
114#include <algorithm>114#include <algorithm>
115#include <time.h>
116#include "drizzled/current_session.h"
117#include "drizzled/error.h"
118#include "drizzled/field.h"
119#include "drizzled/internal/my_sys.h"
115120
116using namespace std;121using namespace std;
117122
118namespace drizzled123namespace drizzled
119{124{
125/**
126 report result of decimal operation.
127
128 @param result decimal library return code (E_DEC_* see include/decimal.h)
129
130 @todo
131 Fix error messages
132
133 @return
134 result
135*/
136
137int decimal_operation_results(int result)
138{
139 switch (result) {
140 case E_DEC_OK:
141 break;
142 case E_DEC_TRUNCATED:
143 push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
144 ER_WARN_DATA_TRUNCATED, ER(ER_WARN_DATA_TRUNCATED),
145 "", (long)-1);
146 break;
147 case E_DEC_OVERFLOW:
148 push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
149 ER_TRUNCATED_WRONG_VALUE,
150 ER(ER_TRUNCATED_WRONG_VALUE),
151 "DECIMAL", "");
152 break;
153 case E_DEC_DIV_ZERO:
154 push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
155 ER_DIVISION_BY_ZERO, ER(ER_DIVISION_BY_ZERO));
156 break;
157 case E_DEC_BAD_NUM:
158 push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
159 ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
160 ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
161 "decimal", "", "", (long)-1);
162 break;
163 case E_DEC_OOM:
164 my_error(ER_OUT_OF_RESOURCES, MYF(0));
165 break;
166 default:
167 assert(0);
168 }
169 return result;
170}
171
172
173/**
174 @brief Converting decimal to string
175
176 @details Convert given my_decimal to String; allocate buffer as needed.
177
178 @param[in] mask what problems to warn on (mask of E_DEC_* values)
179 @param[in] d the decimal to print
180 @param[in] fixed_prec overall number of digits if ZEROFILL, 0 otherwise
181 @param[in] fixed_dec number of decimal places (if fixed_prec != 0)
182 @param[in] filler what char to pad with (ZEROFILL et al.)
183 @param[out] *str where to store the resulting string
184
185 @return error coce
186 @retval E_DEC_OK
187 @retval E_DEC_TRUNCATED
188 @retval E_DEC_OVERFLOW
189 @retval E_DEC_OOM
190*/
191
192int my_decimal2string(uint32_t mask, const my_decimal *d,
193 uint32_t fixed_prec, uint32_t fixed_dec,
194 char filler, String *str)
195{
196 /*
197 Calculate the size of the string: For DECIMAL(a,b), fixed_prec==a
198 holds true iff the type is also ZEROFILL, which in turn implies
199 UNSIGNED. Hence the buffer for a ZEROFILLed value is the length
200 the user requested, plus one for a possible decimal point, plus
201 one if the user only wanted decimal places, but we force a leading
202 zero on them. Because the type is implicitly UNSIGNED, we do not
203 need to reserve a character for the sign. For all other cases,
204 fixed_prec will be 0, and my_decimal_string_length() will be called
205 instead to calculate the required size of the buffer.
206 */
207 int length= (fixed_prec
208 ? (fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1)
209 : my_decimal_string_length(d));
210 int result;
211 if (str->alloc(length))
212 return check_result(mask, E_DEC_OOM);
213 result= decimal2string((decimal_t*) d, (char*) str->ptr(),
214 &length, (int)fixed_prec, fixed_dec,
215 filler);
216 str->length(length);
217 return check_result(mask, result);
218}
219
220
221/*
222 Convert from decimal to binary representation
223
224 SYNOPSIS
225 my_decimal2binary()
226 mask error processing mask
227 d number for conversion
228 bin pointer to buffer where to write result
229 prec overall number of decimal digits
230 scale number of decimal digits after decimal point
231
232 NOTE
233 Before conversion we round number if it need but produce truncation
234 error in this case
235
236 RETURN
237 E_DEC_OK
238 E_DEC_TRUNCATED
239 E_DEC_OVERFLOW
240*/
241
242int my_decimal2binary(uint32_t mask, const my_decimal *d, unsigned char *bin, int prec,
243 int scale)
244{
245 int err1= E_DEC_OK, err2;
246 my_decimal rounded;
247 my_decimal2decimal(d, &rounded);
248 rounded.frac= decimal_actual_fraction(&rounded);
249 if (scale < rounded.frac)
250 {
251 err1= E_DEC_TRUNCATED;
252 /* decimal_round can return only E_DEC_TRUNCATED */
253 decimal_round(&rounded, &rounded, scale, HALF_UP);
254 }
255 err2= decimal2bin(&rounded, bin, prec, scale);
256 if (!err2)
257 err2= err1;
258 return check_result(mask, err2);
259}
260
261
262/*
263 Convert string for decimal when string can be in some multibyte charset
264
265 SYNOPSIS
266 str2my_decimal()
267 mask error processing mask
268 from string to process
269 length length of given string
270 charset charset of given string
271 decimal_value buffer for result storing
272
273 RESULT
274 E_DEC_OK
275 E_DEC_TRUNCATED
276 E_DEC_OVERFLOW
277 E_DEC_BAD_NUM
278 E_DEC_OOM
279*/
280
281int str2my_decimal(uint32_t mask, const char *from, uint32_t length,
282 const CHARSET_INFO * charset, my_decimal *decimal_value)
283{
284 char *end, *from_end;
285 int err;
286 char buff[STRING_BUFFER_USUAL_SIZE];
287 String tmp(buff, sizeof(buff), &my_charset_bin);
288 if (charset->mbminlen > 1)
289 {
290 uint32_t dummy_errors;
291 tmp.copy(from, length, charset, &my_charset_utf8_general_ci, &dummy_errors);
292 from= tmp.ptr();
293 length= tmp.length();
294 charset= &my_charset_bin;
295 }
296 from_end= end= (char*) from+length;
297 err= string2decimal((char *)from, (decimal_t*) decimal_value, &end);
298 if (end != from_end && !err)
299 {
300 /* Give warning if there is something other than end space */
301 for ( ; end < from_end; end++)
302 {
303 if (!my_isspace(&my_charset_utf8_general_ci, *end))
304 {
305 err= E_DEC_TRUNCATED;
306 break;
307 }
308 }
309 }
310 check_result_and_overflow(mask, err, decimal_value);
311 return err;
312}
313
314
315my_decimal *date2my_decimal(DRIZZLE_TIME *ltime, my_decimal *dec)
316{
317 int64_t date;
318 date = (ltime->year*100L + ltime->month)*100L + ltime->day;
319 if (ltime->time_type > DRIZZLE_TIMESTAMP_DATE)
320 date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second;
321 if (int2my_decimal(E_DEC_FATAL_ERROR, date, false, dec))
322 return dec;
323 if (ltime->second_part)
324 {
325 dec->buf[(dec->intg-1) / 9 + 1]= ltime->second_part * 1000;
326 dec->frac= 6;
327 }
328 return dec;
329}
330
331
332void my_decimal_trim(uint32_t *precision, uint32_t *scale)
333{
334 if (!(*precision) && !(*scale))
335 {
336 *precision= 10;
337 *scale= 0;
338 return;
339 }
340}
341
120342
121/*343/*
122 Internally decimal numbers are stored base 10^9 (see DIG_BASE below)344 Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
@@ -236,6 +458,7 @@
236 } while (0)458 } while (0)
237459
238460
461
239/*462/*
240 Get maximum value for given precision and scale463 Get maximum value for given precision and scale
241464
242465
=== modified file 'drizzled/decimal.h'
--- drizzled/decimal.h 2010-03-01 01:20:07 +0000
+++ drizzled/decimal.h 2010-03-28 01:34:23 +0000
@@ -15,7 +15,10 @@
1515
16#ifndef DRIZZLED_DECIMAL_H16#ifndef DRIZZLED_DECIMAL_H
17#define DRIZZLED_DECIMAL_H17#define DRIZZLED_DECIMAL_H
1818#include <assert.h>
19#include <drizzled/sql_string.h>
20#include "drizzled/definitions.h"
21#include "drizzled/my_time.h"
19namespace drizzled22namespace drizzled
20{23{
2124
@@ -101,6 +104,353 @@
101104
102#define E_DEC_ERROR 31105#define E_DEC_ERROR 31
103#define E_DEC_FATAL_ERROR 30106#define E_DEC_FATAL_ERROR 30
107#define DECIMAL_LONGLONG_DIGITS 22
108#define DECIMAL_LONG_DIGITS 10
109#define DECIMAL_LONG3_DIGITS 8
110
111/** maximum length of buffer in our big digits (uint32_t). */
112#define DECIMAL_BUFF_LENGTH 9
113
114/* the number of digits that my_decimal can possibly contain */
115#define DECIMAL_MAX_POSSIBLE_PRECISION (DECIMAL_BUFF_LENGTH * 9)
116
117
118/**
119 maximum guaranteed precision of number in decimal digits (number of our
120 digits * number of decimal digits in one our big digit - number of decimal
121 digits in one our big digit decreased by 1 (because we always put decimal
122 point on the border of our big digits))
123*/
124#define DECIMAL_MAX_PRECISION (DECIMAL_MAX_POSSIBLE_PRECISION - 8*2)
125#define DECIMAL_MAX_SCALE 30
126#define DECIMAL_NOT_SPECIFIED 31
127
128/**
129 maximum length of string representation (number of maximum decimal
130 digits + 1 position for sign + 1 position for decimal point)
131*/
132#define DECIMAL_MAX_STR_LENGTH (DECIMAL_MAX_POSSIBLE_PRECISION + 2)
133
134/**
135 maximum size of packet length.
136*/
137#define DECIMAL_MAX_FIELD_SIZE DECIMAL_MAX_PRECISION
138
139inline int my_decimal_int_part(uint32_t precision, uint32_t decimals)
140{
141 return precision - ((decimals == DECIMAL_NOT_SPECIFIED) ? 0 : decimals);
142}
143
144
145/**
146 my_decimal class limits 'decimal_t' type to what we need in MySQL.
147
148 It contains internally all necessary space needed by the instance so
149 no extra memory is needed. One should call fix_buffer_pointer() function
150 when he moves my_decimal objects in memory.
151*/
152
153class my_decimal :public decimal_t
154{
155 decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
156
157public:
158
159 void init()
160 {
161 len= DECIMAL_BUFF_LENGTH;
162 buf= buffer;
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
168 }
169 my_decimal()
170 {
171 init();
172 }
173 void fix_buffer_pointer() { buf= buffer; }
174 bool sign() const { return decimal_t::sign; }
175 void sign(bool s) { decimal_t::sign= s; }
176 uint32_t precision() const { return intg + frac; }
177};
178
179int decimal_operation_results(int result);
180
181inline 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
188inline void max_internal_decimal(my_decimal *to)
189{
190 max_my_decimal(to, DECIMAL_MAX_PRECISION, 0);
191}
192
193inline int check_result(uint32_t mask, int result)
194{
195 if (result & mask)
196 decimal_operation_results(result);
197 return result;
198}
199
200inline 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
212inline uint32_t my_decimal_length_to_precision(uint32_t length, uint32_t scale,
213 bool unsigned_flag)
214{
215 return (uint32_t) (length - (scale>0 ? 1:0) - (unsigned_flag ? 0:1));
216}
217
218inline uint32_t my_decimal_precision_to_length(uint32_t precision, uint8_t scale,
219 bool unsigned_flag)
220{
221 set_if_smaller(precision, (uint32_t)DECIMAL_MAX_PRECISION);
222 return static_cast<uint32_t>(precision + (scale>0 ? 1:0) + (unsigned_flag ? 0:1));
223}
224
225inline
226int my_decimal_string_length(const my_decimal *d)
227{
228 return decimal_string_size(d);
229}
230
231
232inline
233int my_decimal_max_length(const my_decimal *d)
234{
235 /* -1 because we do not count \0 */
236 return decimal_string_size(d) - 1;
237}
238
239
240inline
241int my_decimal_get_binary_size(uint32_t precision, uint32_t scale)
242{
243 return decimal_bin_size(static_cast<int>(precision), static_cast<int>(scale));
244}
245
246
247inline
248void my_decimal2decimal(const my_decimal *from, my_decimal *to)
249{
250 *to= *from;
251 to->fix_buffer_pointer();
252}
253
254
255int my_decimal2binary(uint32_t mask, const my_decimal *d, unsigned char *bin, int prec,
256 int scale);
257
258
259inline
260int binary2my_decimal(uint32_t mask, const unsigned char *bin, my_decimal *d, int prec,
261 int scale)
262{
263 return check_result(mask, bin2decimal(bin, static_cast<decimal_t*>(d), prec, scale));
264}
265
266
267inline
268int my_decimal_set_zero(my_decimal *d)
269{
270 decimal_make_zero(static_cast<decimal_t*> (d));
271 return 0;
272}
273
274
275inline
276bool 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
282inline
283int my_decimal_round(uint32_t mask, const my_decimal *from, int scale,
284 bool truncate, my_decimal *to)
285{
286 return check_result(mask, decimal_round(static_cast<const decimal_t*>(from), to, scale,
287 (truncate ? TRUNCATE : HALF_UP)));
288}
289
290
291inline
292int my_decimal_floor(uint32_t mask, const my_decimal *from, my_decimal *to)
293{
294 return check_result(mask, decimal_round(static_cast<const decimal_t*>(from), to, 0, FLOOR));
295}
296
297
298inline
299int my_decimal_ceiling(uint32_t mask, const my_decimal *from, my_decimal *to)
300{
301 return check_result(mask, decimal_round(static_cast<const decimal_t*>(from), to, 0, CEILING));
302}
303
304
305int my_decimal2string(uint32_t mask, const my_decimal *d, uint32_t fixed_prec,
306 uint32_t fixed_dec, char filler, String *str);
307
308inline
309int 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
321inline
322int my_decimal2double(uint32_t, const my_decimal *d, double *result)
323{
324 /* No need to call check_result as this will always succeed */
325 return decimal2double(static_cast<const decimal_t*>(d), result);
326}
327
328
329inline
330int 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
337int str2my_decimal(uint32_t mask, const char *from, uint32_t length,
338 const CHARSET_INFO * charset, my_decimal *decimal_value);
339
340inline
341int 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
347my_decimal *date2my_decimal(DRIZZLE_TIME *ltime, my_decimal *dec);
348
349
350inline
351int 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
357inline
358int int2my_decimal(uint32_t mask, int64_t i, bool unsigned_flag, my_decimal *d)
359{
360 return check_result(mask, (unsigned_flag ?
361 uint64_t2decimal(static_cast<uint64_t>(i), d) :
362 int64_t2decimal(i, d)));
363}
364
365
366inline
367void my_decimal_neg(decimal_t *arg)
368{
369 if (decimal_is_zero(arg))
370 {
371 arg->sign= 0;
372 return;
373 }
374 decimal_neg(arg);
375}
376
377
378inline
379int 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
389inline
390int 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
400inline
401int 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
411inline
412int 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
423inline
424int 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);
431}
432
433
434/**
435 @return
436 -1 if a<b, 1 if a>b and 0 if a==b
437*/
438inline
439int my_decimal_cmp(const my_decimal *a, const my_decimal *b)
440{
441 return decimal_cmp(static_cast<const decimal_t*>(a),
442 static_cast<const decimal_t*>(b));
443}
444
445
446inline
447int my_decimal_intg(const my_decimal *a)
448{
449 return decimal_intg(static_cast<const decimal_t*>(a));
450}
451
452
453void my_decimal_trim(uint32_t *precision, uint32_t *scale);
104454
105} /* namespace drizzled */455} /* namespace drizzled */
106456
107457
=== modified file 'drizzled/field.h'
--- drizzled/field.h 2010-03-02 06:41:59 +0000
+++ drizzled/field.h 2010-03-28 01:34:23 +0000
@@ -26,7 +26,7 @@
26#define DRIZZLED_FIELD_H26#define DRIZZLED_FIELD_H
2727
28#include "drizzled/sql_error.h"28#include "drizzled/sql_error.h"
29#include "drizzled/my_decimal.h"29#include "drizzled/decimal.h"
30#include "drizzled/key_map.h"30#include "drizzled/key_map.h"
31#include "drizzled/sql_bitmap.h"31#include "drizzled/sql_bitmap.h"
32#include "drizzled/sql_list.h"32#include "drizzled/sql_list.h"
3333
=== modified file 'drizzled/hybrid_type.h'
--- drizzled/hybrid_type.h 2010-02-04 08:14:46 +0000
+++ drizzled/hybrid_type.h 2010-03-28 01:34:23 +0000
@@ -20,7 +20,7 @@
20#ifndef DRIZZLED_HYBRID_TYPE_H20#ifndef DRIZZLED_HYBRID_TYPE_H
21#define DRIZZLED_HYBRID_TYPE_H21#define DRIZZLED_HYBRID_TYPE_H
2222
23#include <drizzled/my_decimal.h>23#include <drizzled/decimal.h>
2424
25namespace drizzled25namespace drizzled
26{26{
2727
=== modified file 'drizzled/include.am'
--- drizzled/include.am 2010-03-22 17:38:58 +0000
+++ drizzled/include.am 2010-03-28 01:34:23 +0000
@@ -255,7 +255,6 @@
255 drizzled/memory/sql_alloc.h \255 drizzled/memory/sql_alloc.h \
256 drizzled/memory/multi_malloc.h \256 drizzled/memory/multi_malloc.h \
257 drizzled/memory/root.h \257 drizzled/memory/root.h \
258 drizzled/my_decimal.h \
259 drizzled/my_getopt.h \258 drizzled/my_getopt.h \
260 drizzled/my_hash.h \259 drizzled/my_hash.h \
261 drizzled/my_time.h \260 drizzled/my_time.h \
@@ -632,7 +631,6 @@
632 drizzled/key_map.cc \631 drizzled/key_map.cc \
633 drizzled/lock.cc \632 drizzled/lock.cc \
634 drizzled/lookup_symbol.cc \633 drizzled/lookup_symbol.cc \
635 drizzled/my_decimal.cc \
636 drizzled/my_getsystime.cc \634 drizzled/my_getsystime.cc \
637 drizzled/my_hash.cc \635 drizzled/my_hash.cc \
638 drizzled/my_time.cc \636 drizzled/my_time.cc \
639637
=== modified file 'drizzled/item.h'
--- drizzled/item.h 2010-03-02 06:41:59 +0000
+++ drizzled/item.h 2010-03-28 01:34:23 +0000
@@ -22,7 +22,7 @@
2222
23#include <drizzled/dtcollation.h>23#include <drizzled/dtcollation.h>
24#include <drizzled/my_time.h>24#include <drizzled/my_time.h>
25#include <drizzled/my_decimal.h>25#include <drizzled/decimal.h>
26#include <drizzled/sql_bitmap.h>26#include <drizzled/sql_bitmap.h>
27#include <drizzled/sql_list.h>27#include <drizzled/sql_list.h>
28#include "drizzled/memory/sql_alloc.h"28#include "drizzled/memory/sql_alloc.h"
2929
=== removed file 'drizzled/my_decimal.cc'
--- drizzled/my_decimal.cc 2010-02-04 08:14:46 +0000
+++ drizzled/my_decimal.cc 1970-01-01 00:00:00 +0000
@@ -1,243 +0,0 @@
1/* Copyright (C) 2005-2006 MySQL AB
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
15
16#include "config.h"
17#include <time.h>
18#include "drizzled/current_session.h"
19#include "drizzled/error.h"
20#include "drizzled/field.h"
21#include "drizzled/internal/my_sys.h"
22
23namespace drizzled
24{
25
26/**
27 report result of decimal operation.
28
29 @param result decimal library return code (E_DEC_* see include/decimal.h)
30
31 @todo
32 Fix error messages
33
34 @return
35 result
36*/
37
38int decimal_operation_results(int result)
39{
40 switch (result) {
41 case E_DEC_OK:
42 break;
43 case E_DEC_TRUNCATED:
44 push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
45 ER_WARN_DATA_TRUNCATED, ER(ER_WARN_DATA_TRUNCATED),
46 "", (long)-1);
47 break;
48 case E_DEC_OVERFLOW:
49 push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
50 ER_TRUNCATED_WRONG_VALUE,
51 ER(ER_TRUNCATED_WRONG_VALUE),
52 "DECIMAL", "");
53 break;
54 case E_DEC_DIV_ZERO:
55 push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
56 ER_DIVISION_BY_ZERO, ER(ER_DIVISION_BY_ZERO));
57 break;
58 case E_DEC_BAD_NUM:
59 push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
60 ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
61 ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
62 "decimal", "", "", (long)-1);
63 break;
64 case E_DEC_OOM:
65 my_error(ER_OUT_OF_RESOURCES, MYF(0));
66 break;
67 default:
68 assert(0);
69 }
70 return result;
71}
72
73
74/**
75 @brief Converting decimal to string
76
77 @details Convert given my_decimal to String; allocate buffer as needed.
78
79 @param[in] mask what problems to warn on (mask of E_DEC_* values)
80 @param[in] d the decimal to print
81 @param[in] fixed_prec overall number of digits if ZEROFILL, 0 otherwise
82 @param[in] fixed_dec number of decimal places (if fixed_prec != 0)
83 @param[in] filler what char to pad with (ZEROFILL et al.)
84 @param[out] *str where to store the resulting string
85
86 @return error coce
87 @retval E_DEC_OK
88 @retval E_DEC_TRUNCATED
89 @retval E_DEC_OVERFLOW
90 @retval E_DEC_OOM
91*/
92
93int my_decimal2string(uint32_t mask, const my_decimal *d,
94 uint32_t fixed_prec, uint32_t fixed_dec,
95 char filler, String *str)
96{
97 /*
98 Calculate the size of the string: For DECIMAL(a,b), fixed_prec==a
99 holds true iff the type is also ZEROFILL, which in turn implies
100 UNSIGNED. Hence the buffer for a ZEROFILLed value is the length
101 the user requested, plus one for a possible decimal point, plus
102 one if the user only wanted decimal places, but we force a leading
103 zero on them. Because the type is implicitly UNSIGNED, we do not
104 need to reserve a character for the sign. For all other cases,
105 fixed_prec will be 0, and my_decimal_string_length() will be called
106 instead to calculate the required size of the buffer.
107 */
108 int length= (fixed_prec
109 ? (fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1)
110 : my_decimal_string_length(d));
111 int result;
112 if (str->alloc(length))
113 return check_result(mask, E_DEC_OOM);
114 result= decimal2string((decimal_t*) d, (char*) str->ptr(),
115 &length, (int)fixed_prec, fixed_dec,
116 filler);
117 str->length(length);
118 return check_result(mask, result);
119}
120
121
122/*
123 Convert from decimal to binary representation
124
125 SYNOPSIS
126 my_decimal2binary()
127 mask error processing mask
128 d number for conversion
129 bin pointer to buffer where to write result
130 prec overall number of decimal digits
131 scale number of decimal digits after decimal point
132
133 NOTE
134 Before conversion we round number if it need but produce truncation
135 error in this case
136
137 RETURN
138 E_DEC_OK
139 E_DEC_TRUNCATED
140 E_DEC_OVERFLOW
141*/
142
143int my_decimal2binary(uint32_t mask, const my_decimal *d, unsigned char *bin, int prec,
144 int scale)
145{
146 int err1= E_DEC_OK, err2;
147 my_decimal rounded;
148 my_decimal2decimal(d, &rounded);
149 rounded.frac= decimal_actual_fraction(&rounded);
150 if (scale < rounded.frac)
151 {
152 err1= E_DEC_TRUNCATED;
153 /* decimal_round can return only E_DEC_TRUNCATED */
154 decimal_round(&rounded, &rounded, scale, HALF_UP);
155 }
156 err2= decimal2bin(&rounded, bin, prec, scale);
157 if (!err2)
158 err2= err1;
159 return check_result(mask, err2);
160}
161
162
163/*
164 Convert string for decimal when string can be in some multibyte charset
165
166 SYNOPSIS
167 str2my_decimal()
168 mask error processing mask
169 from string to process
170 length length of given string
171 charset charset of given string
172 decimal_value buffer for result storing
173
174 RESULT
175 E_DEC_OK
176 E_DEC_TRUNCATED
177 E_DEC_OVERFLOW
178 E_DEC_BAD_NUM
179 E_DEC_OOM
180*/
181
182int str2my_decimal(uint32_t mask, const char *from, uint32_t length,
183 const CHARSET_INFO * charset, my_decimal *decimal_value)
184{
185 char *end, *from_end;
186 int err;
187 char buff[STRING_BUFFER_USUAL_SIZE];
188 String tmp(buff, sizeof(buff), &my_charset_bin);
189 if (charset->mbminlen > 1)
190 {
191 uint32_t dummy_errors;
192 tmp.copy(from, length, charset, &my_charset_utf8_general_ci, &dummy_errors);
193 from= tmp.ptr();
194 length= tmp.length();
195 charset= &my_charset_bin;
196 }
197 from_end= end= (char*) from+length;
198 err= string2decimal((char *)from, (decimal_t*) decimal_value, &end);
199 if (end != from_end && !err)
200 {
201 /* Give warning if there is something other than end space */
202 for ( ; end < from_end; end++)
203 {
204 if (!my_isspace(&my_charset_utf8_general_ci, *end))
205 {
206 err= E_DEC_TRUNCATED;
207 break;
208 }
209 }
210 }
211 check_result_and_overflow(mask, err, decimal_value);
212 return err;
213}
214
215
216my_decimal *date2my_decimal(DRIZZLE_TIME *ltime, my_decimal *dec)
217{
218 int64_t date;
219 date = (ltime->year*100L + ltime->month)*100L + ltime->day;
220 if (ltime->time_type > DRIZZLE_TIMESTAMP_DATE)
221 date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second;
222 if (int2my_decimal(E_DEC_FATAL_ERROR, date, false, dec))
223 return dec;
224 if (ltime->second_part)
225 {
226 dec->buf[(dec->intg-1) / 9 + 1]= ltime->second_part * 1000;
227 dec->frac= 6;
228 }
229 return dec;
230}
231
232
233void my_decimal_trim(uint32_t *precision, uint32_t *scale)
234{
235 if (!(*precision) && !(*scale))
236 {
237 *precision= 10;
238 *scale= 0;
239 return;
240 }
241}
242
243} /* namespace drizzled */
2440
=== removed file 'drizzled/my_decimal.h'
--- drizzled/my_decimal.h 2010-02-04 08:14:46 +0000
+++ drizzled/my_decimal.h 1970-01-01 00:00:00 +0000
@@ -1,395 +0,0 @@
1/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3 *
4 * Copyright (C) 2008 Sun Microsystems
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20/**
21 @file
22
23 It is interface module to fixed precision decimals library.
24
25 Most functions use 'uint32_t mask' as parameter, if during operation error
26 which fit in this mask is detected then it will be processed automatically
27 here. (errors are E_DEC_* constants, see drizzled/decimal.h)
28
29 Most function are just inline wrappers around library calls
30*/
31
32#ifndef DRIZZLED_MY_DECIMAL_H
33#define DRIZZLED_MY_DECIMAL_H
34
35#include <drizzled/decimal.h>
36#include <drizzled/my_time.h>
37#include <drizzled/definitions.h>
38#include <drizzled/sql_string.h>
39
40namespace drizzled
41{
42
43#define DECIMAL_LONGLONG_DIGITS 22
44#define DECIMAL_LONG_DIGITS 10
45#define DECIMAL_LONG3_DIGITS 8
46
47/** maximum length of buffer in our big digits (uint32_t). */
48#define DECIMAL_BUFF_LENGTH 9
49
50/* the number of digits that my_decimal can possibly contain */
51#define DECIMAL_MAX_POSSIBLE_PRECISION (DECIMAL_BUFF_LENGTH * 9)
52
53
54/**
55 maximum guaranteed precision of number in decimal digits (number of our
56 digits * number of decimal digits in one our big digit - number of decimal
57 digits in one our big digit decreased by 1 (because we always put decimal
58 point on the border of our big digits))
59*/
60#define DECIMAL_MAX_PRECISION (DECIMAL_MAX_POSSIBLE_PRECISION - 8*2)
61#define DECIMAL_MAX_SCALE 30
62#define DECIMAL_NOT_SPECIFIED 31
63
64/**
65 maximum length of string representation (number of maximum decimal
66 digits + 1 position for sign + 1 position for decimal point)
67*/
68#define DECIMAL_MAX_STR_LENGTH (DECIMAL_MAX_POSSIBLE_PRECISION + 2)
69
70/**
71 maximum size of packet length.
72*/
73#define DECIMAL_MAX_FIELD_SIZE DECIMAL_MAX_PRECISION
74
75inline int my_decimal_int_part(uint32_t precision, uint32_t decimals)
76{
77 return precision - ((decimals == DECIMAL_NOT_SPECIFIED) ? 0 : decimals);
78}
79
80
81/**
82 my_decimal class limits 'decimal_t' type to what we need in MySQL.
83
84 It contains internally all necessary space needed by the instance so
85 no extra memory is needed. One should call fix_buffer_pointer() function
86 when he moves my_decimal objects in memory.
87*/
88
89class my_decimal :public decimal_t
90{
91 decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
92
93public:
94
95 void init()
96 {
97 len= DECIMAL_BUFF_LENGTH;
98 buf= buffer;
99#if !defined (HAVE_purify)
100 /* Set buffer to 'random' value to find wrong buffer usage */
101 for (uint32_t i= 0; i < DECIMAL_BUFF_LENGTH; i++)
102 buffer[i]= i;
103#endif
104 }
105 my_decimal()
106 {
107 init();
108 }
109 void fix_buffer_pointer() { buf= buffer; }
110
111 bool sign() const { return decimal_t::sign; }
112 void sign(bool s) { decimal_t::sign= s; }
113 uint32_t precision() const { return intg + frac; }
114};
115
116int decimal_operation_results(int result);
117
118inline
119void max_my_decimal(my_decimal *to, int precision, int frac)
120{
121 assert((precision <= DECIMAL_MAX_PRECISION)&&
122 (frac <= DECIMAL_MAX_SCALE));
123 max_decimal(precision, frac, (decimal_t*) to);
124}
125
126inline void max_internal_decimal(my_decimal *to)
127{
128 max_my_decimal(to, DECIMAL_MAX_PRECISION, 0);
129}
130
131inline int check_result(uint32_t mask, int result)
132{
133 if (result & mask)
134 decimal_operation_results(result);
135 return result;
136}
137
138inline int check_result_and_overflow(uint32_t mask, int result, my_decimal *val)
139{
140 if (check_result(mask, result) & E_DEC_OVERFLOW)
141 {
142 bool sign= val->sign();
143 val->fix_buffer_pointer();
144 max_internal_decimal(val);
145 val->sign(sign);
146 }
147 return result;
148}
149
150inline uint32_t my_decimal_length_to_precision(uint32_t length, uint32_t scale,
151 bool unsigned_flag)
152{
153 return (uint32_t) (length - (scale>0 ? 1:0) - (unsigned_flag ? 0:1));
154}
155
156inline uint32_t my_decimal_precision_to_length(uint32_t precision, uint8_t scale,
157 bool unsigned_flag)
158{
159 set_if_smaller(precision, (uint32_t)DECIMAL_MAX_PRECISION);
160 return static_cast<uint32_t>(precision + (scale>0 ? 1:0) + (unsigned_flag ? 0:1));
161}
162
163inline
164int my_decimal_string_length(const my_decimal *d)
165{
166 return decimal_string_size(d);
167}
168
169
170inline
171int my_decimal_max_length(const my_decimal *d)
172{
173 /* -1 because we do not count \0 */
174 return decimal_string_size(d) - 1;
175}
176
177
178inline
179int my_decimal_get_binary_size(uint32_t precision, uint32_t scale)
180{
181 return decimal_bin_size(static_cast<int>(precision), static_cast<int>(scale));
182}
183
184
185inline
186void my_decimal2decimal(const my_decimal *from, my_decimal *to)
187{
188 *to= *from;
189 to->fix_buffer_pointer();
190}
191
192
193int my_decimal2binary(uint32_t mask, const my_decimal *d, unsigned char *bin, int prec,
194 int scale);
195
196
197inline
198int binary2my_decimal(uint32_t mask, const unsigned char *bin, my_decimal *d, int prec,
199 int scale)
200{
201 return check_result(mask, bin2decimal(bin, static_cast<decimal_t*>(d), prec, scale));
202}
203
204
205inline
206int my_decimal_set_zero(my_decimal *d)
207{
208 decimal_make_zero(static_cast<decimal_t*> (d));
209 return 0;
210}
211
212
213inline
214bool my_decimal_is_zero(const my_decimal *decimal_value)
215{
216 return decimal_is_zero(static_cast<const decimal_t*>(decimal_value));
217}
218
219
220inline
221int my_decimal_round(uint32_t mask, const my_decimal *from, int scale,
222 bool truncate, my_decimal *to)
223{
224 return check_result(mask, decimal_round(static_cast<const decimal_t*>(from), to, scale,
225 (truncate ? TRUNCATE : HALF_UP)));
226}
227
228
229inline
230int my_decimal_floor(uint32_t mask, const my_decimal *from, my_decimal *to)
231{
232 return check_result(mask, decimal_round(static_cast<const decimal_t*>(from), to, 0, FLOOR));
233}
234
235
236inline
237int my_decimal_ceiling(uint32_t mask, const my_decimal *from, my_decimal *to)
238{
239 return check_result(mask, decimal_round(static_cast<const decimal_t*>(from), to, 0, CEILING));
240}
241
242
243int my_decimal2string(uint32_t mask, const my_decimal *d, uint32_t fixed_prec,
244 uint32_t fixed_dec, char filler, String *str);
245
246inline
247int my_decimal2int(uint32_t mask, const my_decimal *d, bool unsigned_flag,
248 int64_t *l)
249{
250 my_decimal rounded;
251 /* decimal_round can return only E_DEC_TRUNCATED */
252 decimal_round(static_cast<const decimal_t*>(d), &rounded, 0, HALF_UP);
253 return check_result(mask, (unsigned_flag ?
254 decimal2uint64_t(&rounded, reinterpret_cast<uint64_t *>(l)) :
255 decimal2int64_t(&rounded, l)));
256}
257
258
259inline
260int my_decimal2double(uint32_t, const my_decimal *d, double *result)
261{
262 /* No need to call check_result as this will always succeed */
263 return decimal2double(static_cast<const decimal_t*>(d), result);
264}
265
266
267inline
268int str2my_decimal(uint32_t mask, char *str, my_decimal *d, char **end)
269{
270 return check_result_and_overflow(mask, string2decimal(str, static_cast<decimal_t*>(d),end),
271 d);
272}
273
274
275int str2my_decimal(uint32_t mask, const char *from, uint32_t length,
276 const CHARSET_INFO * charset, my_decimal *decimal_value);
277
278inline
279int string2my_decimal(uint32_t mask, const String *str, my_decimal *d)
280{
281 return str2my_decimal(mask, str->ptr(), str->length(), str->charset(), d);
282}
283
284
285my_decimal *date2my_decimal(DRIZZLE_TIME *ltime, my_decimal *dec);
286
287
288inline
289int double2my_decimal(uint32_t mask, double val, my_decimal *d)
290{
291 return check_result_and_overflow(mask, double2decimal(val, static_cast<decimal_t*>(d)), d);
292}
293
294
295inline
296int int2my_decimal(uint32_t mask, int64_t i, bool unsigned_flag, my_decimal *d)
297{
298 return check_result(mask, (unsigned_flag ?
299 uint64_t2decimal(static_cast<uint64_t>(i), d) :
300 int64_t2decimal(i, d)));
301}
302
303
304inline
305void my_decimal_neg(decimal_t *arg)
306{
307 if (decimal_is_zero(arg))
308 {
309 arg->sign= 0;
310 return;
311 }
312 decimal_neg(arg);
313}
314
315
316inline
317int my_decimal_add(uint32_t mask, my_decimal *res, const my_decimal *a,
318 const my_decimal *b)
319{
320 return check_result_and_overflow(mask,
321 decimal_add(static_cast<const decimal_t*>(a),
322 static_cast<const decimal_t*>(b), res),
323 res);
324}
325
326
327inline
328int my_decimal_sub(uint32_t mask, my_decimal *res, const my_decimal *a,
329 const my_decimal *b)
330{
331 return check_result_and_overflow(mask,
332 decimal_sub(static_cast<const decimal_t*>(a),
333 static_cast<const decimal_t*>(b), res),
334 res);
335}
336
337
338inline
339int my_decimal_mul(uint32_t mask, my_decimal *res, const my_decimal *a,
340 const my_decimal *b)
341{
342 return check_result_and_overflow(mask,
343 decimal_mul(static_cast<const decimal_t*>(a),
344 static_cast<const decimal_t*>(b),res),
345 res);
346}
347
348
349inline
350int my_decimal_div(uint32_t mask, my_decimal *res, const my_decimal *a,
351 const my_decimal *b, int div_scale_inc)
352{
353 return check_result_and_overflow(mask,
354 decimal_div(static_cast<const decimal_t*>(a),
355 static_cast<const decimal_t*>(b),res,
356 div_scale_inc),
357 res);
358}
359
360
361inline
362int my_decimal_mod(uint32_t mask, my_decimal *res, const my_decimal *a,
363 const my_decimal *b)
364{
365 return check_result_and_overflow(mask,
366 decimal_mod(static_cast<const decimal_t*>(a),
367 static_cast<const decimal_t*>(b),res),
368 res);
369}
370
371
372/**
373 @return
374 -1 if a<b, 1 if a>b and 0 if a==b
375*/
376inline
377int my_decimal_cmp(const my_decimal *a, const my_decimal *b)
378{
379 return decimal_cmp(static_cast<const decimal_t*>(a),
380 static_cast<const decimal_t*>(b));
381}
382
383
384inline
385int my_decimal_intg(const my_decimal *a)
386{
387 return decimal_intg(static_cast<const decimal_t*>(a));
388}
389
390
391void my_decimal_trim(uint32_t *precision, uint32_t *scale);
392
393} /* namespace drizzled */
394
395#endif /* DRIZZLED_MY_DECIMAL_H */
3960
=== modified file 'drizzled/temporal.cc'
--- drizzled/temporal.cc 2010-02-04 08:14:46 +0000
+++ drizzled/temporal.cc 2010-03-28 01:34:23 +0000
@@ -37,7 +37,7 @@
37#include "config.h"37#include "config.h"
3838
39#include "drizzled/charset_info.h"39#include "drizzled/charset_info.h"
40#include "drizzled/my_decimal.h"40#include "drizzled/decimal.h"
41#include "drizzled/calendar.h"41#include "drizzled/calendar.h"
42#include "drizzled/temporal.h"42#include "drizzled/temporal.h"
43#ifdef NOTYETIMPLEMENTED43#ifdef NOTYETIMPLEMENTED
4444
=== modified file 'support-files/drizzle.spec.in'
--- support-files/drizzle.spec.in 2010-02-12 20:53:27 +0000
+++ support-files/drizzle.spec.in 2010-03-28 01:34:23 +0000
@@ -312,7 +312,6 @@
312%{_includedir}/drizzled/message/statement_transform.h312%{_includedir}/drizzled/message/statement_transform.h
313%{_includedir}/drizzled/message/table.pb.h313%{_includedir}/drizzled/message/table.pb.h
314%{_includedir}/drizzled/message/transaction.pb.h314%{_includedir}/drizzled/message/transaction.pb.h
315%{_includedir}/drizzled/my_decimal.h
316%{_includedir}/drizzled/my_error.h315%{_includedir}/drizzled/my_error.h
317%{_includedir}/drizzled/my_getopt.h316%{_includedir}/drizzled/my_getopt.h
318%{_includedir}/drizzled/my_hash.h317%{_includedir}/drizzled/my_hash.h