CUBRID Engine  latest
numeric_opfunc.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * numeric_opfunc.c - Basig manipulations of DB_NUMERIC type data
21  */
22 
23 #ident "$Id$"
24 
25 /* The bits in the character string of a DB_NUMERIC are the binary digits of
26  * the number. The LSB's of the DB_NUMERIC are in buf[DB_NUMERIC_BUF_SIZE-1].
27  */
28 
29 #include <float.h>
30 #include <math.h>
31 #include <assert.h>
32 #include <stdio.h>
33 #include <string.h>
34 
35 #include "mprec.h"
36 #include "numeric_opfunc.h"
37 #include "tz_support.h"
38 #include "db_date.h"
39 #include "memory_alloc.h"
40 #include "system_parameter.h"
41 #include "byte_order.h"
42 #include "object_primitive.h"
43 #include "object_representation.h"
44 
45 #if defined (__cplusplus)
46 #include <cmath>
47 #endif
48 
49 #include "dbtype.h"
50 
51 #if defined (SUPPRESS_STRLEN_WARNING)
52 #define strlen(s1) ((int) strlen(s1))
53 #endif /* defined (SUPPRESS_STRLEN_WARNING) */
54 
55 /* the multipler of long NUMERIC, internal used */
56 #define DB_LONG_NUMERIC_MULTIPLIER 2
57 
58 #define CARRYOVER(arg) ((arg) >> 8)
59 #define GET_LOWER_BYTE(arg) ((arg) & 0xff)
60 #define NUMERIC_ABS(a) ((a) >= 0 ? a : -a)
61 #define TWICE_NUM_MAX_PREC (2*DB_MAX_NUMERIC_PRECISION)
62 #define SECONDS_IN_A_DAY (int)(24L * 60L * 60L)
63 
64 #define ROUND(x) ((x) > 0 ? ((x) + .5) : ((x) - .5))
65 
66 typedef struct dec_string DEC_STRING;
67 struct dec_string
68 {
70 };
71 
72 static const char fast_mod[20] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
73  0, 1, 2, 3, 4, 5, 6, 7, 8, 9
74 };
75 
77 #if !defined(SERVER_MODE)
78 static bool initialized_2 = false;
79 #endif
81 #if !defined(SERVER_MODE)
82 static bool initialized_10 = false;
83 #endif
84 
85 static double numeric_Pow_of_10[10] = {
86  1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9
87 };
88 
89 typedef enum fp_value_type
90 {
95 }
97 
98 static bool numeric_is_negative (DB_C_NUMERIC arg);
99 static void numeric_copy (DB_C_NUMERIC dest, DB_C_NUMERIC source);
100 static void numeric_copy_long (DB_C_NUMERIC dest, DB_C_NUMERIC source, bool is_long_num);
101 static void numeric_increase (DB_C_NUMERIC answer);
102 static void numeric_increase_long (DB_C_NUMERIC answer, bool is_long_num);
103 static void numeric_decrease (DB_C_NUMERIC answer);
104 static void numeric_zero (DB_C_NUMERIC answer, int size);
105 static void numeric_init_dec_str (DEC_STRING * answer);
106 static void numeric_add_dec_str (DEC_STRING * arg1, DEC_STRING * arg2, DEC_STRING * answer);
107 static void numeric_init_pow_of_2_helper (void);
108 #if defined(SERVER_MODE)
109 static void numeric_init_pow_of_2 (void);
110 #endif
111 static DEC_STRING *numeric_get_pow_of_2 (int exp);
112 static void numeric_init_pow_of_10_helper (void);
113 #if defined(SERVER_MODE)
114 static void numeric_init_pow_of_10 (void);
115 #endif
116 static DB_C_NUMERIC numeric_get_pow_of_10 (int exp);
117 static void numeric_double_shift_bit (DB_C_NUMERIC arg1, DB_C_NUMERIC arg2, int numbits, DB_C_NUMERIC lsb,
118  DB_C_NUMERIC msb, bool is_long_num);
119 static int numeric_compare_pos (DB_C_NUMERIC arg1, DB_C_NUMERIC arg2);
120 static void numeric_negate (DB_C_NUMERIC answer);
121 static void numeric_negate_long (DB_C_NUMERIC answer, bool is_long_num);
122 static void numeric_shift_byte (DB_C_NUMERIC arg, int numbytes, DB_C_NUMERIC answer, int length);
123 static bool numeric_is_zero (DB_C_NUMERIC arg);
124 static bool numeric_is_long (DB_C_NUMERIC arg);
125 static bool numeric_is_bigint (DB_C_NUMERIC arg);
126 static bool numeric_is_bit_set (DB_C_NUMERIC arg, int pos);
127 static bool numeric_overflow (DB_C_NUMERIC arg, int exp);
128 static void numeric_add (DB_C_NUMERIC arg1, DB_C_NUMERIC arg2, DB_C_NUMERIC answer, int size);
129 static void numeric_sub (DB_C_NUMERIC arg1, DB_C_NUMERIC arg2, DB_C_NUMERIC answer, int size);
130 static void numeric_mul (DB_C_NUMERIC a1, DB_C_NUMERIC a2, bool * positive_flag, DB_C_NUMERIC answer);
131 static void numeric_long_div (DB_C_NUMERIC a1, DB_C_NUMERIC a2, DB_C_NUMERIC answer, DB_C_NUMERIC remainder,
132  bool is_long_num);
133 static void numeric_div (DB_C_NUMERIC arg1, DB_C_NUMERIC arg2, DB_C_NUMERIC answer, DB_C_NUMERIC remainder);
134 static int numeric_compare (DB_C_NUMERIC arg1, DB_C_NUMERIC arg2);
135 static int numeric_scale_by_ten (DB_C_NUMERIC arg, bool is_long_num);
136 static int numeric_scale_dec (const DB_C_NUMERIC arg, int dscale, DB_C_NUMERIC answer);
137 static int numeric_scale_dec_long (DB_C_NUMERIC answer, int dscale, bool is_long_num);
138 static int numeric_common_prec_scale (const DB_VALUE * dbv1, const DB_VALUE * dbv2, DB_VALUE * dbv1_common,
139  DB_VALUE * dbv2_common);
140 static int numeric_prec_scale_when_overflow (const DB_VALUE * dbv1, const DB_VALUE * dbv2, DB_VALUE * dbv1_common,
141  DB_VALUE * dbv2_common);
142 static void numeric_coerce_big_num_to_dec_str (unsigned char *num, char *dec_str);
143 static int numeric_get_msb_for_dec (int src_prec, int src_scale, unsigned char *src, int *dest_prec, int *dest_scale,
144  DB_C_NUMERIC dest);
145 static int numeric_fast_convert (double adouble, int dst_scale, DB_C_NUMERIC num, int *prec, int *scale);
146 static FP_VALUE_TYPE get_fp_value_type (double d);
147 static int numeric_internal_real_to_num (double adouble, int dst_scale, DB_C_NUMERIC num, int *prec, int *scale,
148  bool is_float);
149 static void numeric_get_integral_part (const DB_C_NUMERIC num, const int src_prec, const int src_scale,
150  const int dst_prec, DB_C_NUMERIC dest);
151 static void numeric_get_fractional_part (const DB_C_NUMERIC num, const int src_scale, const int dst_prec,
152  DB_C_NUMERIC dest);
153 static bool numeric_is_fraction_part_zero (const DB_C_NUMERIC num, const int scale);
154 static bool numeric_is_longnum_value (DB_C_NUMERIC arg);
155 static int numeric_longnum_to_shortnum (DB_C_NUMERIC answer, DB_C_NUMERIC long_arg);
156 static void numeric_shortnum_to_longnum (DB_C_NUMERIC long_answer, DB_C_NUMERIC arg);
157 static int get_significant_digit (DB_BIGINT i);
158 /*
159  * numeric_is_negative () -
160  * return: true, false
161  * arg(in) : DB_C_NUMERIC value
162  */
163 static bool
165 {
166  return (arg[0] & 0x80) ? true : false;
167 }
168 
169 /*
170  * numeric_copy () -
171  * return:
172  * dest(out) : DB_C_NUMERIC value
173  * source(in) : DB_C_NUMERIC value
174  * Note: This routine returns source copied into dest.
175  */
176 static void
178 {
179  numeric_copy_long (dest, source, false);
180 }
181 
182 /*
183  * numeric_copy_long () -
184  * return:
185  * dest(out) : DB_C_NUMERIC value
186  * source(in) : DB_C_NUMERIC value
187  * is_long_num(in): is long NUMERIC
188  * Note: This routine returns source copied into dest.
189  */
190 static void
191 numeric_copy_long (DB_C_NUMERIC dest, DB_C_NUMERIC source, bool is_long_num)
192 {
193  int num_cnt = 1;
194 
195  if (dest != source)
196  {
197  if (source == NULL || dest == NULL)
198  {
199  assert (0);
200  return;
201  }
202 
203  if (is_long_num)
204  {
205  num_cnt = DB_LONG_NUMERIC_MULTIPLIER;
206  }
207  memcpy (dest, source, DB_NUMERIC_BUF_SIZE * num_cnt);
208  }
209 }
210 
211 /*
212  * numeric_increase () -
213  * return:
214  * answer(in/out) : DB_C_NUMERIC value
215  *
216  * Note: This routine increments a numeric value.
217  */
218 static void
220 {
221  numeric_increase_long (answer, false);
222 }
223 
224 /*
225  * numeric_increase_long () -
226  * return:
227  * answer(in/out) : DB_C_NUMERIC value
228  * is_long_num(in): is long NUMERIC
229  *
230  * Note: This routine increments a numeric value.
231  */
232 static void
233 numeric_increase_long (DB_C_NUMERIC answer, bool is_long_num)
234 {
235  int carry = 1;
236  int digit;
237 
238  if (is_long_num)
239  {
241  }
242  else
243  {
244  digit = DB_NUMERIC_BUF_SIZE - 1;
245  }
246  /* Loop through answer as long as there is a carry */
247  for (; digit >= 0 && carry == 1; digit--)
248  {
249  answer[digit] += 1;
250  carry = (answer[digit] == 0) ? 1 : 0;
251  }
252 }
253 
254 /*
255  * numeric_decrease () -
256  * return:
257  * answer(in/out) : DB_C_NUMERIC value
258  *
259  * Note: This routine decrements a numeric value.
260  */
261 static void
263 {
264  int carry = 1;
265  int digit;
266 
267  /* Loop through answer as long as there is a carry */
268  for (digit = DB_NUMERIC_BUF_SIZE - 1; digit >= 0 && carry == 1; digit--)
269  {
270  answer[digit] -= 1;
271  carry = (answer[digit] == 0xff) ? 1 : 0;
272  }
273 }
274 
275 /*
276  * numeric_zero () -
277  * return:
278  * answer(in) : DB_C_NUMERIC value
279  * size(in) :
280  *
281  * Note: This routine zeroes out a numeric value and returns the result
282  */
283 static void
284 numeric_zero (DB_C_NUMERIC answer, int size)
285 {
286  memset (answer, 0, size); /* sizeof(answer[0]) == 1 */
287 }
288 
289 /*
290  * numeric_negative_one () -
291  * return:
292  * answer(in) : DB_C_NUMERIC value
293  * size(in) :
294  *
295  * Note: This routine make a numeric value as -1
296  */
297 static void
299 {
300  memset (answer, 0xff, size);
301 }
302 
303 /*
304  * numeric_init_dec_str () -
305  * return:
306  * answer(in/out) : (IN/OUT) ptr to a DEC_STRING
307  *
308  * Note: Fills a DEC_STRING with -1 constant bytes and zero rightmost byte
309  *
310  * digits:[00][01][02]......[73][74][75]
311  * values: -1 -1 -1 ...... -1 -1 0
312  */
313 static void
315 {
316  /* sizeof(answer->digits[0]) == 1 */
317  memset (answer->digits, -1, TWICE_NUM_MAX_PREC);
318 
319  /* Set first element to 0 */
320  answer->digits[TWICE_NUM_MAX_PREC - 1] = 0;
321 }
322 
323 /*
324  * numeric_add_dec_str () -
325  * arg1(in) : ptr to a DEC_STRING
326  * arg2(in) : ptr to a DEC_STRING
327  * answer(out): ptr to a DEC_STRING
328  *
329  * Note: This routine adds two DEC_STRINGs and returns the result. It assumes
330  * that arg1 and arg2 have the same scaling.
331  */
332 
333 static void
335 {
336  unsigned int answer_bit = 0;
337  int digit;
338  char arg1_dec, arg2_dec;
339 
340  /* Loop through the characters setting answer */
341  for (digit = TWICE_NUM_MAX_PREC - 1; digit >= 0; digit--)
342  {
343  arg1_dec = arg1->digits[digit];
344  arg2_dec = arg2->digits[digit];
345 
346  if (arg1_dec == -1)
347  {
348  arg1_dec = 0;
349 
350  if (answer_bit < 10)
351  {
352  break; /* pass through the leftmost digits */
353  }
354  }
355 
356  if (arg2_dec == -1)
357  {
358  /* is not first element */
359  assert (digit < TWICE_NUM_MAX_PREC - 1);
360 
361  arg2_dec = 0;
362  }
363 
364  assert (arg1_dec >= 0);
365  assert (arg2_dec >= 0);
366 
367  answer_bit = (arg1_dec + arg2_dec) + (answer_bit >= 10);
368  answer->digits[digit] = fast_mod[answer_bit];
369  }
370 }
371 
372 /*
373  * numeric_init_pow_of_2_helper () -
374  * return:
375  */
376 static void
378 {
379  unsigned int i;
380 
381  numeric_init_dec_str (&(powers_of_2[0]));
382 
383  /* Set first element to 1 */
384  powers_of_2[0].digits[TWICE_NUM_MAX_PREC - 1] = 1;
385 
386  /* Loop through array elements setting each one to twice the prior */
387  for (i = 1; i < DB_NUMERIC_BUF_SIZE * 16; i++)
388  {
389  numeric_init_dec_str (&(powers_of_2[i]));
390  numeric_add_dec_str (&(powers_of_2[i - 1]), &(powers_of_2[i - 1]), &(powers_of_2[i]));
391  }
392 }
393 
394 #if defined(SERVER_MODE)
395 /*
396  * numeric_init_pow_of_2 () -
397  * return:
398  */
399 static void
400 numeric_init_pow_of_2 (void)
401 {
403 }
404 #endif
405 
406 /*
407  * numeric_get_pow_of_2 () -
408  * return: DEC_STRING containing the equivalent base 10 representation
409  * exp(in) : positive integer exponent base 2
410  *
411  * Note: This routine returns a DEC_STRING that holds the base 10 digits of a
412  * power of 2.
413  */
414 static DEC_STRING *
416 {
417  assert (exp < (int) (DB_NUMERIC_BUF_SIZE * 16 - 3)); /* exp < 253 */
418 
419 #if !defined(SERVER_MODE)
420  /* If this is the first time to call this routine, initialize */
421  if (!initialized_2)
422  {
424  initialized_2 = true;
425  }
426 #endif
427 
428  /* Return the appropriate power of 2 */
429  return &powers_of_2[exp];
430 }
431 
432 /*
433  * numeric_init_pow_of_10_helper () -
434  * return:
435  */
436 static void
438 {
439  int i;
440 
442 
443  /* Set first element to 1 */
444  powers_of_10[0][DB_NUMERIC_BUF_SIZE - 1] = 1;
445 
446  /* Loop through elements setting each one to 10 times the prior */
447  for (i = 1; i < TWICE_NUM_MAX_PREC + 1; i++)
448  {
450  }
451 }
452 
453 #if defined(SERVER_MODE)
454 /*
455  * numeric_init_pow_of_10 () -
456  * return:
457  */
458 static void
459 numeric_init_pow_of_10 (void)
460 {
462 }
463 #endif
464 
465 /*
466  * numeric_get_pow_of_10 () -
467  * return: DB_C_NUMERIC containing the equivalent base 2 representation
468  * exp(in) : positive integer exponent base 10
469  *
470  * Note: This routine returns a DB_C_NUMERIC that holds the base 2 digits of a
471  * power of 10.
472  */
473 static DB_C_NUMERIC
475 {
476  assert (exp < (int) sizeof (powers_of_10));
477 
478 #if !defined(SERVER_MODE)
479  /* If this is the first time to call this routine, initialize */
480  if (!initialized_10)
481  {
483  initialized_10 = true;
484  }
485 #endif
486 
487  /* Return the appropriate power of 10 */
488  return powers_of_10[exp];
489 }
490 
491 #if defined(SERVER_MODE)
492 /*
493  * numeric_init_power_value_string () -
494  * return:
495  */
496 void
497 numeric_init_power_value_string (void)
498 {
499  numeric_init_pow_of_2 ();
500  numeric_init_pow_of_10 ();
501 }
502 #endif
503 
504 /*
505  * numeric_double_shift_bit () -
506  * return:
507  * arg1(in) : DB_C_NUMERIC
508  * arg2(in) : DB_C_NUMERIC
509  * numbits(in): integer number of bits to shift
510  * lsb(out) : DB_C_NUMERIC
511  * msb(out) : DB_C_NUMERIC
512  * is_long_num(in) : is long NUMERIC.
513  *
514  * Note: This routine returns lsb, msb shifted by numbits from arg1, arg2.
515  * Bits that are shifted out of arg1 are placed into LSB of arg2.
516  * only arg1 and lsb may be long NUMERIC.
517  */
518 static void
520  bool is_long_num)
521 {
522  /* the largest buf size of DB_C_NUMERIC */
523  unsigned char local_arg1[DB_NUMERIC_BUF_SIZE * DB_LONG_NUMERIC_MULTIPLIER];
524  unsigned char local_arg2[DB_NUMERIC_BUF_SIZE]; /* copy of a DB_C_NUMERIC */
525  unsigned int digit;
526  unsigned int buf_size;
527 
528  if (is_long_num)
529  {
531  }
532  else
533  {
534  buf_size = DB_NUMERIC_BUF_SIZE;
535  }
536 
537  /* Copy args into local variables */
538  numeric_copy_long (local_arg1, arg1, is_long_num);
539  numeric_copy (local_arg2, arg2);
540 
541  /* Loop through all but last word of msb shifting bits */
542  for (digit = 0; digit < DB_NUMERIC_BUF_SIZE - 1; digit++)
543  {
544  msb[digit] = (local_arg2[digit] << numbits) | (local_arg2[digit + 1] >> (8 - numbits));
545  }
546 
547  /* Do last word of msb separately using upper word of lsb */
548  msb[DB_NUMERIC_BUF_SIZE - 1] = (local_arg2[DB_NUMERIC_BUF_SIZE - 1] << numbits) | (local_arg1[0] >> (8 - numbits));
549 
550  /* Loop through all but last word of lsb shifting bits */
551  for (digit = 0; digit < buf_size - 1; digit++)
552  {
553  lsb[digit] = (local_arg1[digit] << numbits) | (local_arg1[digit + 1] >> (8 - numbits));
554  }
555 
556  /* Do last word of lsb separately. */
557  lsb[buf_size - 1] = local_arg1[buf_size - 1] << numbits;
558 }
559 
560 /*
561  * numeric_compare_pos () -
562  * return: Integer flag indicating whether arg1 is less than arg2
563  * arg1(in) : DB_C_NUMERIC
564  * arg2(in) : DB_C_NUMERIC
565  *
566  * Note: This routine compares two positive DB_C_NUMERIC values.
567  * This function returns:
568  * -1 if arg1 < arg2
569  * 0 if arg1 = arg2 and
570  * 1 if arg1 > arg2.
571  */
572 static int
574 {
575  unsigned int digit;
576 
577  /* Loop through bytes looking for the largest */
578  for (digit = 0; digit < DB_NUMERIC_BUF_SIZE; digit++)
579  {
580  if (arg1[digit] != arg2[digit])
581  {
582  return (arg1[digit] > arg2[digit]) ? 1 : (-1);
583  }
584  }
585 
586  /* If all bytes have been compared, then args are equal */
587  return (0);
588 }
589 
590 /*
591  * numeric_negate () -
592  * return:
593  * answer(in/out) : DB_C_NUMERIC
594  *
595  * Note: This routine returns the negative (2's complement) of arg in answer.
596  * The argument answer is modified in place.
597  */
598 static void
600 {
601  numeric_negate_long (answer, false);
602 }
603 
604 /*
605  * numeric_negate_long () -
606  * return:
607  * answer(in/out) : DB_C_NUMERIC
608  * is_long_num(in): is long NUMERIC
609  *
610  * Note: This routine returns the negative (2's complement) of arg in answer.
611  * The argument answer is modified in place.
612  */
613 static void
614 numeric_negate_long (DB_C_NUMERIC answer, bool is_long_num)
615 {
616  unsigned int digit;
617  unsigned int buf_size;
618 
619  if (is_long_num)
620  {
622  }
623  else
624  {
625  buf_size = DB_NUMERIC_BUF_SIZE;
626  }
627 
628  /* Complement all bits of answer */
629  for (digit = 0; digit < buf_size; digit++)
630  {
631  answer[digit] = ~(answer[digit]);
632  }
633 
634  /* Add one to answer */
635  numeric_increase_long (answer, is_long_num);
636 }
637 
638 /*
639  * numeric_shift_byte () -
640  * return:
641  * arg(in) : DB_C_NUMERIC
642  * numbytes(in): integer number of bytes to shift
643  * answer(out) : DB_C_NUMERIC
644  * length(in) : Length in bytes of answer
645  *
646  * Note: This routine returns arg shifted by numbytes in answer. Empty bytes
647  * are zero filled.
648  */
649 static void
650 numeric_shift_byte (DB_C_NUMERIC arg, int numbytes, DB_C_NUMERIC answer, int length)
651 {
652  int digit;
653  int first;
654  int last;
655 
656  /* Loop through bytes in answer setting to 0 or arg1 */
657  first = length - DB_NUMERIC_BUF_SIZE - numbytes;
658  last = length - numbytes - 1;
659  for (digit = 0; digit < length; digit++)
660  {
661  if (first <= digit && digit <= last)
662  {
663  answer[digit] = arg[digit - first];
664  }
665  else
666  {
667  answer[digit] = 0;
668  }
669  }
670 }
671 
672 /*
673  * numeric_is_zero () -
674  * return: bool
675  * arg(in) : DB_C_NUMERIC
676  *
677  * Note: This routine checks if arg = 0.
678  * This function returns:
679  * true if arg1 = 0 and
680  * false otherwise.
681  */
682 static bool
684 {
685  unsigned int digit;
686 
687  /* Loop through arg's bits looking for non-zero values */
688  for (digit = 0; digit < DB_NUMERIC_BUF_SIZE; digit++)
689  {
690  if (arg[digit] != 0)
691  {
692  return (false);
693  }
694  }
695 
696  return (true);
697 }
698 
699 /*
700  * numeric_is_long () -
701  * return: bool
702  * arg(in) : DB_C_NUMERIC
703  *
704  * Note: This routine checks if -2**31 <= arg <= 2**31-1
705  */
706 static bool
708 {
709  unsigned int digit;
710  unsigned char pad;
711 
712  /* Get pad value */
713  pad = arg[0];
714  if (pad != 0xff && pad != 0)
715  {
716  return (false);
717  }
718 
719  /*
720  * Loop through arg's bits except the 32 LSB looking for non-sign
721  * extended values
722  */
723  for (digit = 1; digit < DB_NUMERIC_BUF_SIZE - sizeof (int); digit++)
724  {
725  if (arg[digit] != pad)
726  {
727  return (false);
728  }
729  }
730 
731  return (arg[digit] & 0x80) == (pad & 0x80) ? true : false;
732 }
733 
734 /*
735  * numeric_is_bigint () -
736  * return: bool
737  * arg(in) : DB_C_NUMERIC
738  *
739  * Note: This routine checks if -2**63 <= arg <= 2**63-1
740  */
741 static bool
743 {
744  unsigned int digit;
745  unsigned char pad;
746 
747  /* Get pad value */
748  pad = arg[0];
749  if (pad != 0xff && pad != 0)
750  {
751  return (false);
752  }
753 
754  /*
755  * Loop through arg's bits except the 64 LSB looking for non-sign
756  * extended values
757  */
758  for (digit = 1; digit < DB_NUMERIC_BUF_SIZE - sizeof (DB_BIGINT); digit++)
759  {
760  if (arg[digit] != pad)
761  {
762  return (false);
763  }
764  }
765 
766  return (arg[digit] & 0x80) == (pad & 0x80) ? true : false;
767 }
768 
769 /*
770  * numeric_is_bit_set () -
771  * return: bool
772  * arg(in) : DB_C_NUMERIC
773  * pos(in) : position of the bit inside arg
774  *
775  * Note: This routine checks if pos'th bit of arg is 1.
776  */
777 static bool
779 {
780  return ((arg[pos / 8]) & (0x01 << (7 - (pos % 8)))) ? true : false;
781 }
782 
783 /*
784  * numeric_overflow () -
785  * return: bool
786  * arg(in) : DB_C_NUMERIC
787  * exp(in) : exponent (base 10) of domain
788  *
789  * Note: This routine checks to see if arg overflows a domain of precision exp.
790  */
791 static bool
793 {
794  unsigned char narg[DB_NUMERIC_BUF_SIZE]; /* copy of a DB_C_NUMERIC */
795 
796  if (numeric_is_negative (arg))
797  {
798  numeric_copy (narg, arg);
799  numeric_negate (narg);
800  return (numeric_compare_pos (narg, numeric_get_pow_of_10 (exp)) >= 0) ? true : false;
801  }
802  else
803  {
804  return (numeric_compare_pos (arg, numeric_get_pow_of_10 (exp)) >= 0) ? true : false;
805  }
806 }
807 
808 /*
809  * numeric_add () -
810  * return:
811  * arg1(in) : DB_C_NUMERIC
812  * arg2(in) : DB_C_NUMERIC
813  * answer(out): DB_C_NUMERIC
814  * size(in) : int
815  *
816  * Note: This routine adds two numerics and returns the result. It assumes
817  * that arg1 and arg2 have the same scaling.
818  */
819 static void
820 numeric_add (DB_C_NUMERIC arg1, DB_C_NUMERIC arg2, DB_C_NUMERIC answer, int size)
821 {
822  unsigned int answer_bit = 0;
823  int digit;
824 
825  /* Loop through the characters setting answer */
826  for (digit = size - 1; digit >= 0; digit--)
827  {
828  answer_bit = (arg1[digit] + arg2[digit]) + CARRYOVER (answer_bit);
829  answer[digit] = GET_LOWER_BYTE (answer_bit);
830  }
831 }
832 
833 /*
834  * numeric_sub () -
835  * return:
836  * arg1(in) : DB_C_NUMERIC
837  * arg2(in) : DB_C_NUMERIC
838  * answer(out): DB_C_NUMERIC
839  * size(in) : int
840  *
841  * Note: This routine subtracts arg2 from arg1 returns the result.
842  * It assumes that arg1 and arg2 have the same scaling.
843  */
844 static void
845 numeric_sub (DB_C_NUMERIC arg1, DB_C_NUMERIC arg2, DB_C_NUMERIC answer, int size)
846 {
847  unsigned char neg_arg2[2 * DB_NUMERIC_BUF_SIZE]; /* copy of a DB_C_NUMERIC */
848 
849  /* Make arg2 negative (use 2's complement) */
850  numeric_copy (neg_arg2, arg2);
851  numeric_negate (neg_arg2);
852 
853  /* Add arg1 and neg_arg2 */
854  numeric_add (arg1, neg_arg2, answer, size);
855 }
856 
857 /*
858  * numeric_mul () -
859  * return:
860  * a1(in) : DB_C_NUMERIC
861  * a2(in) : DB_C_NUMERIC
862  * positive_ans(out): bool if the answer's is positive (true)
863  * or negative (false)
864  * answer(out) : DB_C_NUMERIC
865  *
866  * Note: This routine multiplies two numerics and returns the results.
867  */
868 static void
869 numeric_mul (DB_C_NUMERIC a1, DB_C_NUMERIC a2, bool * positive_ans, DB_C_NUMERIC answer)
870 {
871  unsigned int answer_bit;
872  int digit1;
873  int digit2;
874  int shift;
875  unsigned char temp_term[2 * DB_NUMERIC_BUF_SIZE]; /* copy of DB_C_NUMERIC */
876  unsigned char temp_arg1[2 * DB_NUMERIC_BUF_SIZE]; /* copy of DB_C_NUMERIC */
877  unsigned char temp_arg2[2 * DB_NUMERIC_BUF_SIZE]; /* copy of DB_C_NUMERIC */
878  unsigned char arg1[DB_NUMERIC_BUF_SIZE]; /* copy of DB_C_NUMERIC */
879  unsigned char arg2[DB_NUMERIC_BUF_SIZE]; /* copy of DB_C_NUMERIC */
880 
881  /* Initialize the answer */
882  numeric_zero (answer, 2 * DB_NUMERIC_BUF_SIZE);
883  *positive_ans = true;
884 
885  /* Check if either arg = 0 */
886  if (numeric_is_zero (a1) || numeric_is_zero (a2))
887  {
888  return;
889  }
890 
891  /* If arg1 is negative, toggle sign and make arg1 positive */
892  numeric_copy (arg1, a1);
893  numeric_copy (arg2, a2);
894  if (numeric_is_negative (arg1))
895  {
896  numeric_negate (arg1);
897  *positive_ans = false;
898  }
899 
900  /* If arg2 is negative, toggle sign and make arg2 positive */
901  if (numeric_is_negative (arg2))
902  {
903  numeric_negate (arg2);
904  *positive_ans = !(*positive_ans);
905  }
906 
907  /* Initialize temporary variables */
908  numeric_zero (temp_arg2, DB_NUMERIC_BUF_SIZE);
909  numeric_copy (temp_arg2 + DB_NUMERIC_BUF_SIZE, arg2);
910 
911  /* Loop through the 8-bit digits of temp_arg2 */
912  shift = 0;
913  for (digit2 = (2 * DB_NUMERIC_BUF_SIZE) - 1; digit2 >= 0; digit2--)
914  {
915  if (temp_arg2[digit2] != 0)
916  {
917  answer_bit = 0;
918  numeric_shift_byte (arg1, shift, temp_arg1, 2 * DB_NUMERIC_BUF_SIZE);
919 
920  /* Loop through the 8-bit digits of temp_arg1 */
921  for (digit1 = (2 * DB_NUMERIC_BUF_SIZE - 1); digit1 >= 0; digit1--)
922  {
923  /* the unsigned int casts are necessary here to avoid 16 bit integer overflow during the multiplication
924  * on PC's */
925  answer_bit =
926  ((unsigned int) temp_arg1[digit1] * (unsigned int) temp_arg2[digit2]) +
927  (unsigned int) CARRYOVER (answer_bit);
928  temp_term[digit1] = GET_LOWER_BYTE (answer_bit);
929  }
930  numeric_add (temp_term, answer, answer, 2 * DB_NUMERIC_BUF_SIZE);
931  }
932  shift++;
933  }
934 }
935 
936 /*
937  * numeric_long_div () -
938  * return:
939  * a1(in) : DB_C_NUMERIC (numerator)
940  * a2(in) : DB_C_NUMERIC (denominator)
941  * answer(in) : DB_C_NUMERIC
942  * remainder(in) : DB_C_NUMERIC
943  * is_long_num(in) : is a1 and answer is long NUMERIC
944  *
945  * Note: This routine divides two numeric values and returns the
946  * result and remainder. This algorithm is based on the algorithm in
947  * "<Mark's Book>".
948  * Only a1(the dividend) and answer(the quotient) can be long numeric.
949  */
950 static void
951 numeric_long_div (DB_C_NUMERIC a1, DB_C_NUMERIC a2, DB_C_NUMERIC answer, DB_C_NUMERIC remainder, bool is_long_num)
952 {
953  unsigned int nbit, total_bit;
954  unsigned int buf_size;
955  /* the largest buf size for DB_C_NUMERIC */
956  unsigned char arg1[DB_LONG_NUMERIC_MULTIPLIER * DB_NUMERIC_BUF_SIZE];
957  unsigned char arg2[DB_NUMERIC_BUF_SIZE]; /* copy of a DB_C_NUMERIC */
958  unsigned char neg_arg2[DB_NUMERIC_BUF_SIZE]; /* copy of a DB_C_NUMERIC */
959  int neg_sign = 0;
960  int neg_remainder = false;
961 
962  /* calculate basic variables */
963  if (is_long_num)
964  {
966  }
967  else
968  {
969  buf_size = DB_NUMERIC_BUF_SIZE;
970  }
971 
972  total_bit = buf_size * 8;
973 
974  /* Copy inputs to local variables */
975  numeric_copy_long (arg1, a1, is_long_num);
976  numeric_copy (arg2, a2);
977 
978  /* If arg1 is negative, toggle sign and make arg1 positive */
979  if (numeric_is_negative (arg1))
980  {
981  numeric_negate_long (arg1, is_long_num);
982  neg_sign = ~neg_sign;
983  neg_remainder = true;
984  }
985 
986  /* If arg2 is negative, toggle sign and make arg2 positive */
987  if (numeric_is_negative (arg2))
988  {
989  numeric_negate (arg2);
990  neg_sign = ~neg_sign;
991  }
992 
993  /* Initialize variables */
994  numeric_coerce_int_to_num (0, remainder);
995  numeric_copy_long (answer, arg1, is_long_num);
996  numeric_copy (neg_arg2, arg2);
997  numeric_negate (neg_arg2);
998 
999  /* Shift *answer and *remainder. Bits shifted out of *answer * are placed into *remainder. */
1000  /***** NEEDS TO BE UPGRADED TO SHIFT SO THAT FIRST NON-ZERO BIT OF *****/
1001  /***** REMAINDER IS AT LEAST EQUAL TO FIRST NON_ZERO BIT OF ARG2. *****/
1002  /***** DON'T DO THIS ONE BIT AT A TIME. *****/
1003  for (nbit = 0; nbit < total_bit; nbit++)
1004  {
1005  numeric_double_shift_bit (answer, remainder, 1, answer, remainder, is_long_num);
1006 
1007  /* If remainder >= arg2, subtract arg2 from remainder and increment the answer. */
1008  if (numeric_compare_pos (remainder, arg2) >= 0)
1009  {
1010  numeric_add (remainder, neg_arg2, remainder, DB_NUMERIC_BUF_SIZE);
1011  answer[buf_size - 1] += 1;
1012  }
1013  }
1014 
1015  /* If the sign is negative, negate the answer */
1016  if (neg_sign)
1017  {
1018  numeric_negate_long (answer, is_long_num);
1019  }
1020 
1021  /* If the remainder is negative, negate it */
1022  if (neg_remainder)
1023  {
1024  numeric_negate (remainder);
1025  }
1026 }
1027 
1028 /*
1029  * numeric_div () -
1030  * return:
1031  * arg1(in) : DB_C_NUMERIC (numerator)
1032  * arg2(in) : DB_C_NUMERIC (denominator)
1033 
1034  * answer(in) : DB_C_NUMERIC
1035  * remainder(in) : DB_C_NUMERIC
1036  *
1037  * Note: This routine divides two numeric values and returns
1038  * the result and remainder. The division is broken down into 5 cases.
1039  * Given arg1/arg2:
1040  * a) if arg2 = 0, then SIGFPE ??, +/- MAX_NUM_DATA ??
1041  * b) if arg1 = 0, then answer = remainder = 0
1042  * c) if arg1, arg2 can be represented as a int
1043  * then answer = arg1/arg2, remainder = arg1%arg2
1044  * d) Otherwise, perform long division
1045  */
1046 static void
1048 {
1049  /* Case 1 - arg2 = 0 */
1050  if (numeric_is_zero (arg2))
1051  {
1052  /* SIGFPE ??, +/- MAX_NUM_DATA ?? */
1053  }
1054 
1055  /* Case 2 - arg1 = 0. Set answer and remainder to 0. */
1056  else if (numeric_is_zero (arg1))
1057  {
1058  numeric_coerce_int_to_num (0, remainder);
1059  numeric_coerce_int_to_num (0, answer);
1060  }
1061 
1062  /* Case 3 - arg1, arg2 are long ints. Do machine divide */
1063  else if (numeric_is_long (arg1) && numeric_is_long (arg2))
1064  {
1065  int long_arg1, long_arg2;
1066 
1067  numeric_coerce_num_to_int (arg1, &long_arg1);
1068  numeric_coerce_num_to_int (arg2, &long_arg2);
1069  numeric_coerce_int_to_num ((long_arg1 / long_arg2), answer);
1070  numeric_coerce_int_to_num ((long_arg1 % long_arg2), remainder);
1071  }
1072 
1073  /* Case 4 - arg1, arg2 are bigints. Do machine divide */
1074  else if (numeric_is_bigint (arg1) && numeric_is_bigint (arg2))
1075  {
1076  DB_BIGINT bi_arg1, bi_arg2;
1077 
1078  numeric_coerce_num_to_bigint (arg1, 0, &bi_arg1);
1079  numeric_coerce_num_to_bigint (arg2, 0, &bi_arg2);
1080  numeric_coerce_bigint_to_num ((bi_arg1 / bi_arg2), answer);
1081  numeric_coerce_bigint_to_num ((bi_arg1 % bi_arg2), remainder);
1082  }
1083 
1084  /* Default case: perform long division */
1085  else
1086  {
1087  numeric_long_div (arg1, arg2, answer, remainder, false);
1088  }
1089 }
1090 
1091 /*
1092  * numeric_is_longnum_value ()
1093  * return:
1094  * arg(in) : DB_C_NUMERIC
1095  *
1096  * Note: This routine check whether the value numeric is long NUMERIC.
1097  * Attention: the arg should be long NUMERIC.
1098  */
1099 static bool
1101 {
1102  int total_nums = (DB_LONG_NUMERIC_MULTIPLIER - 1) * DB_NUMERIC_BUF_SIZE;
1103  int i;
1104 
1105  if (numeric_is_negative (arg))
1106  {
1107  for (i = 0; i < total_nums; i++)
1108  {
1109  if (arg[i] != 0xff)
1110  {
1111  return true;
1112  }
1113  }
1114 
1115  if (!(arg[i] & 0x80))
1116  {
1117  return true;
1118  }
1119 
1120  }
1121  else
1122  {
1123  for (i = 0; i < total_nums; i++)
1124  {
1125  if (arg[i] != 0)
1126  {
1127  return true;
1128  }
1129  }
1130 
1131  if (arg[i] & 0x80)
1132  {
1133  return true;
1134  }
1135  }
1136 
1137  return false;
1138 }
1139 
1140 /*
1141  * numeric_shortnum_to_longnum ()
1142  * return:
1143  * long_answer(out): the long NUMERIC
1144  * arg(in) : DB_C_NUMERIC
1145  *
1146  * Note: This routine translate a normal NUMERIC to long NUMERIC.
1147  * Attention: the long_answer should be long NUMERIC.
1148  */
1149 static void
1151 {
1152  bool is_negative;
1153  int i;
1154 
1155  is_negative = numeric_is_negative (arg);
1156  for (i = 0; i < DB_LONG_NUMERIC_MULTIPLIER - 1; i++)
1157  {
1158  if (is_negative)
1159  {
1160  numeric_negative_one (long_answer + i * DB_NUMERIC_BUF_SIZE, DB_NUMERIC_BUF_SIZE);
1161  }
1162  else
1163  {
1164  numeric_zero (long_answer + i * DB_NUMERIC_BUF_SIZE, DB_NUMERIC_BUF_SIZE);
1165  }
1166  }
1167  numeric_copy (long_answer + i * DB_NUMERIC_BUF_SIZE, arg);
1168 }
1169 
1170 
1171 /*
1172  * numeric_longnum_to_shortnum ()
1173  * return:
1174  * answer(out): DB_C_NUMERIC
1175  * arg(in) : long NUMERIC
1176  *
1177  * Note: This routine translate a long NUMERIC to normal NUMERIC.
1178  * Attention: the long_answer should be long NUMERIC.
1179  */
1180 static int
1182 {
1183  if (numeric_is_longnum_value (long_arg))
1184  {
1185  return ER_IT_DATA_OVERFLOW;
1186  }
1187 
1188  numeric_copy (answer, long_arg + (DB_LONG_NUMERIC_MULTIPLIER - 1) * DB_NUMERIC_BUF_SIZE);
1189  return NO_ERROR;
1190 }
1191 
1192 /*
1193  * numeric_compare () -
1194  * return:
1195  * arg1(in) : DB_C_NUMERIC
1196  * arg2(in) : DB_C_NUMERIC
1197  *
1198  * Note: This routine compares two DB_C_NUMERIC values.
1199  * This function returns:
1200  * -1 if arg1 < arg2
1201  * 0 if arg1 = arg2 and
1202  * 1 if arg1 > arg2.
1203  */
1204 static int
1206 {
1207  unsigned char narg1[DB_NUMERIC_BUF_SIZE];
1208  unsigned char narg2[DB_NUMERIC_BUF_SIZE];
1209  int arg1_sign, arg2_sign; /* 0 if positive */
1210 
1211  arg1_sign = numeric_is_negative (arg1) ? 1 : 0;
1212  arg2_sign = numeric_is_negative (arg2) ? 1 : 0;
1213 
1214  if (arg1_sign < arg2_sign)
1215  { /* arg1 >= 0, arg2 < 0 */
1216  return (1);
1217  }
1218  else if (arg1_sign > arg2_sign)
1219  { /* arg1 < 0, arg2 >= 0 */
1220  return (-1);
1221  }
1222  else
1223  {
1224  if (arg1_sign == 0)
1225  { /* arg1 >= 0, arg2 >= 0 */
1226  return numeric_compare_pos (arg1, arg2);
1227  }
1228  else
1229  { /* arg1 < 0, arg2 < 0 */
1230  numeric_copy (narg1, arg1); /* need copy? */
1231  numeric_negate (narg1);
1232  numeric_copy (narg2, arg2); /* need copy? */
1233  numeric_negate (narg2);
1234  return -numeric_compare_pos (narg1, narg2);
1235  }
1236  }
1237 }
1238 
1239 /*
1240  * numeric_scale_by_ten () -
1241  * return: NO_ERROR, or ER_code (ER_IT_DATA_OVERFLOW)
1242  * arg(in/out) : ptr to a DB_NUMERIC structure
1243  * is_long_num(in): is long NUMERIC
1244  *
1245  * Note: This routine scales arg by a factor of ten.
1246  */
1247 static int
1248 numeric_scale_by_ten (DB_C_NUMERIC arg, bool is_long_num)
1249 {
1250  int i, answer;
1251  bool negative = false;
1252 
1253  answer = 0;
1254  if (numeric_is_negative (arg))
1255  {
1256  negative = true;
1257  numeric_negate_long (arg, is_long_num);
1258  }
1259 
1260  if (is_long_num)
1261  {
1263  }
1264  else
1265  {
1266  i = DB_NUMERIC_BUF_SIZE;
1267  }
1268  while (i--)
1269  {
1270  answer = (10 * arg[i]) + CARRYOVER (answer);
1271  arg[i] = GET_LOWER_BYTE (answer);
1272  }
1273 
1274  if ((int) arg[0] > 0x7f)
1275  {
1276  return ER_IT_DATA_OVERFLOW;
1277  }
1278 
1279  if (negative)
1280  {
1281  numeric_negate_long (arg, is_long_num);
1282  }
1283 
1284  return NO_ERROR;
1285 }
1286 
1287 /*
1288  * numeric_scale_dec () -
1289  * return: NO_ERROR, or ER_code
1290  * arg(in) : ptr to a DB_C_NUMERIC structure
1291  * dscale(in) : integer scaling factor (positive)
1292  * answer(in) : ptr to a DB_C_NUMERIC structure
1293  *
1294  * Note: This routine returns a numeric value that has been scaled by the
1295  * given number of decimal places. The result is returned in answer.
1296  */
1297 static int
1298 numeric_scale_dec (const DB_C_NUMERIC arg, int dscale, DB_C_NUMERIC answer)
1299 {
1300  int ret = NO_ERROR;
1301 
1302  if (dscale >= 0)
1303  {
1304  numeric_copy (answer, arg);
1305  ret = numeric_scale_dec_long (answer, dscale, false);
1306  }
1307 
1308  return ret;
1309 }
1310 
1311 /*
1312  * numeric_scale_dec_long () -
1313  * return: NO_ERROR, or ER_code
1314  * answer(in/out) : ptr to a DB_C_NUMERIC structure
1315  * dscale(in) : integer scaling factor (positive)
1316  * is_long_num: is long NUMERIC
1317  *
1318  * Note: This routine returns a numeric value that has been scaled by the
1319  * given number of decimal places. The result is returned in answer.
1320  */
1321 static int
1322 numeric_scale_dec_long (DB_C_NUMERIC answer, int dscale, bool is_long_num)
1323 {
1324  int loop;
1325  int ret = NO_ERROR;
1326 
1327  if (dscale >= 0)
1328  {
1329  for (loop = 0; loop < dscale && ret == NO_ERROR; loop++)
1330  {
1331  ret = numeric_scale_by_ten (answer, is_long_num);
1332  }
1333  if (ret != NO_ERROR)
1334  {
1335  return ret;
1336  }
1337  }
1338 
1339  return ret;
1340 }
1341 
1342 /*
1343  * numeric_common_prec_scale () -
1344  * return: NO_ERROR, or ER_code
1345  * Errors:
1346  * ER_IT_DATA_OVERFLOW - if scaling would exceed max scale
1347  * dbv1(in): ptr to a DB_VALUE structure of type DB_TYPE_NUMERIC
1348  * dbv2(in): ptr to a DB_VALUE structure of type DB_TYPE_NUMERIC
1349  * dbv1_common(out): ptr to a DB_VALUE structure of type DB_TYPE_NUMERIC
1350  * dbv2_common(out): ptr to a DB_VALUE structure of type DB_TYPE_NUMERIC
1351  *
1352  * Note: This routine returns two DB_VALUE's of type numeric with the same
1353  * scale. dbv1_common, dbv2_common are set to dbv1, dbv2 respectively
1354  * when an error occurs.
1355  */
1356 static int
1357 numeric_common_prec_scale (const DB_VALUE * dbv1, const DB_VALUE * dbv2, DB_VALUE * dbv1_common, DB_VALUE * dbv2_common)
1358 {
1359  unsigned char temp[DB_NUMERIC_BUF_SIZE]; /* copy of a DB_C_NUMERIC */
1360  int scale1, scale2;
1361  int prec1, prec2;
1362  int cprec;
1363  int scale_diff;
1364  TP_DOMAIN *domain;
1365 
1366  /* If scales already match, merely copy them and return */
1367  scale1 = DB_VALUE_SCALE (dbv1);
1368  scale2 = DB_VALUE_SCALE (dbv2);
1369  prec1 = DB_VALUE_PRECISION (dbv1);
1370  prec2 = DB_VALUE_PRECISION (dbv2);
1371  if (scale1 == scale2)
1372  {
1373  cprec = MAX (prec1, prec2);
1374  db_make_numeric (dbv1_common, db_locate_numeric (dbv1), cprec, scale1);
1375  db_make_numeric (dbv2_common, db_locate_numeric (dbv2), cprec, scale2);
1376  }
1377 
1378  /* Otherwise scale and reset the numbers */
1379  else if (scale1 < scale2)
1380  {
1381  scale_diff = scale2 - scale1;
1382  prec1 = scale_diff + prec1;
1383  if (prec1 > DB_MAX_NUMERIC_PRECISION)
1384  {
1387  return ER_IT_DATA_OVERFLOW;
1388  }
1389  numeric_scale_dec (db_locate_numeric (dbv1), scale_diff, temp);
1390  cprec = MAX (prec1, prec2);
1391  db_make_numeric (dbv1_common, temp, cprec, scale2);
1392  db_make_numeric (dbv2_common, db_locate_numeric (dbv2), cprec, scale2);
1393  }
1394  else
1395  {
1396  scale_diff = scale1 - scale2;
1397  prec2 = scale_diff + prec2;
1398  if (prec2 > DB_MAX_NUMERIC_PRECISION)
1399  {
1402  return ER_IT_DATA_OVERFLOW;
1403  }
1404  numeric_scale_dec (db_locate_numeric (dbv2), scale_diff, temp);
1405  cprec = MAX (prec1, prec2);
1406  db_make_numeric (dbv2_common, temp, cprec, scale1);
1407  db_make_numeric (dbv1_common, db_locate_numeric (dbv1), cprec, scale1);
1408  }
1409 
1410  return NO_ERROR;
1411 }
1412 
1413 /*
1414  * numeric_prec_scale_when_overflow () -
1415  * return: NO_ERROR, or ER_code
1416  * dbv1(in) :
1417  * dbv2(in) :
1418  * dbv1_common(out) :
1419  * dbv2_common(out) :
1420  */
1421 static int
1422 numeric_prec_scale_when_overflow (const DB_VALUE * dbv1, const DB_VALUE * dbv2, DB_VALUE * dbv1_common,
1423  DB_VALUE * dbv2_common)
1424 {
1425  int prec1, scale1, prec2, scale2;
1426  int prec, scale;
1427  unsigned char num1[DB_NUMERIC_BUF_SIZE], num2[DB_NUMERIC_BUF_SIZE];
1428  unsigned char temp[DB_NUMERIC_BUF_SIZE];
1429  int ret;
1430 
1431  prec1 = DB_VALUE_PRECISION (dbv1);
1432  prec2 = DB_VALUE_PRECISION (dbv2);
1433  scale1 = DB_VALUE_SCALE (dbv1);
1434  scale2 = DB_VALUE_SCALE (dbv2);
1435 
1436  scale = MAX (scale1, scale2);
1437  prec = DB_MAX_NUMERIC_PRECISION;
1438 
1439  numeric_copy (num1, db_locate_numeric (dbv1));
1440  numeric_copy (num2, db_locate_numeric (dbv2));
1441 
1442  ret = numeric_coerce_num_to_num (num1, prec1, scale1, prec, scale, temp);
1443  if (ret != NO_ERROR)
1444  {
1445  return ret;
1446  }
1447  db_make_numeric (dbv1_common, temp, prec, scale);
1448 
1449  ret = numeric_coerce_num_to_num (num2, prec2, scale2, prec, scale, temp);
1450  if (ret != NO_ERROR)
1451  {
1452  return ret;
1453  }
1454  db_make_numeric (dbv2_common, temp, prec, scale);
1455 
1456  return ret;
1457 }
1458 
1459 /*
1460  * numeric_coerce_big_num_to_dec_str () -
1461  * return:
1462  * num(in) : buffer twice the size of a DB_C_NUMERIC
1463  * dec_str(out): returned string of decimal digits as ASCII chars
1464  *
1465  * Note: This routine converts a DB_C_NUMERIC into a character string that is
1466  * TWICE_NUM_MAX_PREC characters long that contains the decimal digits of
1467  * the numeric encoded as ASCII characters.
1468  * THIS ROUTINE ASSUMES THAT THE NUMERIC BUFFER REPRESENTS A POSITIVE
1469  * VALUE.
1470  */
1471 static void
1472 numeric_coerce_big_num_to_dec_str (unsigned char *num, char *dec_str)
1473 {
1474  DEC_STRING *bit_value;
1475  DEC_STRING result;
1476  unsigned int i;
1477 
1478  /* Loop through the bits of the numeric building up string */
1479  numeric_init_dec_str (&result);
1480  for (i = 0; i < DB_NUMERIC_BUF_SIZE * 16; i++)
1481  {
1482  if (numeric_is_bit_set (num, i))
1483  {
1484  bit_value = numeric_get_pow_of_2 ((DB_NUMERIC_BUF_SIZE * 16) - i - 1);
1485  numeric_add_dec_str (bit_value, &result, &result);
1486  }
1487  }
1488 
1489  /* Convert result into ASCII array */
1490  for (i = 0; i < TWICE_NUM_MAX_PREC; i++)
1491  {
1492  if (result.digits[i] == -1)
1493  {
1494  result.digits[i] = 0;
1495  }
1496  assert (result.digits[i] >= 0);
1497 
1498  *dec_str = result.digits[i] + '0';
1499  dec_str++;
1500  }
1501 
1502  /* Null terminate */
1503  *dec_str = '\0';
1504 }
1505 
1506 /*
1507  * numeric_get_msb_for_dec () -
1508  * return:
1509  * Errors:
1510  * ER_IT_DATA_OVERFLOW - if src exceeds max precision
1511  * src_prec(in) : int precision of src
1512  * src_scale(in) : int scale of src
1513  * src(in) : buffer to NUMERIC twice the length of the maximum
1514  * dest_prec(out) : ptr to a int precision of dest
1515  * dest_scale(out) : ptr to a int scale of dest
1516  * dest(out) : DB_C_NUMERIC
1517  *
1518  * Note: This routine returns a DB_C_NUMERIC along with the precision and
1519  * scale of the MSB of the source. Round-off occurs as long as the scale
1520  * of the destination >= 0.
1521  * Note: it is assumed that src represents a positive number
1522  */
1523 static int
1524 numeric_get_msb_for_dec (int src_prec, int src_scale, unsigned char *src, int *dest_prec, int *dest_scale,
1525  DB_C_NUMERIC dest)
1526 {
1527  int ret = NO_ERROR;
1528  char dec_digits[TWICE_NUM_MAX_PREC + 2];
1529 
1530  /* If src precision fits without truncation, merely set dest to the lower half of the source buffer and return */
1531  if (src_prec <= DB_MAX_NUMERIC_PRECISION)
1532  {
1533  numeric_copy (dest, &(src[DB_NUMERIC_BUF_SIZE]));
1534  *dest_prec = src_prec;
1535  *dest_scale = src_scale;
1536  }
1537 
1538  /* The remaining cases are for when the precision of the source overflows. */
1539 
1540  /* Case 1: The scale of the source does *not* overflow */
1541  else if (src_scale <= DB_MAX_NUMERIC_PRECISION)
1542  {
1543  /* If upper half of *src is zero, merely copy, reset precision, and return */
1544  if (numeric_is_zero (src) && src[DB_NUMERIC_BUF_SIZE] <= 0x7F)
1545  {
1546  numeric_copy (dest, &(src[DB_NUMERIC_BUF_SIZE]));
1547  *dest_prec = DB_MAX_NUMERIC_PRECISION;
1548  *dest_scale = src_scale;
1549  }
1550  else
1551  {
1552  /* Can't truncate answer - expected results must maintain the proper amount of scaling */
1553  return ER_IT_DATA_OVERFLOW;
1554  }
1555  }
1556 
1557  /* Case 2: The scale of the source overflows. This means the number can't overflow as long as truncation occurs.
1558  * Reduce the scale and precision by the same amount. */
1559  else
1560  {
1561  int truncation_diff = src_prec - DB_MAX_NUMERIC_PRECISION;
1562 
1563  *dest_scale = src_scale - truncation_diff;
1564  *dest_prec = DB_MAX_NUMERIC_PRECISION;
1565 
1566  /* Truncate the obsolete trailing digits. (Note: numeric_coerce_big_num_to_dec_str is guaranteed ro return a
1567  * NULL-terminated buffer that is TWICE_NUM_MAX_PREC characters long.) */
1568  numeric_coerce_big_num_to_dec_str (src, dec_digits);
1569  dec_digits[TWICE_NUM_MAX_PREC - truncation_diff] = '\0';
1570  numeric_coerce_dec_str_to_num (dec_digits, dest);
1571  }
1572 
1573  return ret;
1574 }
1575 
1576 /*
1577  * numeric_db_value_add () -
1578  * return: NO_ERROR, or ER_code
1579  * Errors:
1580  * ER_OBJ_INVALID_ARGUMENTS - if dbv1, dbv2, or answer are NULL or
1581  * are not DB_TYPE_NUMERIC
1582  * dbv1(in) : ptr to a DB_VALUE structure of type DB_TYPE_NUMERIC
1583  * dbv2(in) : ptr to a DB_VALUE structure of type DB_TYPE_NUMERIC
1584  * answer(out): ptr to a DB_VALUE structure of type DB_TYPE_NUMERIC
1585  *
1586  * Note: This routine adds the numeric values of two DB_VALUE structs and
1587  * returns the results in answer. The answer will be returned as either the
1588  * common type of dbv1 and dbv2 or as the common type of dbv1 and dbv2 with
1589  * an extra decimal place of precision if the sum requires it due to carry.
1590  * The answer is set to a NULL-valued DB_C_NUMERIC's when an error occurs.
1591  *
1592  */
1593 int
1594 numeric_db_value_add (const DB_VALUE * dbv1, const DB_VALUE * dbv2, DB_VALUE * answer)
1595 {
1596  DB_VALUE dbv1_common, dbv2_common;
1597  int ret = NO_ERROR;
1598  unsigned int prec;
1599  unsigned char temp[DB_NUMERIC_BUF_SIZE]; /* Copy of a DB_C_NUMERIC */
1600  TP_DOMAIN *domain;
1601 
1602  /* Check for bad inputs */
1603  if (answer == NULL)
1604  {
1605  return ER_OBJ_INVALID_ARGUMENTS;
1606  }
1607  if (dbv1 == NULL || DB_VALUE_TYPE (dbv1) != DB_TYPE_NUMERIC)
1608  {
1609  db_make_null (answer);
1610  return ER_OBJ_INVALID_ARGUMENTS;
1611  }
1612  if (dbv2 == NULL || DB_VALUE_TYPE (dbv2) != DB_TYPE_NUMERIC)
1613  {
1614  db_make_null (answer);
1615  return ER_OBJ_INVALID_ARGUMENTS;
1616  }
1617 
1618  /* Check for NULL values */
1619  if (DB_IS_NULL (dbv1) || DB_IS_NULL (dbv2))
1620  {
1622  return NO_ERROR;
1623  }
1624 
1625  /* Coerce, if necessary, to make prec & scale match */
1626  ret = numeric_common_prec_scale (dbv1, dbv2, &dbv1_common, &dbv2_common);
1627  if (ret == ER_IT_DATA_OVERFLOW)
1628  {
1629  ret = numeric_prec_scale_when_overflow (dbv1, dbv2, &dbv1_common, &dbv2_common);
1630  if (ret != NO_ERROR)
1631  {
1632  goto exit_on_error;
1633  }
1634  else
1635  {
1636  er_clear ();
1637  }
1638  }
1639  else if (ret != NO_ERROR)
1640  {
1641  goto exit_on_error;
1642  }
1643 
1644  /* Perform the addition */
1645  numeric_add (db_locate_numeric (&dbv1_common), db_locate_numeric (&dbv2_common), temp, DB_NUMERIC_BUF_SIZE);
1646  /*
1647  * Update the domin information of the answer. Check to see if precision
1648  * needs to be updated due to carry
1649  */
1650  prec = DB_VALUE_PRECISION (&dbv1_common);
1651  if (numeric_overflow (temp, prec))
1652  {
1653  if (prec < DB_MAX_NUMERIC_PRECISION)
1654  {
1655  prec++;
1656  }
1657  else
1658  {
1661  ret = ER_IT_DATA_OVERFLOW;
1662  goto exit_on_error;
1663  }
1664  }
1665  db_make_numeric (answer, temp, prec, DB_VALUE_SCALE (&dbv1_common));
1666 
1667  return ret;
1668 
1669 exit_on_error:
1670 
1672 
1673  return (ret == NO_ERROR && (ret = er_errid ()) == NO_ERROR) ? ER_FAILED : ret;
1674 }
1675 
1676 /*
1677  * numeric_db_value_sub () -
1678  * return: NO_ERROR, or ER_code
1679  * Errors:
1680  * ER_OBJ_INVALID_ARGUMENTS - if dbv1, dbv2, or answer are NULL or
1681  * are not DB_TYPE_NUMERIC
1682  * dbv1(in) : ptr to a DB_VALUE structure of type DB_TYPE_NUMERIC
1683  * dbv2(in) : ptr to a DB_VALUE structure of type DB_TYPE_NUMERIC
1684  * answer(out): ptr to a DB_VALUE structure of type DB_TYPE_NUMERIC
1685  *
1686  * Note: This routine subtracts the numeric values of two DB_VALUE's and
1687  * returns the results in answer. The answer will be returned as either the
1688  * common type of dbv1 and dbv2 or as the common type of dbv1 and dbv2 with
1689  * an extra decimal place of precision if the sum requires it due to carry.
1690  *
1691  * The answer is set to a NULL-valued DB_C_NUMERIC's when an error occurs.
1692  */
1693 int
1694 numeric_db_value_sub (const DB_VALUE * dbv1, const DB_VALUE * dbv2, DB_VALUE * answer)
1695 {
1696  DB_VALUE dbv1_common, dbv2_common;
1697  int ret = NO_ERROR;
1698  unsigned int prec;
1699  unsigned char temp[DB_NUMERIC_BUF_SIZE]; /* Copy of a DB_C_NUMERIC */
1700  TP_DOMAIN *domain;
1701 
1702  /* Check for bad inputs */
1703  if (answer == NULL)
1704  {
1705  return ER_OBJ_INVALID_ARGUMENTS;
1706  }
1707  if (dbv1 == NULL || DB_VALUE_TYPE (dbv1) != DB_TYPE_NUMERIC)
1708  {
1709  db_make_null (answer);
1710  return ER_OBJ_INVALID_ARGUMENTS;
1711  }
1712  if (dbv2 == NULL || DB_VALUE_TYPE (dbv2) != DB_TYPE_NUMERIC)
1713  {
1714  db_make_null (answer);
1715  return ER_OBJ_INVALID_ARGUMENTS;
1716  }
1717 
1718  /* Check for NULL values */
1719  if (DB_IS_NULL (dbv1) || DB_IS_NULL (dbv2))
1720  {
1722  return NO_ERROR;
1723  }
1724 
1725  /* Coerce, if necessary, to make prec & scale match */
1726  ret = numeric_common_prec_scale (dbv1, dbv2, &dbv1_common, &dbv2_common);
1727  if (ret == ER_IT_DATA_OVERFLOW)
1728  {
1729  ret = numeric_prec_scale_when_overflow (dbv1, dbv2, &dbv1_common, &dbv2_common);
1730  if (ret != NO_ERROR)
1731  {
1732  goto exit_on_error;
1733  }
1734  else
1735  {
1736  er_clear ();
1737  }
1738  }
1739  else if (ret != NO_ERROR)
1740  {
1741  goto exit_on_error;
1742  }
1743 
1744  /* Perform the subtraction */
1745  numeric_sub (db_locate_numeric (&dbv1_common), db_locate_numeric (&dbv2_common), temp, DB_NUMERIC_BUF_SIZE);
1746  /*
1747  * Update the domin information of the answer. Check to see if precision
1748  * needs to be updated due to carry
1749  */
1750  prec = DB_VALUE_PRECISION (&dbv1_common);
1751  if (numeric_overflow (temp, prec))
1752  {
1753  if (prec < DB_MAX_NUMERIC_PRECISION)
1754  {
1755  prec++;
1756  }
1757  else
1758  {
1761  ret = ER_IT_DATA_OVERFLOW;
1762  goto exit_on_error;
1763  }
1764  }
1765  db_make_numeric (answer, temp, prec, DB_VALUE_SCALE (&dbv1_common));
1766 
1767  return ret;
1768 
1769 exit_on_error:
1770 
1772 
1773  return (ret == NO_ERROR && (ret = er_errid ()) == NO_ERROR) ? ER_FAILED : ret;
1774 }
1775 
1776 /*
1777  * numeric_db_value_mul () -
1778  * return: NO_ERROR, or ER_code
1779  * Errors:
1780  * ER_OBJ_INVALID_ARGUMENTS - if dbv1, dbv2, or answer are NULL or
1781  * are not DB_TYPE_NUMERIC
1782  * dbv1(in) : ptr to a DB_VALUE structure of type DB_TYPE_NUMERIC
1783  * dbv2(in) : ptr to a DB_VALUE structure of type DB_TYPE_NUMERIC
1784  * answer(out): ptr to a DB_VALUE structure of type DB_TYPE_NUMERIC
1785  *
1786  * Note: This routine multiplies the numeric values of two DB_VALUE's and
1787  * returns the results in answer. The answer will be returned as either the
1788  * common type of dbv1 and dbv2 or as the common type of dbv1 and dbv2 with
1789  * a extra decimal places of precision if the product requires it to avoid
1790  * loss of data.
1791  *
1792  * The answer is set to a NULL-valued DB_C_NUMERIC's when an error occurs.
1793  */
1794 int
1795 numeric_db_value_mul (const DB_VALUE * dbv1, const DB_VALUE * dbv2, DB_VALUE * answer)
1796 {
1797  int ret = NO_ERROR;
1798  int prec;
1799  int scale;
1800  bool positive_ans;
1801  unsigned char temp[2 * DB_NUMERIC_BUF_SIZE]; /* Copy of a DB_C_NUMERIC */
1802  unsigned char result[DB_NUMERIC_BUF_SIZE]; /* Copy of a DB_C_NUMERIC */
1803 
1804  /* Check for bad inputs */
1805  if (answer == NULL)
1806  {
1807  return ER_OBJ_INVALID_ARGUMENTS;
1808  }
1809  if (dbv1 == NULL || DB_VALUE_TYPE (dbv1) != DB_TYPE_NUMERIC)
1810  {
1811  db_make_null (answer);
1812  return ER_OBJ_INVALID_ARGUMENTS;
1813  }
1814  if (dbv2 == NULL || DB_VALUE_TYPE (dbv2) != DB_TYPE_NUMERIC)
1815  {
1816  db_make_null (answer);
1817  return ER_OBJ_INVALID_ARGUMENTS;
1818  }
1819 
1820  /* Check for NULL values */
1821  if (DB_IS_NULL (dbv1) || DB_IS_NULL (dbv2))
1822  {
1824  return NO_ERROR;
1825  }
1826 
1827  /* Perform the multiplication */
1828  numeric_mul (db_locate_numeric (dbv1), db_locate_numeric (dbv2), &positive_ans, temp);
1829  /* Check for overflow. Reset precision & scale if necessary */
1830  prec = DB_VALUE_PRECISION (dbv1) + DB_VALUE_PRECISION (dbv2) + 1;
1831  scale = DB_VALUE_SCALE (dbv1) + DB_VALUE_SCALE (dbv2);
1832  ret = numeric_get_msb_for_dec (prec, scale, temp, &prec, &scale, result);
1833  if (ret != NO_ERROR)
1834  {
1835  goto exit_on_error;
1836  }
1837 
1838  /* If no error, make the answer */
1839  if (!positive_ans)
1840  {
1841  numeric_negate (result);
1842  }
1843  db_make_numeric (answer, result, prec, scale);
1844 
1845  return ret;
1846 
1847 exit_on_error:
1848 
1850 
1851  return (ret == NO_ERROR && (ret = er_errid ()) == NO_ERROR) ? ER_FAILED : ret;
1852 }
1853 
1854 /*
1855  * numeric_db_value_div () -
1856  * return: NO_ERROR, or ER_code
1857  * Errors:
1858  * ER_OBJ_INVALID_ARGUMENTS - if dbv1, dbv2, or answer are NULL or
1859  * are not DB_TYPE_NUMERIC
1860  * dbv1(in) : ptr to a DB_VALUE structure of type DB_TYPE_NUMERIC
1861  * dbv2(in) : ptr to a DB_VALUE structure of type DB_TYPE_NUMERIC
1862  * answer(out): ptr to a DB_VALUE structure of type DB_TYPE_NUMERIC
1863  *
1864  * Note: This routine divides the numeric values of two DB_VALUE's and
1865  * returns the results in answer. The answer will be returned as either the
1866  * common type of dbv1 and dbv2 or as the common type of dbv1 and dbv2 with
1867  * a extra decimal places of precision if the quotient requires it to avoid
1868  * loss of data.
1869  *
1870  * The answer is set to a NULL-valued DB_C_NUMERIC's when an error occurs.
1871  */
1872 int
1873 numeric_db_value_div (const DB_VALUE * dbv1, const DB_VALUE * dbv2, DB_VALUE * answer)
1874 {
1875  int prec;
1876  int max_scale, scale1, scale2;
1877  unsigned char long_dbv1_copy[DB_LONG_NUMERIC_MULTIPLIER * DB_NUMERIC_BUF_SIZE];
1878  unsigned char long_temp_quo[DB_LONG_NUMERIC_MULTIPLIER * DB_NUMERIC_BUF_SIZE];
1879  unsigned char dbv1_copy[DB_NUMERIC_BUF_SIZE]; /* Copy of a DB_C_NUMERIC */
1880  unsigned char dbv2_copy[DB_NUMERIC_BUF_SIZE]; /* Copy of a DB_C_NUMERIC */
1881  unsigned char temp_quo[DB_NUMERIC_BUF_SIZE]; /* Copy of a DB_C_NUMERIC */
1882  unsigned char temp_rem[DB_NUMERIC_BUF_SIZE]; /* Copy of a DB_C_NUMERIC */
1883  int scale, scaleup = 0;
1884  int ret = NO_ERROR;
1885  TP_DOMAIN *domain;
1886  DB_C_NUMERIC divisor_p;
1887 
1888  /* Check for bad inputs */
1889  if (answer == NULL)
1890  {
1891  return ER_OBJ_INVALID_ARGUMENTS;
1892  }
1893  if (dbv1 == NULL || DB_VALUE_TYPE (dbv1) != DB_TYPE_NUMERIC)
1894  {
1895  db_make_null (answer);
1896  return ER_OBJ_INVALID_ARGUMENTS;
1897  }
1898  if (dbv2 == NULL || DB_VALUE_TYPE (dbv2) != DB_TYPE_NUMERIC)
1899  {
1900  db_make_null (answer);
1901  return ER_OBJ_INVALID_ARGUMENTS;
1902  }
1903 
1904  /* Check for NULL values */
1905  if (DB_IS_NULL (dbv1) || DB_IS_NULL (dbv2))
1906  {
1908  return NO_ERROR;
1909  }
1910 
1911  /* In order to maintain the proper number of scaling in the output, find the maximum scale of the two args and make
1912  * sure that the scale of dbv1 exceeds the scale of dbv2 by that amount. */
1913  numeric_shortnum_to_longnum (long_dbv1_copy, db_locate_numeric (dbv1));
1914  scale1 = DB_VALUE_SCALE (dbv1);
1915  scale2 = DB_VALUE_SCALE (dbv2);
1916  max_scale = MAX (scale1, scale2);
1917  if (scale2 > 0)
1918  {
1919  scaleup = (max_scale + scale2) - scale1;
1920  ret = numeric_scale_dec_long (long_dbv1_copy, scaleup, true);
1921  if (ret != NO_ERROR)
1922  { /* overflow */
1923  goto exit_on_error;
1924  }
1925  }
1926 
1927  /*
1928  * Update the domain information of the answer. Check to see if precision
1929  * needs to be updated due to carry
1930  */
1931  prec = DB_VALUE_PRECISION (dbv1) + scaleup;
1932  scale = max_scale;
1933  if (prec > DB_MAX_NUMERIC_PRECISION)
1934  {
1935  prec = DB_MAX_NUMERIC_PRECISION;
1936  }
1937 
1939  {
1940  int new_scale, new_prec;
1941  int scale_delta;
1942  scale_delta = DB_DEFAULT_NUMERIC_DIVISION_SCALE - scale;
1943  new_scale = scale + scale_delta;
1944  new_prec = prec + scale_delta;
1945  if (new_prec > DB_MAX_NUMERIC_PRECISION)
1946  {
1947  new_scale -= (new_prec - DB_MAX_NUMERIC_PRECISION);
1948  new_prec = DB_MAX_NUMERIC_PRECISION;
1949  }
1950 
1951  ret = numeric_scale_dec_long (long_dbv1_copy, new_scale - scale, true);
1952  if (ret != NO_ERROR)
1953  {
1954  goto exit_on_error;
1955  }
1956 
1957  scale = new_scale;
1958  prec = new_prec;
1959  }
1960 
1961  if (numeric_is_longnum_value (long_dbv1_copy))
1962  {
1963  /* only the dividend and quotient maybe long numeric, divisor must be numeric */
1964  numeric_long_div (long_dbv1_copy, db_locate_numeric (dbv2), long_temp_quo, temp_rem, true);
1965  ret = numeric_longnum_to_shortnum (temp_quo, long_temp_quo);
1966  if (ret != NO_ERROR)
1967  {
1968  goto exit_on_error;
1969  }
1970  }
1971  else
1972  {
1973  numeric_longnum_to_shortnum (dbv1_copy, long_dbv1_copy);
1974  numeric_div (dbv1_copy, db_locate_numeric (dbv2), temp_quo, temp_rem);
1975  }
1976 
1977  /* round! Check if remainder is larger than or equal to 2*divisor. i.e. rem / divisor >= 0.5 */
1978 
1979  /* first convert to positive number Note that reminder and dbv2 must be numeric, so we don't consider long numeric. */
1980  if (numeric_is_negative (temp_rem))
1981  {
1982  numeric_negate (temp_rem);
1983  }
1984 
1986  {
1987  numeric_copy (dbv2_copy, db_locate_numeric (dbv2));
1988  numeric_negate (dbv2_copy);
1989  divisor_p = dbv2_copy;
1990  }
1991  else
1992  {
1993  divisor_p = db_locate_numeric (dbv2);
1994  }
1995 
1996  numeric_add (temp_rem, temp_rem, temp_rem, DB_NUMERIC_BUF_SIZE);
1997  if (numeric_compare (temp_rem, divisor_p) >= 0)
1998  {
1999  if (numeric_is_negative (temp_quo))
2000  {
2001  /* for negative number */
2002  numeric_decrease (temp_quo);
2003  }
2004  else
2005  {
2006  numeric_increase (temp_quo);
2007  }
2008  }
2009 
2010  if (numeric_overflow (temp_quo, prec))
2011  {
2012  if (prec < DB_MAX_NUMERIC_PRECISION)
2013  {
2014  prec++;
2015  }
2016  else
2017  {
2020  ret = ER_IT_DATA_OVERFLOW;
2021  goto exit_on_error;
2022  }
2023  }
2024 
2025  db_make_numeric (answer, temp_quo, prec, scale);
2026 
2027  return ret;
2028 
2029 exit_on_error:
2030 
2032 
2033  return (ret == NO_ERROR && (ret = er_errid ()) == NO_ERROR) ? ER_FAILED : ret;
2034 }
2035 
2036 /*
2037  * numeric_db_value_negate () -
2038  * return: NO_ERROR, or ER_code
2039  The argument answer is modified in place.
2040  * Errors:
2041  * ER_OBJ_INVALID_ARGUMENTS - answer is not DB_TYPE_NUMERIC
2042  * answer(in/out) : ptr to a DB_VALUE of type DB_TYPE_NUMERIC
2043  *
2044  * Note: This routine returns the negative (2's complement) of arg in answer.
2045  */
2046 int
2048 {
2049  /* Check for NULL value */
2050  if (DB_IS_NULL (answer))
2051  {
2052  return NO_ERROR;
2053  }
2054 
2055  /* Check for bad inputs */
2056  if (answer == NULL || DB_VALUE_TYPE (answer) != DB_TYPE_NUMERIC)
2057  {
2058  return ER_OBJ_INVALID_ARGUMENTS;
2059  }
2060 
2061  /* Perform the negation */
2062  numeric_negate (db_locate_numeric (answer));
2063 
2064  return NO_ERROR;
2065 }
2066 
2067 /*
2068  * numeric_db_value_abs () -
2069  * return:
2070  * src_num(in) :
2071  * dest_num(in) :
2072  */
2073 void
2075 {
2076  numeric_copy (dest_num, src_num);
2077  if (numeric_is_negative (src_num))
2078  {
2079  numeric_negate (dest_num);
2080  }
2081 }
2082 
2083 /*
2084  * numeric_db_value_is_positive () -
2085  * return: 1 (>= 0), 0 (< 0), error code (error)
2086  * dbvalue(in): ptr to a DB_VALUE of type DB_TYPE_NUMERIC
2087  */
2088 int
2090 {
2091  int ret;
2092 
2093  /* Check for bad inputs */
2094  if (dbvalue == NULL || DB_VALUE_TYPE (dbvalue) != DB_TYPE_NUMERIC || DB_IS_NULL (dbvalue))
2095  {
2096  return ER_OBJ_INVALID_ARGUMENTS;
2097  }
2098 
2100 
2101  return !ret;
2102 }
2103 
2104 /*
2105  * numeric_db_value_compare () -
2106  * return: NO_ERROR, or ER_code
2107  * Errors:
2108  * ER_OBJ_INVALID_ARGUMENTS - if dbv1, dbv2, or answer are NULL or
2109  * are not DB_TYPE_NUMERIC (for dbv*) or
2110  * DB_TYPE_INTEGER (for answer);
2111  * dbv1(in) : ptr to a DB_VALUE of type DB_TYPE_NUMERIC
2112  * dbv2(in) : ptr to a DB_VALUE of type DB_TYPE_NUMERIC
2113  * answer(out): ptr to a DB_VALUE of type DB_TYPE_INTEGER
2114  *
2115  * Note: This routine compares two numeric DB_VALUE's and sets the value of
2116  * answer accordingly. This function returns:
2117  * -1 if dbv1 < dbv2
2118  * 0 if dbv1 = dbv2 and
2119  * 1 if dbv1 > dbv2.
2120  */
2121 int
2122 numeric_db_value_compare (const DB_VALUE * dbv1, const DB_VALUE * dbv2, DB_VALUE * answer)
2123 {
2124  int ret = NO_ERROR;
2125  int prec1 = 0, prec2 = 0, scale1 = 0, scale2 = 0;
2126  int prec_common = 0, scale_common = 0;
2127  int cmp_rez = 0;
2128 
2129  /* Check for bad inputs */
2130  if (answer == NULL)
2131  {
2132  return ER_OBJ_INVALID_ARGUMENTS;
2133  }
2134  if (dbv1 == NULL || DB_VALUE_TYPE (dbv1) != DB_TYPE_NUMERIC)
2135  {
2136  db_make_null (answer);
2137  return ER_OBJ_INVALID_ARGUMENTS;
2138  }
2139  if (dbv2 == NULL || DB_VALUE_TYPE (dbv2) != DB_TYPE_NUMERIC)
2140  {
2141  db_make_null (answer);
2142  return ER_OBJ_INVALID_ARGUMENTS;
2143  }
2144 
2145  /* Check for NULL values */
2146  if (DB_IS_NULL (dbv1) || DB_IS_NULL (dbv2))
2147  {
2149  return NO_ERROR;
2150  }
2151 
2152  scale1 = DB_VALUE_SCALE (dbv1);
2153  scale2 = DB_VALUE_SCALE (dbv2);
2154  prec1 = DB_VALUE_PRECISION (dbv1);
2155  prec2 = DB_VALUE_PRECISION (dbv2);
2156 
2157  if (prec1 == prec2 && scale1 == scale2)
2158  {
2159  /* Simple case. Just compare two numbers. */
2160  cmp_rez = numeric_compare (db_locate_numeric (dbv1), db_locate_numeric (dbv2));
2161  db_make_int (answer, cmp_rez);
2162  return NO_ERROR;
2163  }
2164  else
2165  {
2166  DB_VALUE dbv1_common, dbv2_common;
2167 
2168  /* First try to coerce to common prec/scale numbers and compare. */
2169  ret = numeric_common_prec_scale (dbv1, dbv2, &dbv1_common, &dbv2_common);
2170  if (ret == NO_ERROR)
2171  {
2172  cmp_rez = numeric_compare (db_locate_numeric (&dbv1_common), db_locate_numeric (&dbv2_common));
2173  db_make_int (answer, cmp_rez);
2174  return NO_ERROR;
2175  }
2176  else if (ret == ER_IT_DATA_OVERFLOW)
2177  {
2178  /* For example, if we want to compare a NUMERIC(31,2) with a NUMERIC(21, 14) the common precision and scale
2179  * is (43, 14) which is an overflow. To avoid this issue we compare the integral parts and the fractional
2180  * parts of dbv1 and dbv2 separately. */
2181  unsigned char num1_integ[DB_NUMERIC_BUF_SIZE];
2182  unsigned char num2_integ[DB_NUMERIC_BUF_SIZE];
2183  unsigned char num1_frac[DB_NUMERIC_BUF_SIZE];
2184  unsigned char num2_frac[DB_NUMERIC_BUF_SIZE];
2185 
2186  er_clear (); /* reset ER_IT_DATA_OVERFLOW */
2187 
2188  if (prec1 - scale1 < prec2 - scale2)
2189  {
2190  prec_common = prec2 - scale2;
2191  }
2192  else
2193  {
2194  prec_common = prec1 - scale1;
2195  }
2196 
2197  if (scale1 > scale2)
2198  {
2199  scale_common = scale1;
2200  }
2201  else
2202  {
2203  scale_common = scale2;
2204  }
2205 
2206  /* first compare integral parts */
2207  numeric_get_integral_part (db_locate_numeric (dbv1), prec1, scale1, prec_common, num1_integ);
2208  numeric_get_integral_part (db_locate_numeric (dbv2), prec2, scale2, prec_common, num2_integ);
2209  cmp_rez = numeric_compare (num1_integ, num2_integ);
2210  if (cmp_rez != 0)
2211  {
2212  /* if the integral parts differ, we don't need to compare fractional parts */
2213  db_make_int (answer, cmp_rez);
2214  return NO_ERROR;
2215  }
2216 
2217  /* the integral parts are equal, now compare fractional parts */
2218  numeric_get_fractional_part (db_locate_numeric (dbv1), scale1, scale_common, num1_frac);
2219  numeric_get_fractional_part (db_locate_numeric (dbv2), scale2, scale_common, num2_frac);
2220 
2221  /* compare fractional parts and return the result */
2222  cmp_rez = numeric_compare (num1_frac, num2_frac);
2223  db_make_int (answer, cmp_rez);
2224  }
2225  else
2226  {
2227  db_make_null (answer);
2228  return ER_FAILED;
2229  }
2230  }
2231 
2232  return NO_ERROR;
2233 }
2234 
2235 /*
2236  * numeric_coerce_int_to_num () -
2237  * return:
2238  * arg(in) : unsigned int value
2239  * answer(out): DB_C_NUMERIC
2240  *
2241  * Note: This routine converts 32 bit integer into DB_C_NUMERIC format and
2242  * returns the result.
2243  */
2244 void
2246 {
2247  unsigned char pad;
2248  int digit;
2249 
2250  /* Check for negative/positive and set pad accordingly */
2251  pad = (arg >= 0) ? 0 : 0xff;
2252 
2253  /* Copy the lower 32 bits into answer */
2254  answer[DB_NUMERIC_BUF_SIZE - 1] = ((arg) & 0xff);
2255  answer[DB_NUMERIC_BUF_SIZE - 2] = ((arg >> 8) & 0xff);
2256  answer[DB_NUMERIC_BUF_SIZE - 3] = ((arg >> 16) & 0xff);
2257  answer[DB_NUMERIC_BUF_SIZE - 4] = ((arg >> 24) & 0xff);
2258 
2259  /* Pad extra bytes of answer accordingly */
2260  for (digit = DB_NUMERIC_BUF_SIZE - 5; digit >= 0; digit--)
2261  {
2262  answer[digit] = pad;
2263  }
2264 }
2265 
2266 /*
2267  * numeric_coerce_bigint_to_num () -
2268  * return:
2269  * arg(in) : unsigned bigint value
2270  * answer(out): DB_C_NUMERIC
2271  *
2272  * Note: This routine converts 64 bit integer into DB_C_NUMERIC format and
2273  * returns the result.
2274  */
2275 void
2277 {
2278  unsigned char pad;
2279  int digit;
2280 
2281  /* Check for negative/positive and set pad accordingly */
2282  pad = (arg >= 0) ? 0 : 0xff;
2283 
2284  /* Copy the lower 64 bits into answer */
2285  answer[DB_NUMERIC_BUF_SIZE - 1] = ((arg) & 0xff);
2286  answer[DB_NUMERIC_BUF_SIZE - 2] = ((arg >> 8) & 0xff);
2287  answer[DB_NUMERIC_BUF_SIZE - 3] = ((arg >> 16) & 0xff);
2288  answer[DB_NUMERIC_BUF_SIZE - 4] = ((arg >> 24) & 0xff);
2289  answer[DB_NUMERIC_BUF_SIZE - 5] = ((arg >> 32) & 0xff);
2290  answer[DB_NUMERIC_BUF_SIZE - 6] = ((arg >> 40) & 0xff);
2291  answer[DB_NUMERIC_BUF_SIZE - 7] = ((arg >> 48) & 0xff);
2292  answer[DB_NUMERIC_BUF_SIZE - 8] = ((arg >> 56) & 0xff);
2293 
2294  /* Pad extra bytes of answer accordingly */
2295  for (digit = DB_NUMERIC_BUF_SIZE - 9; digit >= 0; digit--)
2296  {
2297  answer[digit] = pad;
2298  }
2299 }
2300 
2301 /*
2302  * numeric_coerce_num_to_int () -
2303  * return:
2304  * arg(in) : ptr to a DB_C_NUMERIC
2305  * answer(out): ptr to an integer
2306  *
2307  * Note: This routine converts a numeric into an integer returns the result.
2308  * If arg overflows answer, answer is set to +/- MAXINT.
2309  */
2310 void
2312 {
2313  int digit;
2314  unsigned char pad;
2315 
2316  /* Check for negative/positive and overflow */
2317  pad = (numeric_is_negative (arg)) ? 0xff : 0;
2318  for (digit = DB_NUMERIC_BUF_SIZE - 5; digit >= 1; digit--)
2319  {
2320  if (arg[digit] != pad)
2321  {
2322  if (pad == 0xff)
2323  {
2324  *answer = ~0;
2325  }
2326  else
2327  {
2328  *answer = ~0 >> 1;
2329  }
2330  return;
2331  }
2332  }
2333 
2334  /* Copy the lower 32 bits into answer */
2335  *answer =
2336  ((arg[DB_NUMERIC_BUF_SIZE - 1]) + (((unsigned int) (arg[DB_NUMERIC_BUF_SIZE - 2])) << 8) +
2337  (((unsigned int) (arg[DB_NUMERIC_BUF_SIZE - 3])) << 16) + (((unsigned int) (arg[DB_NUMERIC_BUF_SIZE - 4])) << 24));
2338 }
2339 
2340 /*
2341  * numeric_coerce_num_to_bigint () -
2342  * return:
2343  * arg(in) : ptr to a DB_C_NUMERIC
2344  * answer(out): ptr to an bigint
2345  *
2346  * Note: This routine converts a numeric into an bigint returns the result.
2347  * If arg overflows answer, answer is set to +/- MAXINT.
2348  */
2349 int
2351 {
2352  DB_NUMERIC zero_scale_numeric, numeric_rem, numeric_tmp;
2353 
2354  zero_scale_numeric.d.buf[0] = '\0';
2355  numeric_rem.d.buf[0] = '\0';
2356  numeric_tmp.d.buf[0] = '\0';
2357 
2358  DB_C_NUMERIC zero_scale_arg = zero_scale_numeric.d.buf;
2359  DB_C_NUMERIC rem = numeric_rem.d.buf;
2360  DB_C_NUMERIC tmp = numeric_tmp.d.buf;
2361  unsigned int i;
2362  char *ptr;
2363 
2364  if (scale >= (int) (sizeof (powers_of_10) / sizeof (powers_of_10[0])))
2365  {
2366  return ER_IT_DATA_OVERFLOW;
2367  }
2368 
2369  if (scale > 0)
2370  {
2371  numeric_div (arg, numeric_get_pow_of_10 (scale), zero_scale_arg, rem);
2372  if (!numeric_is_negative (zero_scale_arg))
2373  {
2374  numeric_negate (rem);
2375  }
2376 
2377  /* round */
2379  numeric_add (tmp, rem, tmp, DB_NUMERIC_BUF_SIZE);
2380  if (numeric_is_negative (tmp) || numeric_is_zero (tmp))
2381  {
2382  if (numeric_is_negative (zero_scale_arg))
2383  {
2384  numeric_decrease (zero_scale_arg);
2385  }
2386  else
2387  {
2388  numeric_increase (zero_scale_arg);
2389  }
2390  }
2391  }
2392  else
2393  {
2394  numeric_copy (zero_scale_arg, arg);
2395  }
2396 
2397  if (!numeric_is_bigint (zero_scale_arg))
2398  {
2399  return ER_IT_DATA_OVERFLOW;
2400  }
2401 
2402  /* Copy the lower 64 bits into answer */
2403  ptr = (char *) answer;
2404  for (i = 0; i < sizeof (DB_BIGINT); i++)
2405  {
2406 #if OR_BYTE_ORDER == OR_LITTLE_ENDIAN
2407  ptr[i] = zero_scale_arg[DB_NUMERIC_BUF_SIZE - (i + 1)];
2408 #else
2409  ptr[sizeof (DB_BIGINT) - (i + 1)] = zero_scale_arg[DB_NUMERIC_BUF_SIZE - (i + 1)];
2410 #endif
2411  }
2412 
2413  return NO_ERROR;
2414 }
2415 
2416 /*
2417  * numeric_coerce_dec_str_to_num () -
2418  * return:
2419  * dec_str(in): char * holds positive decimal digits as ASCII chars
2420  * result(out): ptr to a DB_C_NUMERIC
2421  *
2422  * Note: This routine converts a character string that contains the positive
2423  * decimal digits of a numeric encoded as ASCII characters.
2424  */
2425 void
2426 numeric_coerce_dec_str_to_num (const char *dec_str, DB_C_NUMERIC result)
2427 {
2428  unsigned char big_chunk[DB_NUMERIC_BUF_SIZE]; /* copy of a DB_C_NUMERIC */
2429  int ntot_digits;
2430  int ndigits;
2431  int dec_dig;
2432  int chunk_value;
2433  char temp_buffer[10];
2434  char *chunk;
2435  bool is_negative = false;
2436 
2437  /* Zero out the result */
2439  /* Check for a negative number. Negative sign must be in the first decimal place */
2440  if (*dec_str == '-')
2441  {
2442  is_negative = true;
2443  dec_str++;
2444  }
2445 
2446  /* Loop through string reading 9 decimal digits at a time */
2447  ntot_digits = strlen ((char *) dec_str);
2448  chunk = (char *) dec_str + ntot_digits;
2449  for (dec_dig = ntot_digits - 1; dec_dig >= 0; dec_dig -= 9)
2450  {
2451  ndigits = MIN (dec_dig + 1, 9);
2452  chunk -= ndigits;
2453  memcpy (temp_buffer, chunk, ndigits);
2454  temp_buffer[ndigits] = '\0';
2455  chunk_value = (int) atol (temp_buffer);
2456  if (chunk_value != 0)
2457  {
2458  numeric_coerce_int_to_num (chunk_value, big_chunk);
2459  /* Scale the number if not first time through */
2460  if (dec_dig != ntot_digits - 1)
2461  {
2462  numeric_scale_dec (big_chunk, ntot_digits - dec_dig - 1, big_chunk);
2463  }
2464  numeric_add (big_chunk, result, result, DB_NUMERIC_BUF_SIZE);
2465  }
2466  }
2467 
2468  /* If negative, negate the result */
2469  if (is_negative)
2470  {
2471  numeric_negate (result);
2472  }
2473 }
2474 
2475 /*
2476  * numeric_coerce_num_to_dec_str () -
2477  * return:
2478  * num(in) : DB_C_NUMERIC
2479  * dec_str(out): returned string of decimal digits as ASCII chars
2480  *
2481  * Note: This routine converts a DB_C_NUMERIC into a character string that
2482  * contains the decimal digits of the numeric encoded as ASCII characters.
2483  */
2484 void
2486 {
2487  unsigned char local_num[DB_NUMERIC_BUF_SIZE]; /* copy of a DB_C_NUMERIC */
2488  DEC_STRING *bit_value;
2489  DEC_STRING result;
2490  unsigned int i, j;
2491 
2492  /* Check if the number is negative */
2493  numeric_copy (local_num, num);
2494  if (numeric_is_negative (local_num))
2495  {
2496  *dec_str = '-';
2497  dec_str++;
2498  numeric_negate (local_num);
2499  }
2500 
2501  /* Loop through the bits of the numeric building up string */
2502  numeric_init_dec_str (&result);
2503  for (i = 0; i < DB_NUMERIC_BUF_SIZE * 8; i += 8)
2504  {
2505  if (local_num[i / 8] == 0)
2506  {
2507  continue;
2508  }
2509  for (j = 0; j < 8; j++)
2510  {
2511  if (numeric_is_bit_set (local_num, i + j))
2512  {
2513  bit_value = numeric_get_pow_of_2 ((DB_NUMERIC_BUF_SIZE * 8) - (i + j) - 1);
2514  numeric_add_dec_str (bit_value, &result, &result);
2515  }
2516  }
2517  }
2518 
2519  /* Convert result into ASCII array */
2520  for (i = 0; i < TWICE_NUM_MAX_PREC; i++)
2521  {
2522  if (result.digits[i] == -1)
2523  {
2524  result.digits[i] = 0;
2525  }
2526  assert (result.digits[i] >= 0);
2527 
2528  *dec_str = result.digits[i] + '0';
2529  dec_str++;
2530  }
2531 
2532  /* Null terminate */
2533  *dec_str = '\0';
2534 }
2535 
2536 /*
2537  * numeric_coerce_num_to_double () -
2538  * return:
2539  * num(in) : DB_C_NUMERIC
2540  * scale(in) : integer value of the scale
2541  * adouble(out): ptr to the returned double value
2542  *
2543  * Note: This routine converts a DB_C_NUMERIC into a double precision value.
2544  */
2545 void
2546 numeric_coerce_num_to_double (DB_C_NUMERIC num, int scale, double *adouble)
2547 {
2548  char num_string[TWICE_NUM_MAX_PREC + 2]; /* 2: Sign, Null terminate */
2549 
2550  /* Convert the numeric to a decimal string */
2551  numeric_coerce_num_to_dec_str (num, num_string);
2552 
2553  /* Convert the decimal string into a double */
2554  /* Problem at precision with line below */
2555  /* 123.445 was converted to 123.444999999999999999 */
2556  *adouble = atof (num_string) / pow (10.0, scale);
2557 
2558  /* TODO: [CUBRIDSUS-2637] revert to early code for now. adouble = atof (num_string); for (i = 0; i < scale; i++)
2559  * adouble /= 10; */
2560 }
2561 
2562 /*
2563  * numeric_fast_convert () -
2564  * return:
2565  * adouble(in) :
2566  * dst_scale(in) :
2567  * num(in) :
2568  * prec(in) :
2569  * scale(in) :
2570  */
2571 static int
2572 numeric_fast_convert (double adouble, int dst_scale, DB_C_NUMERIC num, int *prec, int *scale)
2573 {
2574  double scaled_double;
2575  int scaled_int, estimated_precision;
2576  scaled_double = (adouble * numeric_Pow_of_10[dst_scale]) + (adouble < 0.0 ? -0.5 : 0.5);
2577  scaled_int = (int) scaled_double;
2578  num[DB_NUMERIC_BUF_SIZE - 1] = (scaled_int >> 0) & 0xff;
2579  num[DB_NUMERIC_BUF_SIZE - 2] = (scaled_int >> 8) & 0xff;
2580  num[DB_NUMERIC_BUF_SIZE - 3] = (scaled_int >> 16) & 0xff;
2581  num[DB_NUMERIC_BUF_SIZE - 4] = (scaled_int >> 24) & 0xff;
2582  memset (num, (scaled_int < 0) ? 0xff : 0x0, DB_NUMERIC_BUF_SIZE - 4);
2583  /*
2584  * Now try to make an educated guess at the actual precision. The
2585  * actual value of scaled_int is no longer of much interest, just so
2586  * long as the general magnitude is maintained (i.e., make sure you
2587  * keep the same number of significant decimal digits).
2588  */
2589  if (scaled_int < 0)
2590  {
2591  scaled_int = (scaled_int == DB_INT32_MIN) ? DB_INT32_MAX : -scaled_int;
2592  }
2593 
2594  if (scaled_int < 10L)
2595  {
2596  estimated_precision = 1;
2597  }
2598  else if (scaled_int < 100L)
2599  {
2600  estimated_precision = 2;
2601  }
2602  else if (scaled_int < 1000L)
2603  {
2604  estimated_precision = 3;
2605  }
2606  else if (scaled_int < 10000L)
2607  {
2608  estimated_precision = 4;
2609  }
2610  else if (scaled_int < 100000L)
2611  {
2612  estimated_precision = 5;
2613  }
2614  else if (scaled_int < 1000000L)
2615  {
2616  estimated_precision = 6;
2617  }
2618  else if (scaled_int < 10000000L)
2619  {
2620  estimated_precision = 7;
2621  }
2622  else if (scaled_int < 100000000L)
2623  {
2624  estimated_precision = 8;
2625  }
2626  else if (scaled_int < 1000000000L)
2627  {
2628  estimated_precision = 9;
2629  }
2630  else
2631  {
2632  estimated_precision = 10;
2633  }
2634 
2635  /*
2636  * No matter what we think it is, it has to be at least as big as the
2637  * scale.
2638  */
2639  if (estimated_precision < dst_scale)
2640  {
2641  estimated_precision = dst_scale;
2642  }
2643 
2644  *prec = estimated_precision;
2645  *scale = dst_scale;
2646  return NO_ERROR;
2647 }
2648 
2649 /*
2650  * numeric_get_integral_part () - return the integral part of a numeric
2651  * return: NO_ERROR, or ER_code
2652  * num(in) : the numeric from which to get the integral part
2653  * src_prec(in) : the precision of num
2654  * src_scale(in) : the scale of num
2655  * dst_prec(in) : the desired precision of the result
2656  * dest(out) : the result
2657  *
2658  * Note: This function returns a NUMERIC value of precision dst_prec and
2659  * 0 scale representing the integral part of the num number.
2660  */
2661 static void
2662 numeric_get_integral_part (const DB_C_NUMERIC num, const int src_prec, const int src_scale, const int dst_prec,
2663  DB_C_NUMERIC dest)
2664 {
2665  char dec_str[DB_MAX_NUMERIC_PRECISION * 4];
2666  char new_dec_num[DB_MAX_NUMERIC_PRECISION + 1];
2667  int i = 0;
2668 
2669  /* the number of digits of the result */
2670  const int res_num_digits = src_prec - src_scale;
2671 
2672  assert (src_prec - src_scale <= dst_prec);
2673  assert (num != dest);
2674 
2676  memset (new_dec_num, 0, DB_MAX_NUMERIC_PRECISION + 1);
2677 
2678  /* 1. get the dec representation of the numeric value */
2679  numeric_coerce_num_to_dec_str (num, dec_str);
2680 
2681  /* 2. "zero" the MSB of new_dec_num. */
2682  for (i = 0; i < dst_prec - res_num_digits; i++)
2683  {
2684  new_dec_num[i] = '0';
2685  }
2686 
2687  /* 3. copy the integral digits from dec_str to the end of the new_dec_num */
2688  for (i = 0; i < res_num_digits; i++)
2689  {
2690  const int idx_new_dec = dst_prec - res_num_digits + i;
2691  const int idx_dec_str = strlen (dec_str) - src_prec + i;
2692  new_dec_num[idx_new_dec] = dec_str[idx_dec_str];
2693  }
2694 
2695  numeric_coerce_dec_str_to_num (new_dec_num, dest);
2696  if (numeric_is_negative (num))
2697  {
2698  numeric_negate (dest);
2699  }
2700 }
2701 
2702 /*
2703  * numeric_get_fractional_part () - return the fractional part of a numeric
2704  * return: NO_ERROR, or ER_code
2705  * num(in) : the numeric from which to get the fractional part
2706  * src_prec(in) : the precision of num
2707  * src_scale(in) : the scale of num
2708  * dst_scale(in) : the desired scale of the result
2709  * dest(out) : the result
2710  *
2711  * Note: This function returns a numeric with precision dst_scale and scale 0
2712  * which contains the fractional part of a numeric
2713  */
2714 static void
2715 numeric_get_fractional_part (const DB_C_NUMERIC num, const int src_scale, const int dst_scale, DB_C_NUMERIC dest)
2716 {
2717  char dec_str[DB_MAX_NUMERIC_PRECISION * 4];
2718  char new_dec_num[DB_MAX_NUMERIC_PRECISION + 1];
2719  int i = 0;
2720 
2721  assert (src_scale <= dst_scale);
2722  assert (num != dest);
2723 
2725  memset (new_dec_num, 0, DB_MAX_NUMERIC_PRECISION + 1);
2726 
2727  /* 1. get the dec representation of the numeric value */
2728  numeric_coerce_num_to_dec_str (num, dec_str);
2729 
2730  /* 2. copy all scale digits to the beginning of the new_dec_num buffer */
2731  for (i = 0; i < src_scale; i++)
2732  {
2733  new_dec_num[i] = dec_str[strlen (dec_str) - src_scale + i];
2734  }
2735 
2736  /* 3. add 0's for the reminder of the dst_scale */
2737  for (i = src_scale; i < dst_scale; i++)
2738  {
2739  new_dec_num[i] = '0';
2740  }
2741 
2742  /* 4. null-terminate the string */
2743  new_dec_num[dst_scale] = '\0';
2744 
2745  numeric_coerce_dec_str_to_num (new_dec_num, dest);
2746  if (numeric_is_negative (num))
2747  {
2748  numeric_negate (dest);
2749  }
2750 }
2751 
2752 /*
2753  * numeric_is_fraction_part_zero () - check if fractional part of a numeric is
2754  * equal to 0
2755  * return : boolean
2756  * num (in) : numeric value
2757  * scale (in) : scale of the numeric
2758  */
2759 static bool
2760 numeric_is_fraction_part_zero (const DB_C_NUMERIC num, const int scale)
2761 {
2762  int i, len = 0;
2763  char dec_str[(2 * DB_MAX_NUMERIC_PRECISION) + 4];
2764  numeric_coerce_num_to_dec_str (num, dec_str);
2765  len = strlen (dec_str);
2766  for (i = 0; i < scale; i++)
2767  {
2768  if (dec_str[len - scale + i] != '0')
2769  {
2770  return false;
2771  }
2772  }
2773  return true;
2774 }
2775 
2776 /*
2777  * numeric_internal_double_to_num () -
2778  * return: NO_ERROR, or ER_code
2779  * adouble(in) :
2780  * dst_scale(in) :
2781  * num(in) :
2782  * prec(in) :
2783  * scale(in) :
2784  */
2785 int
2786 numeric_internal_double_to_num (double adouble, int dst_scale, DB_C_NUMERIC num, int *prec, int *scale)
2787 {
2788  return numeric_internal_real_to_num (adouble, dst_scale, num, prec, scale, false);
2789 }
2790 
2791 
2792 /*
2793  * numeric_internal_float_to_num () - converts a float to a DB_C_NUMERIC
2794  *
2795  * return: NO_ERROR or ER_code
2796  * afloat(in): floating-point value to be converted to NUMERIC
2797  * dst_scale(in): expected scale for the destination NUMERIC type
2798  * num(in): an allocated DB_C_NUMERIC to be filled with the converted numeric
2799  * value
2800  * prec(out): resulting precision of the converted value
2801  * scale(out): resulting scale of the converted value
2802  */
2803 int
2804 numeric_internal_float_to_num (float afloat, int dst_scale, DB_C_NUMERIC num, int *prec, int *scale)
2805 {
2806  return numeric_internal_real_to_num (afloat, dst_scale, num, prec, scale, true);
2807 }
2808 
2809 /*
2810  * fp_value_type() - returns the type of a given value of type double, as one
2811  * of the above enumerators.
2812  *
2813  * returns: the type of the passed-in floating-point value
2814  * d(in): floating-point value whose type is to be returned
2815  */
2818 {
2819 #ifdef WINDOWS
2820  /* actually the following symbols are dependent on the _MSC macro, not the WINDOWS macro */
2821  switch (_fpclass (d))
2822  {
2823  case _FPCLASS_NINF: /* -Inf */
2824  case _FPCLASS_PINF: /* +Inf */
2825  return FP_VALUE_TYPE_INFINITE;
2826 
2827  case _FPCLASS_SNAN: /* signaling NaN */
2828  case _FPCLASS_QNAN: /* quiet NaN */
2829  return FP_VALUE_TYPE_NAN;
2830 
2831  case _FPCLASS_NZ: /* -0 */
2832  case _FPCLASS_PZ: /* +0 */
2833  return FP_VALUE_TYPE_ZERO;
2834 
2835  default:
2836  return FP_VALUE_TYPE_NUMBER;
2837  }
2838 #else
2839  switch (std::fpclassify (d))
2840  {
2841  case FP_INFINITE:
2842  return FP_VALUE_TYPE_INFINITE;
2843  case FP_NAN:
2844  return FP_VALUE_TYPE_NAN;
2845  case FP_ZERO:
2846  return FP_VALUE_TYPE_ZERO;
2847  default:
2848  return FP_VALUE_TYPE_NUMBER;
2849  }
2850 #endif
2851 }
2852 
2853 /*
2854  * numeric_internal_real_to_num() - converts a floating point value (float or
2855  * double) to a DB_C_NUMERIC.
2856  *
2857  * return: NO_ERROR or ER_code
2858  * adouble(in): floating-point value to be converted to NUMERIC. May be either
2859  * float promoted to double, or a double.
2860  * dst_scale(in): expected scale of the destination NUMERIC data type
2861  * prec(out): resulting precision of the converted value
2862  * scale(out): resulting scale of the converted value
2863  * is_float(in): indicates adouble is a float promoted to double
2864  */
2865 int
2866 numeric_internal_real_to_num (double adouble, int dst_scale, DB_C_NUMERIC num, int *prec, int *scale, bool is_float)
2867 {
2868  char numeric_str[MAX (TP_DOUBLE_AS_CHAR_LENGTH + 1, DB_MAX_NUMERIC_PRECISION + 4)];
2869  int i = 0;
2870 
2871  switch (get_fp_value_type (adouble))
2872  {
2874  return ER_IT_DATA_OVERFLOW;
2875  case FP_VALUE_TYPE_NAN:
2876  case FP_VALUE_TYPE_ZERO:
2877  /* currently CUBRID returns 0 for a NaN converted to NUMERIC (??) */
2878  *scale = dst_scale;
2879  *prec = dst_scale ? dst_scale : 1;
2880 
2881  while (i < *prec)
2882  {
2883  numeric_str[i++] = '0';
2884  }
2885  numeric_str[i] = '\0';
2886 
2887  numeric_coerce_dec_str_to_num (numeric_str, num);
2888  return NO_ERROR;
2889  default:
2890  /* compare against pow(10, DB_MAX_NUMERIC_PRECISION) to check for overflow/underflow before actual conversion */
2891  if (NUMERIC_ABS (adouble) > DB_NUMERIC_OVERFLOW_LIMIT)
2892  {
2893  return ER_IT_DATA_OVERFLOW;
2894  }
2895  else
2896  {
2897  if (NUMERIC_ABS (adouble) < DB_NUMERIC_UNDERFLOW_LIMIT)
2898  {
2899  /* the floating-point number underflows any possible CUBRID NUMERIC domain type, so just return 0 with no
2900  * other conversion */
2901  *scale = dst_scale;
2902  *prec = dst_scale ? dst_scale : 1;
2903 
2904  while (i < *prec)
2905  {
2906  numeric_str[i++] = '0';
2907  }
2908  numeric_str[i] = '\0';
2909 
2910  numeric_coerce_dec_str_to_num ("0", num);
2911  return NO_ERROR;
2912  }
2913  else
2914  {
2915  /* adouble might fit into a CUBRID NUMERIC domain type with sufficient precision. Invoke _dtoa() to get
2916  * the sequence of digits and the decimal point position */
2917  int decpt, sign;
2918  char *rve;
2919  int ndigits;
2920 
2921  if (is_float)
2922  {
2923  _dtoa (adouble, 0, TP_FLOAT_MANTISA_DECIMAL_PRECISION, &decpt, &sign, &rve, numeric_str + 1, 0);
2924 
2925  numeric_str[TP_FLOAT_MANTISA_DECIMAL_PRECISION + 1] = '\0';
2926  }
2927  else
2928  {
2929  _dtoa (adouble, 0, TP_DOUBLE_MANTISA_DECIMAL_PRECISION, &decpt, &sign, &rve, numeric_str + 1, 0);
2930 
2931  numeric_str[TP_DOUBLE_MANTISA_DECIMAL_PRECISION + 1] = '\0';
2932  }
2933 
2934  /* shift the digits in the sequence to make room for and to reach the decimal point */
2935  ndigits = strlen (numeric_str + 1);
2936 
2937  if (decpt <= 0)
2938  {
2939  char *dst = MIN (numeric_str + 1 + ndigits - decpt,
2940  numeric_str + sizeof numeric_str / sizeof numeric_str[0] - 1), *src = dst + decpt;
2941 
2942  *prec = MIN (DB_MAX_NUMERIC_PRECISION, -decpt + ndigits);
2943  *scale = *prec;
2944 
2945  /* actually rounding should also be performed if value gets truncated. */
2946  *dst = '\0';
2947  dst--;
2948  src--;
2949 
2950  /* shift all digits in the string */
2951  while (src >= numeric_str + 1)
2952  {
2953  *dst = *src;
2954  dst--;
2955  src--;
2956  }
2957 
2958  /* prepend 0s from right to left until the decimal point position is reached */
2959  while (dst > numeric_str)
2960  {
2961  *dst-- = '0';
2962  }
2963  }
2964  else
2965  {
2966  /* the numer is greater than 1, either insert the decimal point at the correct position in the digits
2967  * sequence, or append 0s to the digits from left to right until the decimal point is reached. */
2968 
2969  if (decpt > DB_MAX_NUMERIC_PRECISION)
2970  {
2971  /* should not happen since overflow has been checked for previously */
2972  return ER_IT_DATA_OVERFLOW;
2973  }
2974  else
2975  {
2976  if (decpt < ndigits)
2977  {
2978  *prec = ndigits;
2979  *scale = ndigits - decpt;
2980  }
2981  else
2982  {
2983  /* append 0s to the digits sequence until the decimal point is reached */
2984 
2985  char *dst = numeric_str + 1 + decpt, *src = numeric_str + 1 + ndigits;
2986 
2987  while (src != dst)
2988  {
2989  *src++ = '0';
2990  }
2991 
2992  *src = '\0';
2993 
2994  *prec = decpt;
2995  *scale = 0;
2996  }
2997  }
2998  }
2999 
3000  /* append zeroes until dst_scale is reached */
3001  while (*prec < DB_MAX_NUMERIC_PRECISION && *scale < dst_scale)
3002  {
3003  numeric_str[1 + *prec] = '0';
3004  (*prec)++;
3005  (*scale)++;
3006  }
3007 
3008  numeric_str[1 + *prec] = '\0';
3009 
3010  /* The number without sign is now written in decimal in numeric_str */
3011 
3012  if (sign)
3013  {
3014  numeric_str[0] = '-';
3015  numeric_coerce_dec_str_to_num (numeric_str, num);
3016  }
3017  else
3018  {
3019  numeric_coerce_dec_str_to_num (numeric_str + 1, num);
3020  }
3021 
3022  return NO_ERROR;
3023  }
3024  }
3025  break;
3026  }
3027 }
3028 
3029 #if defined (ENABLE_UNUSED_FUNCTION)
3030 /*
3031  * numeric_coerce_double_to_num () -
3032  * return:
3033  * adouble(in): ptr to the returned double value
3034  * num(out) : DB_C_NUMERIC
3035  * prec(out) : integer value of the precision
3036  * scale(out) : integer value of the scale
3037  *
3038  * Note: This routine converts a double precision value into a DB_C_NUMERIC.
3039  * Works via the static routine numeric_internal_double_to_num (), which is
3040  * also called from numeric_db_value_coerce_to_num () so that we can exploit info
3041  * about the scale of the destination.
3042  */
3043 int
3044 numeric_coerce_double_to_num (double adouble, DB_C_NUMERIC num, int *prec, int *scale)
3045 {
3046  /*
3047  * return numeric_internal_double_to_num(adouble, DB_MAX_NUMERIC_PRECISION,
3048  */
3049  return numeric_internal_double_to_num (adouble, 16, num, prec, scale);
3050 }
3051 #endif /* ENABLE_UNUSED_FUNCTION */
3052 
3053 /*
3054  * numeric_coerce_string_to_num () -
3055  * return:
3056  * astring(in) : ptr to the input character string
3057  * astring_length(in) : length of the input character string
3058  * codeset(in) : codeset of string
3059  * result(out) : DB_VALUE of type numeric
3060  *
3061  * Note: This routine converts a string into a DB_VALUE.
3062  * It is not localized in relation to fractional and digit
3063  * grouping symbols.
3064  */
3065 int
3066 numeric_coerce_string_to_num (const char *astring, int astring_length, INTL_CODESET codeset, DB_VALUE * result)
3067 {
3068  char num_string[TWICE_NUM_MAX_PREC + 1];
3069  unsigned char num[DB_NUMERIC_BUF_SIZE];
3070  int i;
3071  int prec = 0;
3072  int scale = 0;
3073  bool leading_zeroes = true;
3074  bool sign_found = false;
3075  bool negate_value = false;
3076  bool pad_character_zero = false;
3077  bool trailing_spaces = false;
3078  bool decimal_part = false;
3079  int ret = NO_ERROR;
3080  int skip_size = 1;
3081  TP_DOMAIN *domain;
3082 
3083  /* Remove the decimal point, track the prec & scale */
3084  prec = 0;
3085  scale = 0;
3086  for (i = 0; i < astring_length && ret == NO_ERROR; i += skip_size)
3087  {
3088  skip_size = 1;
3089  if (astring[i] == '.')
3090  {
3091  leading_zeroes = false;
3092  decimal_part = true;
3093  scale = astring_length - (i + 1);
3094  }
3095  else if (leading_zeroes)
3096  { /* Look for 1st digit between 1 & 9 */
3097  if (astring[i] >= '1' && astring[i] <= '9')
3098  {
3099  leading_zeroes = false;
3100  num_string[prec] = astring[i];
3101  if (++prec > DB_MAX_NUMERIC_PRECISION)
3102  {
3103  break;
3104  }
3105  }
3106  else if (astring[i] == '+' || astring[i] == '-')
3107  { /* sign found */
3108  if (!sign_found)
3109  {
3110  sign_found = true;
3111  if (astring[i] == '-')
3112  {
3113  negate_value = true;
3114  }
3115  }
3116  else
3117  { /* Duplicate sign characters */
3118  ret = DOMAIN_INCOMPATIBLE;
3119  }
3120  }
3121  else if (astring[i] == '0')
3122  {
3123  /* leading pad '0' found */
3124  pad_character_zero = true;
3125  }
3126  else if (intl_is_space (astring + i, NULL, codeset, &skip_size))
3127  {
3128  /* Just skip this. OK to have leading spaces */
3129  ;
3130  }
3131  else
3132  {
3133  /* Stray Non-numeric compatible character */
3134  ret = DOMAIN_INCOMPATIBLE;
3135  }
3136  }
3137  else
3138  {
3139  /* Only space character should be allowed on trailer. If the first space character is shown after digits, we
3140  * consider it as the beginning of trailer. */
3141  if (trailing_spaces && !intl_is_space (astring + i, NULL, codeset, &skip_size))
3142  {
3143  ret = DOMAIN_INCOMPATIBLE;
3144  }
3145  else if (intl_is_space (astring + i, NULL, codeset, &skip_size))
3146  {
3147  if (!trailing_spaces)
3148  {
3149  trailing_spaces = true;
3150  }
3151  /* Decrease scale if decimal part exists. */
3152  scale -= skip_size;
3153  if (scale < 0)
3154  {
3155  scale = 0;
3156  }
3157  }
3158  else if (astring[i] == ',')
3159  {
3160  /* Accept ',' character on integer part. */
3161  if (decimal_part)
3162  {
3163  ret = DOMAIN_INCOMPATIBLE;
3164  }
3165  }
3166  else if (astring[i] >= '0' && astring[i] <= '9')
3167  {
3168  num_string[prec] = astring[i];
3169  if (++prec > DB_MAX_NUMERIC_PRECISION)
3170  {
3171  break;
3172  }
3173  }
3174  else
3175  {
3176  /* Characters excluding digit, space and comma are not acceptable. */
3177  ret = DOMAIN_INCOMPATIBLE;
3178  }
3179  }
3180  }
3181 
3182  if (ret != NO_ERROR)
3183  {
3184  goto exit_on_error;
3185  }
3186 
3187  /* If there is no overflow, try to parse the decimal string */
3188  if (prec > DB_MAX_NUMERIC_PRECISION)
3189  {
3192  ret = ER_IT_DATA_OVERFLOW;
3193  goto exit_on_error;
3194  }
3195 
3196  if (prec == 0 && pad_character_zero)
3197  {
3198  prec = 1;
3199  num_string[0] = '0';
3200  num_string[prec] = '\0';
3201  numeric_coerce_dec_str_to_num (num_string, num);
3202  }
3203  else
3204  {
3205  num_string[prec] = '\0';
3206  numeric_coerce_dec_str_to_num (num_string, num);
3207  }
3208 
3209  /* Make the return value */
3210  if (negate_value)
3211  {
3212  numeric_negate (num);
3213  }
3214  db_make_numeric (result, num, prec, scale);
3215 
3216  return ret;
3217 
3218 exit_on_error:
3219 
3221 
3222  return (ret == NO_ERROR && (ret = er_errid ()) == NO_ERROR) ? ER_FAILED : ret;
3223 }
3224 
3225 /*
3226  * numeric_coerce_num_to_num () -
3227  * return: NO_ERROR, or ER_code
3228  * src_num(in) : DB_C_NUMERIC
3229  * src_prec(in) : integer value of the precision
3230  * src_scale(in) : integer value of the scale
3231  * dest_prec(in) : integer value of the precision
3232  * dest_scale(in) : integer value of the scale
3233  * dest_num(out) : DB_C_NUMERIC
3234  * Note: This routine converts a numeric of a given precision and scale to
3235  * another precision and scale.
3236  */
3237 int
3238 numeric_coerce_num_to_num (DB_C_NUMERIC src_num, int src_prec, int src_scale, int dest_prec, int dest_scale,
3239  DB_C_NUMERIC dest_num)
3240 {
3241  int ret = NO_ERROR;
3242  char num_string[DB_MAX_NUMERIC_PRECISION * 4];
3243  int scale_diff;
3244  int orig_length;
3245  int i, len;
3246  bool round_up = false;
3247  bool negate_answer;
3248 
3249  if (src_num == NULL)
3250  {
3251  return ER_FAILED;
3252  }
3253 
3254  /* Check for trivial case */
3255  if (src_prec <= dest_prec && src_scale == dest_scale)
3256  {
3257  numeric_copy (dest_num, src_num);
3258  return NO_ERROR;
3259  }
3260 
3261  /* If src is negative, coerce the positive part now so that rounding is always done in the correct 'direction'. */
3262  if (numeric_is_negative (src_num))
3263  {
3264  negate_answer = true;
3265  numeric_copy (dest_num, src_num);
3266  numeric_negate (dest_num);
3267  }
3268  else
3269  {
3270  negate_answer = false;
3271  numeric_copy (dest_num, src_num);
3272  }
3273 
3274  /* Convert the src_num into a decimal string */
3275  numeric_coerce_num_to_dec_str (dest_num, num_string);
3276  /* Scale the number */
3277  if (src_scale < dest_scale)
3278  { /* add trailing zeroes */
3279  scale_diff = dest_scale - src_scale;
3280  orig_length = strlen (num_string);
3281  for (i = 0; i < scale_diff; i++)
3282  {
3283  num_string[orig_length + i] = '0';
3284  }
3285  num_string[orig_length + scale_diff] = '\0';
3286  }
3287  else if (dest_scale < src_scale)
3288  { /* Truncate and prepare for rounding */
3289  scale_diff = src_scale - dest_scale;
3290  orig_length = strlen (num_string);
3291  if (num_string[orig_length - scale_diff] >= '5' && num_string[orig_length - scale_diff] <= '9')
3292  {
3293  round_up = true;
3294  }
3295  num_string[orig_length - scale_diff] = '\0';
3296  }
3297 
3298  /*
3299  * Check to see if the scaled number 'fits' into the desired precision
3300  * and scaling by looking for significant digits prior to the last
3301  * 'precision' digits.
3302  */
3303  for (i = 0, len = strlen (num_string) - dest_prec; i < len; i++)
3304  {
3305  if (num_string[i] >= '1' && num_string[i] <= '9')
3306  {
3307  ret = ER_IT_DATA_OVERFLOW;
3308  goto exit_on_error;
3309  }
3310  }
3311 
3312  /* only when all number are 9, round up will led overflow. */
3313  if (round_up)
3314  {
3315  bool is_all_nine = true;
3316  for (len = strlen (num_string), i = len - dest_prec; i < len; i++)
3317  {
3318  if (num_string[i] != '9')
3319  {
3320  is_all_nine = false;
3321  break;
3322  }
3323  }
3324  if (is_all_nine)
3325  {
3326  ret = ER_IT_DATA_OVERFLOW;
3327  goto exit_on_error;
3328  }
3329  }
3330 
3331  /* Convert scaled string into destination */
3332  numeric_coerce_dec_str_to_num (num_string, dest_num);
3333  /* Round up, if necessary */
3334  if (round_up)
3335  {
3336  numeric_increase (dest_num);
3337  }
3338 
3339  /* Negate the answer, if necessary */
3340  if (negate_answer)
3341  {
3342  numeric_negate (dest_num);
3343  }
3344 
3345  return ret;
3346 
3347 exit_on_error:
3348 
3349  return (ret == NO_ERROR && (ret = er_errid ()) == NO_ERROR) ? ER_FAILED : ret;
3350 }
3351 
3352 /*
3353  * get_significant_digit () -
3354  * return: significant digit of integer value
3355  * i(in) :
3356  */
3357 static int
3359 {
3360  int n = 0;
3361 
3362  do
3363  {
3364  n++;
3365  i /= 10;
3366  }
3367  while (i != 0);
3368 
3369  return n;
3370 }
3371 
3372 /*
3373  * numeric_db_value_coerce_to_num () -
3374  * return: NO_ERROR, or ER_code
3375  * src(in) : ptr to a DB_VALUE of some numerical type
3376  * dest(in/out): ptr to a DB_VALUE of type DB_TYPE_NUMERIC
3377  * data_status(out): ptr to a DB_DATA_STATUS value
3378  *
3379  * Note: This routine converts a DB_VALUE of some numerical type into a
3380  * DB_VALUE of type DB_TYPE_NUMERIC. The precision and scale fields of
3381  * are assumed to represent the desired values of the output. If they are
3382  * set to DB_DEFAULT_PRECISION/SCALE, the default values are implied. If
3383  * they are set to 0, the precision and scale are set to be the maximum
3384  * amount necessary in order to preserve as much data as possible.
3385  */
3386 int
3388 {
3389  int ret = NO_ERROR;
3390  unsigned char num[DB_NUMERIC_BUF_SIZE]; /* copy of a DB_C_NUMERIC */
3391  int precision, scale;
3392  int desired_precision, desired_scale;
3393 
3394  *data_status = DATA_STATUS_OK;
3395  desired_precision = DB_VALUE_PRECISION (dest);
3396  desired_scale = DB_VALUE_SCALE (dest);
3397  /* Check for a non NULL src and a dest whose type is DB_TYPE_NUMERIC */
3398  /* Switch on the src type */
3399  switch (DB_VALUE_TYPE (src))
3400  {
3401  case DB_TYPE_DOUBLE:
3402  {
3403  double adouble = db_get_double (src);
3404  ret = numeric_internal_double_to_num (adouble, desired_scale, num, &precision, &scale);
3405  break;
3406  }
3407 
3408  case DB_TYPE_FLOAT:
3409  {
3410  float adouble = (float) db_get_float (src);
3411  ret = numeric_internal_float_to_num (adouble, desired_scale, num, &precision, &scale);
3412  break;
3413  }
3414 
3415  case DB_TYPE_MONETARY:
3416  {
3417  double adouble = db_value_get_monetary_amount_as_double (src);
3418  ret = numeric_internal_double_to_num (adouble, desired_scale, num, &precision, &scale);
3419  break;
3420  }
3421 
3422  case DB_TYPE_INTEGER:
3423  {
3424  int anint = db_get_int (src);
3425 
3426  numeric_coerce_int_to_num (anint, num);
3427  precision = get_significant_digit (anint);
3428  scale = 0;
3429  break;
3430  }
3431 
3432  case DB_TYPE_SMALLINT:
3433  {
3434  int anint = (int) db_get_short (src);
3435 
3436  numeric_coerce_int_to_num (anint, num);
3437  precision = get_significant_digit (anint);
3438  scale = 0;
3439  break;
3440  }
3441 
3442  case DB_TYPE_BIGINT:
3443  {
3444  DB_BIGINT bigint = db_get_bigint (src);
3445 
3446  numeric_coerce_bigint_to_num (bigint, num);
3447  precision = get_significant_digit (bigint);
3448  desired_precision = MAX (desired_precision, precision);
3449  scale = 0;
3450  break;
3451  }
3452 
3453  case DB_TYPE_NUMERIC:
3454  {
3455  precision = DB_VALUE_PRECISION (src);
3456  scale = DB_VALUE_SCALE (src);
3457  numeric_copy (num, db_locate_numeric (src));
3458  break;
3459  }
3460 
3461  case DB_TYPE_ENUMERATION:
3462  {
3463  int anint = db_get_enum_short (src);
3464  numeric_coerce_int_to_num (anint, num);
3465  precision = 5;
3466  scale = 0;
3467  break;
3468  }
3469 
3470  default:
3471  ret = ER_FAILED;
3472  break;
3473  }
3474 
3475  /* Make the destination value */
3476  if (ret == NO_ERROR)
3477  {
3478  /* Make the intermediate value */
3479  db_make_numeric (dest, num, precision, scale);
3480  ret =
3482  desired_precision, desired_scale, num);
3483  if (ret != NO_ERROR)
3484  {
3485  goto exit_on_error;
3486  }
3487 
3488  db_make_numeric (dest, num, desired_precision, desired_scale);
3489  }
3490 
3491  if (ret == ER_IT_DATA_OVERFLOW)
3492  {
3493  *data_status = DATA_STATUS_TRUNCATED;
3494  }
3495 
3496  return ret;
3497 
3498 exit_on_error:
3499 
3500  if (ret == ER_IT_DATA_OVERFLOW)
3501  {
3502  *data_status = DATA_STATUS_TRUNCATED;
3503  }
3504 
3505  return (ret == NO_ERROR && (ret = er_errid ()) == NO_ERROR) ? ER_FAILED : ret;
3506 }
3507 
3508 /*
3509  * numeric_db_value_coerce_from_num () -
3510  * return: NO_ERROR, or ER_code
3511  * src(in) : ptr to a DB_VALUE of type DB_TYPE_NUMERIC
3512  * dest(out) : ptr to a DB_VALUE of some numerical type
3513  * data_status(out): ptr to a DB_DATA_STATUS value
3514  *
3515  * Note: This routine converts a DB_VALUE of type DB_TYPE_NUMERIC into some
3516  * numerical type.
3517  */
3518 int
3520 {
3521  int ret = NO_ERROR;
3522 
3523  *data_status = DATA_STATUS_OK;
3524  /* Check for a DB_TYPE_NUMERIC src and a non NULL numerical dest */
3525  /* Switch on the dest type */
3526  switch (DB_VALUE_DOMAIN_TYPE (dest))
3527  {
3528  case DB_TYPE_DOUBLE:
3529  {
3530  double adouble;
3532  if (OR_CHECK_DOUBLE_OVERFLOW (adouble))
3533  {
3534  ret = ER_IT_DATA_OVERFLOW;
3535  goto exit_on_error;
3536  }
3537  db_make_double (dest, adouble);
3538  break;
3539  }
3540 
3541  case DB_TYPE_FLOAT:
3542  {
3543  double adouble;
3545  if (OR_CHECK_FLOAT_OVERFLOW (adouble))
3546  {
3547  ret = ER_IT_DATA_OVERFLOW;
3548  goto exit_on_error;
3549  }
3550  db_make_float (dest, (float) adouble);
3551  break;
3552  }
3553 
3554  case DB_TYPE_MONETARY:
3555  {
3556  double adouble;
3558  db_make_monetary (dest, DB_CURRENCY_DEFAULT, adouble);
3559  break;
3560  }
3561 
3562  case DB_TYPE_INTEGER:
3563  {
3564  double adouble;
3566  if (OR_CHECK_INT_OVERFLOW (adouble))
3567  {
3568  ret = ER_IT_DATA_OVERFLOW;
3569  goto exit_on_error;
3570  }
3571  db_make_int (dest, (int) ROUND (adouble));
3572  break;
3573  }
3574 
3575  case DB_TYPE_BIGINT:
3576  {
3577  DB_BIGINT bint;
3578 
3580  if (ret != NO_ERROR)
3581  {
3582  goto exit_on_error;
3583  }
3584 
3585  db_make_bigint (dest, bint);
3586  break;
3587  }
3588 
3589  case DB_TYPE_SMALLINT:
3590  {
3591  double adouble;
3593  if (OR_CHECK_SHORT_OVERFLOW (adouble))
3594  {
3595  ret = ER_IT_DATA_OVERFLOW;
3596  goto exit_on_error;
3597  }
3598  db_make_short (dest, (DB_C_SHORT) ROUND (adouble));
3599  break;
3600  }
3601 
3602  case DB_TYPE_NUMERIC:
3603  {
3604  ret = numeric_db_value_coerce_to_num (src, dest, data_status);
3605  break;
3606  }
3607 
3608  case DB_TYPE_CHAR:
3609  case DB_TYPE_VARCHAR:
3610  case DB_TYPE_NCHAR:
3611  case DB_TYPE_VARNCHAR:
3612  {
3613  char *return_string = NULL;
3614  char str_buf[NUMERIC_MAX_STRING_SIZE];
3615  int size = 0;
3616  DB_TYPE type;
3617 
3618  numeric_db_value_print (src, str_buf);
3619  size = strlen (str_buf);
3620  return_string = (char *) db_private_alloc (NULL, size + 1);
3621  if (return_string == NULL)
3622  {
3623  assert (er_errid () != NO_ERROR);
3624  return er_errid ();
3625  }
3626 
3627  strcpy (return_string, str_buf);
3628  type = DB_VALUE_DOMAIN_TYPE (dest);
3629  if (type == DB_TYPE_CHAR)
3630  {
3631  db_make_char (dest, size, return_string, size, LANG_SYS_CODESET, LANG_SYS_COLLATION);
3632  }
3633  else if (type == DB_TYPE_VARCHAR)
3634  {
3635  db_make_varchar (dest, size, return_string, size, LANG_SYS_CODESET, LANG_SYS_COLLATION);
3636  }
3637  else if (type == DB_TYPE_NCHAR)
3638  {
3639  db_make_nchar (dest, size, return_string, size, LANG_SYS_CODESET, LANG_SYS_COLLATION);
3640  }
3641  else if (type == DB_TYPE_VARNCHAR)
3642  {
3643  db_make_varnchar (dest, size, return_string, size, LANG_SYS_CODESET, LANG_SYS_COLLATION);
3644  }
3645  dest->need_clear = true;
3646  break;
3647  }
3648 
3649  case DB_TYPE_TIME:
3650  {
3651  double adouble;
3652  DB_TIME v_time;
3653  int hour, minute, second;
3654 
3656  v_time = (int) (adouble + 0.5) % SECONDS_IN_A_DAY;
3657  db_time_decode (&v_time, &hour, &minute, &second);
3658  db_make_time (dest, hour, minute, second);
3659  break;
3660  }
3661 
3662  case DB_TYPE_DATE:
3663  {
3664  double adouble;
3665  DB_DATE v_date;
3666  int year, month, day;
3667 
3669  v_date = (DB_DATE) (adouble);
3670  db_date_decode (&v_date, &month, &day, &year);
3671  db_make_date (dest, month, day, year);
3672  break;
3673  }
3674 
3675  case DB_TYPE_TIMESTAMP:
3676  {
3677  double adouble;
3678  DB_TIMESTAMP v_timestamp;
3679 
3681  v_timestamp = (DB_TIMESTAMP) (adouble);
3682  db_make_timestamp (dest, v_timestamp);
3683  break;
3684  }
3685 
3686  case DB_TYPE_DATETIME:
3687  {
3688  DB_BIGINT bi, tmp_bi;
3689  DB_DATETIME v_datetime;
3690 
3692  if (ret == NO_ERROR)
3693  {
3694  /* make datetime value from interval value */
3695  tmp_bi = (DB_BIGINT) (bi / MILLISECONDS_OF_ONE_DAY);
3696  if (OR_CHECK_INT_OVERFLOW (tmp_bi))
3697  {
3698  ret = ER_IT_DATA_OVERFLOW;
3699  }
3700  else
3701  {
3702  v_datetime.date = (int) tmp_bi;
3703  v_datetime.time = (int) (bi % MILLISECONDS_OF_ONE_DAY);
3704  db_make_datetime (dest, &v_datetime);
3705  }
3706  }
3707  break;
3708  }
3709 
3710  default:
3711  ret = DOMAIN_INCOMPATIBLE;
3712  break;
3713  }
3714 
3715  return ret;
3716 
3717 exit_on_error:
3718 
3719  return (ret == NO_ERROR && (ret = er_errid ()) == NO_ERROR) ? ER_FAILED : ret;
3720 }
3721 
3722 /*
3723  * numeric_db_value_coerce_from_num_strict () - coerce a numeric to the type
3724  * of dest
3725  * return : error code or NO_ERROR
3726  * src (in) : the numeric value
3727  * dest(in/out) : the value to coerce to
3728  */
3729 int
3731 {
3732  int ret = NO_ERROR;
3733 
3734  switch (DB_VALUE_DOMAIN_TYPE (dest))
3735  {
3736  case DB_TYPE_DOUBLE:
3737  {
3738  double adouble;
3740  if (OR_CHECK_DOUBLE_OVERFLOW (adouble))
3741  {
3742  return ER_FAILED;
3743  }
3744  db_make_double (dest, adouble);
3745  break;
3746  }
3747 
3748  case DB_TYPE_FLOAT:
3749  {
3750  double adouble;
3752  if (OR_CHECK_FLOAT_OVERFLOW (adouble))
3753  {
3754  return ER_FAILED;
3755  }
3756  db_make_float (dest, (float) adouble);
3757  break;
3758  }
3759 
3760  case DB_TYPE_MONETARY:
3761  {
3762  double adouble;
3764  if (OR_CHECK_FLOAT_OVERFLOW (adouble))
3765  {
3766  return ER_FAILED;
3767  }
3768  db_make_monetary (dest, DB_CURRENCY_DEFAULT, adouble);
3769  break;
3770  }
3771 
3772  case DB_TYPE_INTEGER:
3773  {
3774  double adouble;
3776  if (OR_CHECK_INT_OVERFLOW (adouble))
3777  {
3778  return ER_FAILED;
3779  }
3781  {
3782  return ER_FAILED;
3783  }
3784  db_make_int (dest, (int) (adouble));
3785  break;
3786  }
3787 
3788  case DB_TYPE_BIGINT:
3789  {
3790  DB_BIGINT bint;
3791 
3793  if (ret != NO_ERROR)
3794  {
3795  return ER_FAILED;
3796  }
3797 
3799  {
3800  return ER_FAILED;
3801  }
3802  db_make_bigint (dest, bint);
3803  break;
3804  }
3805 
3806  case DB_TYPE_SMALLINT:
3807  {
3808  double adouble;
3810  if (OR_CHECK_SHORT_OVERFLOW (adouble))
3811  {
3812  return ER_FAILED;
3813  }
3815  {
3816  return ER_FAILED;
3817  }
3818  db_make_short (dest, (DB_C_SHORT) ROUND (adouble));
3819  break;
3820  }
3821 
3822  case DB_TYPE_NUMERIC:
3823  {
3824  DB_DATA_STATUS data_status = DATA_STATUS_OK;
3825  ret = numeric_db_value_coerce_to_num (src, dest, &data_status);
3826  break;
3827  }
3828 
3829  default:
3830  ret = ER_FAILED;
3831  break;
3832  }
3833 
3834  return ER_FAILED;
3835 }
3836 
3837 /*
3838  * numeric_db_value_print () -
3839  * return: a static character buffer that contains the numeric printed in an
3840  * ASCII format.
3841  * val(in) : DB_VALUE of type numeric to print
3842  *
3843  * Note: returns the null-terminated string form of val
3844  */
3845 char *
3846 numeric_db_value_print (const DB_VALUE * val, char *buf)
3847 {
3848  char temp[80];
3849  int nbuf;
3850  int temp_size;
3851  int i;
3852  bool found_first_non_zero = false;
3853  int scale = db_value_scale (val);
3854 
3855  assert (val != NULL && buf != NULL);
3856 
3857  if (DB_IS_NULL (val))
3858  {
3859  buf[0] = '\0';
3860  return buf;
3861  }
3862 
3863  /* Retrieve raw decimal string */
3865 
3866  /* Remove the extra padded zeroes and add the decimal point */
3867  nbuf = 0;
3868  temp_size = (int) strnlen (temp, sizeof (temp));
3869  for (i = 0; i < temp_size; i++)
3870  {
3871  /* Add the negative sign */
3872  if (temp[i] == '-')
3873  {
3874  buf[nbuf] = '-';
3875  nbuf++;
3876  }
3877 
3878  /* Add decimal point */
3879  if (i == temp_size - scale)
3880  {
3881  buf[nbuf] = '.';
3882  nbuf++;
3883  }
3884 
3885  /* Check to see if the first significant digit has been found */
3886  if (!found_first_non_zero && temp[i] >= '1' && temp[i] <= '9')
3887  {
3888  found_first_non_zero = true;
3889  }
3890 
3891  /* Remove leading zeroes */
3892  if (found_first_non_zero || i >= temp_size - scale - 1)
3893  {
3894  buf[nbuf] = temp[i];
3895  nbuf++;
3896  }
3897  }
3898 
3899  /* Null terminate */
3900  buf[nbuf] = '\0';
3901  return buf;
3902 }
3903 
3904 /*
3905  * numeric_db_value_is_zero () -
3906  * return: bool
3907  * arg(in) : DB_VALUE of type DB_NUMERIC
3908  *
3909  * Note: This routine checks if arg = 0.
3910  * This function returns:
3911  * true if arg1 = 0 and
3912  * false otherwise.
3913  *
3914  */
3915 bool
3917 {
3918  if (DB_IS_NULL (arg)) /* NULL values are not 0 */
3919  {
3920  return false;
3921  }
3922  else
3923  {
3924  return (numeric_is_zero (db_get_numeric (arg)));
3925  }
3926 }
3927 
3928 /*
3929  * numeric_db_value_increase () -
3930  * return: NO_ERROR or Error status
3931  * arg(in) : DB_VALUE of type DB_NUMERIC
3932  *
3933  * Note: This routine increments a numeric value.
3934  *
3935  */
3936 int
3938 {
3939  /* Check for bad inputs */
3940  if (DB_IS_NULL (arg) || DB_VALUE_TYPE (arg) != DB_TYPE_NUMERIC)
3941  {
3942  return ER_OBJ_INVALID_ARGUMENTS;
3943  }
3944 
3946 
3947  return NO_ERROR;
3948 }
DB_C_FLOAT db_get_float(const DB_VALUE *value)
#define GET_LOWER_BYTE(arg)
int db_make_datetime(DB_VALUE *value, const DB_DATETIME *datetime)
int numeric_internal_float_to_num(float afloat, int dst_scale, DB_C_NUMERIC num, int *prec, int *scale)
#define NO_ERROR
Definition: error_code.h:46
int db_value_scale(const DB_VALUE *value)
#define LANG_SYS_COLLATION
static DEC_STRING * numeric_get_pow_of_2(int exp)
static bool initialized_10
#define db_locate_numeric(value)
static void numeric_div(DB_C_NUMERIC arg1, DB_C_NUMERIC arg2, DB_C_NUMERIC answer, DB_C_NUMERIC remainder)
#define CARRYOVER(arg)
int db_make_bigint(DB_VALUE *value, const DB_BIGINT num)
int db_get_int(const DB_VALUE *value)
#define DB_DEFAULT_NUMERIC_DIVISION_SCALE
Definition: dbtype_def.h:570
DB_TYPE
Definition: dbtype_def.h:670
DB_C_DOUBLE db_get_double(const DB_VALUE *value)
#define ER_FAILED
Definition: error_code.h:47
void numeric_coerce_num_to_double(DB_C_NUMERIC num, int scale, double *adouble)
int db_make_varchar(DB_VALUE *value, const int max_char_length, DB_CONST_C_CHAR str, const int char_str_byte_size, const int codeset, const int collation_id)
static bool numeric_is_bit_set(DB_C_NUMERIC arg, int pos)
int numeric_db_value_div(const DB_VALUE *dbv1, const DB_VALUE *dbv2, DB_VALUE *answer)
int numeric_db_value_negate(DB_VALUE *answer)
static void numeric_copy_long(DB_C_NUMERIC dest, DB_C_NUMERIC source, bool is_long_num)
int db_make_numeric(DB_VALUE *value, const DB_C_NUMERIC num, const int precision, const int scale)
bool numeric_db_value_is_zero(const DB_VALUE *arg)
DB_C_NUMERIC db_get_numeric(const DB_VALUE *value)
static bool initialized_2
static int numeric_prec_scale_when_overflow(const DB_VALUE *dbv1, const DB_VALUE *dbv2, DB_VALUE *dbv1_common, DB_VALUE *dbv2_common)
int numeric_db_value_compare(const DB_VALUE *dbv1, const DB_VALUE *dbv2, DB_VALUE *answer)
#define TP_FLOAT_MANTISA_DECIMAL_PRECISION
static void numeric_decrease(DB_C_NUMERIC answer)
static void numeric_copy(DB_C_NUMERIC dest, DB_C_NUMERIC source)
int db_make_date(DB_VALUE *value, const int month, const int day, const int year)
char digits[TWICE_NUM_MAX_PREC]
static const char fast_mod[20]
int numeric_db_value_coerce_to_num(DB_VALUE *src, DB_VALUE *dest, DB_DATA_STATUS *data_status)
int er_errid(void)
double db_value_get_monetary_amount_as_double(const DB_VALUE *value)
Definition: db_macro.c:1505
int numeric_db_value_sub(const DB_VALUE *dbv1, const DB_VALUE *dbv2, DB_VALUE *answer)
static void numeric_shift_byte(DB_C_NUMERIC arg, int numbytes, DB_C_NUMERIC answer, int length)
#define DB_VALUE_PRECISION(value)
Definition: dbtype.h:73
static void numeric_init_dec_str(DEC_STRING *answer)
fp_value_type
bool intl_is_space(const char *str, const char *str_end, const INTL_CODESET codeset, int *space_size)
static DEC_STRING powers_of_2[DB_NUMERIC_BUF_SIZE *16]
#define DB_DEFAULT_NUMERIC_SCALE
Definition: dbtype_def.h:567
int numeric_coerce_num_to_num(DB_C_NUMERIC src_num, int src_prec, int src_scale, int dest_prec, int dest_scale, DB_C_NUMERIC dest_num)
#define DB_VALUE_SCALE(value)
Definition: dbtype.h:74
void numeric_coerce_num_to_int(DB_C_NUMERIC arg, int *answer)
static void numeric_init_pow_of_2_helper(void)
short DB_C_SHORT
Definition: dbtype_def.h:1150
#define TP_DOUBLE_MANTISA_DECIMAL_PRECISION
#define TP_DOUBLE_AS_CHAR_LENGTH
static bool numeric_is_long(DB_C_NUMERIC arg)
static int numeric_longnum_to_shortnum(DB_C_NUMERIC answer, DB_C_NUMERIC long_arg)
int db_make_short(DB_VALUE *value, const DB_C_SHORT num)
static unsigned char powers_of_10[TWICE_NUM_MAX_PREC+1][DB_NUMERIC_BUF_SIZE]
unsigned int DB_TIMESTAMP
Definition: dbtype_def.h:759
static void numeric_negate(DB_C_NUMERIC answer)
#define OR_CHECK_DOUBLE_OVERFLOW(i)
TP_DOMAIN * tp_domain_resolve_default(DB_TYPE type)
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
#define DB_MAX_NUMERIC_PRECISION
Definition: dbtype_def.h:522
static int get_significant_digit(DB_BIGINT i)
static void numeric_coerce_big_num_to_dec_str(unsigned char *num, char *dec_str)
#define DB_INT32_MIN
Definition: dbtype_def.h:632
#define assert(x)
int db_make_monetary(DB_VALUE *value, const DB_CURRENCY type, const double amount)
static int numeric_get_msb_for_dec(int src_prec, int src_scale, unsigned char *src, int *dest_prec, int *dest_scale, DB_C_NUMERIC dest)
int numeric_db_value_increase(DB_VALUE *arg)
static void numeric_sub(DB_C_NUMERIC arg1, DB_C_NUMERIC arg2, DB_C_NUMERIC answer, int size)
#define ROUND(x)
static bool numeric_is_zero(DB_C_NUMERIC arg)
static int numeric_scale_by_ten(DB_C_NUMERIC arg, bool is_long_num)
static void return_string(CSS_CONN_ENTRY *conn, unsigned short request_id, char **buffer, int *buffer_size)
Definition: commdb.c:216
#define ER_IT_DATA_OVERFLOW
Definition: error_code.h:505
static bool numeric_is_bigint(DB_C_NUMERIC arg)
#define OR_CHECK_SHORT_OVERFLOW(i)
static void numeric_get_integral_part(const DB_C_NUMERIC num, const int src_prec, const int src_scale, const int dst_prec, DB_C_NUMERIC dest)
static int numeric_compare(DB_C_NUMERIC arg1, DB_C_NUMERIC arg2)
int numeric_db_value_coerce_from_num(DB_VALUE *src, DB_VALUE *dest, DB_DATA_STATUS *data_status)
#define DB_VALUE_DOMAIN_TYPE(value)
Definition: dbtype.h:70
void numeric_coerce_bigint_to_num(DB_BIGINT arg, DB_C_NUMERIC answer)
#define DB_INT32_MAX
Definition: dbtype_def.h:633
#define _dtoa
Definition: mprec.h:362
static int numeric_scale_dec(const DB_C_NUMERIC arg, int dscale, DB_C_NUMERIC answer)
#define OR_CHECK_INT_OVERFLOW(i)
static void numeric_add(DB_C_NUMERIC arg1, DB_C_NUMERIC arg2, DB_C_NUMERIC answer, int size)
static void numeric_negate_long(DB_C_NUMERIC answer, bool is_long_num)
unsigned char buf[DB_NUMERIC_BUF_SIZE]
Definition: dbtype_def.h:794
#define TP_DOMAIN_TYPE(dom)
static bool numeric_is_negative(DB_C_NUMERIC arg)
static void numeric_increase(DB_C_NUMERIC answer)
#define NULL
Definition: freelistheap.h:34
unsigned short db_get_enum_short(const DB_VALUE *value)
#define NUMERIC_MAX_STRING_SIZE
unsigned char * DB_C_NUMERIC
Definition: dbtype_def.h:1214
#define NUMERIC_ABS(a)
const char * pr_type_name(DB_TYPE id)
void numeric_coerce_int_to_num(int arg, DB_C_NUMERIC answer)
static void numeric_add_dec_str(DEC_STRING *arg1, DEC_STRING *arg2, DEC_STRING *answer)
#define MILLISECONDS_OF_ONE_DAY
static bool numeric_is_longnum_value(DB_C_NUMERIC arg)
static bool numeric_is_fraction_part_zero(const DB_C_NUMERIC num, const int scale)
static void numeric_init_pow_of_10_helper(void)
int numeric_db_value_is_positive(const DB_VALUE *dbvalue)
static int numeric_fast_convert(double adouble, int dst_scale, DB_C_NUMERIC num, int *prec, int *scale)
#define SECONDS_IN_A_DAY
void numeric_coerce_num_to_dec_str(DB_C_NUMERIC num, char *dec_str)
int numeric_coerce_num_to_bigint(DB_C_NUMERIC arg, int scale, DB_BIGINT *answer)
int numeric_db_value_coerce_from_num_strict(DB_VALUE *src, DB_VALUE *dest)
#define db_private_alloc(thrd, size)
Definition: memory_alloc.h:227
int numeric_db_value_mul(const DB_VALUE *dbv1, const DB_VALUE *dbv2, DB_VALUE *answer)
need_clear_type need_clear
Definition: dbtype_def.h:1084
DB_BIGINT db_get_bigint(const DB_VALUE *value)
#define DB_DEFAULT_NUMERIC_PRECISION
Definition: dbtype_def.h:564
int db_make_time(DB_VALUE *value, const int hour, const int minute, const int second)
#define DB_DEFAULT_SCALE
Definition: dbtype_def.h:561
static int numeric_scale_dec_long(DB_C_NUMERIC answer, int dscale, bool is_long_num)
#define DB_LONG_NUMERIC_MULTIPLIER
int64_t DB_BIGINT
Definition: dbtype_def.h:751
int db_make_float(DB_VALUE *value, const DB_C_FLOAT num)
static void numeric_get_fractional_part(const DB_C_NUMERIC num, const int src_scale, const int dst_prec, DB_C_NUMERIC dest)
#define DB_DEFAULT_PRECISION
Definition: dbtype_def.h:558
static void numeric_long_div(DB_C_NUMERIC a1, DB_C_NUMERIC a2, DB_C_NUMERIC answer, DB_C_NUMERIC remainder, bool is_long_num)
int numeric_internal_double_to_num(double adouble, int dst_scale, DB_C_NUMERIC num, int *prec, int *scale)
char * numeric_db_value_print(const DB_VALUE *val, char *buf)
#define OR_CHECK_FLOAT_OVERFLOW(i)
#define ARG_FILE_LINE
Definition: error_manager.h:44
unsigned int DB_TIME
Definition: dbtype_def.h:754
unsigned int DB_DATE
Definition: dbtype_def.h:771
DB_DATA_STATUS
void numeric_coerce_dec_str_to_num(const char *dec_str, DB_C_NUMERIC result)
#define strlen(s1)
Definition: intl_support.c:43
#define ER_OBJ_INVALID_ARGUMENTS
Definition: error_code.h:275
enum fp_value_type FP_VALUE_TYPE
unsigned int date
Definition: dbtype_def.h:776
enum intl_codeset INTL_CODESET
Definition: intl_support.h:190
bool prm_get_bool_value(PARAM_ID prm_id)
DB_C_SHORT db_get_short(const DB_VALUE *value)
void er_clear(void)
int db_make_varnchar(DB_VALUE *value, const int max_nchar_length, DB_CONST_C_NCHAR str, const int nchar_str_byte_size, const int codeset, const int collation_id)
#define DB_VALUE_TYPE(value)
Definition: dbtype.h:72
#define DB_CURRENCY_DEFAULT
Definition: dbtype.h:46
int i
Definition: dynamic_load.c:954
static DB_C_NUMERIC numeric_get_pow_of_10(int exp)
int db_make_null(DB_VALUE *value)
static bool numeric_overflow(DB_C_NUMERIC arg, int exp)
#define DB_IS_NULL(value)
Definition: dbtype.h:63
int db_make_double(DB_VALUE *value, const DB_C_DOUBLE num)
union db_numeric::@51 d
void db_date_decode(const DB_DATE *date, int *monthp, int *dayp, int *yearp)
Definition: db_date.c:338
#define DB_NUMERIC_BUF_SIZE
Definition: dbtype_def.h:573
int db_make_timestamp(DB_VALUE *value, const DB_C_TIMESTAMP timeval)
int db_make_int(DB_VALUE *value, const int num)
void numeric_db_value_abs(DB_C_NUMERIC src_num, DB_C_NUMERIC dest_num)
#define DB_NUMERIC_OVERFLOW_LIMIT
Definition: dbtype_def.h:525
int db_make_char(DB_VALUE *value, const int char_length, DB_CONST_C_CHAR str, const int char_str_byte_size, const int codeset, const int collation_id)
static double numeric_Pow_of_10[10]
int numeric_db_value_add(const DB_VALUE *dbv1, const DB_VALUE *dbv2, DB_VALUE *answer)
static void numeric_double_shift_bit(DB_C_NUMERIC arg1, DB_C_NUMERIC arg2, int numbits, DB_C_NUMERIC lsb, DB_C_NUMERIC msb, bool is_long_num)
static void numeric_mul(DB_C_NUMERIC a1, DB_C_NUMERIC a2, bool *positive_flag, DB_C_NUMERIC answer)
#define LANG_SYS_CODESET
int numeric_coerce_string_to_num(const char *astring, int astring_length, INTL_CODESET codeset, DB_VALUE *result)
static void numeric_zero(DB_C_NUMERIC answer, int size)
void db_time_decode(DB_TIME *timeval, int *hourp, int *minutep, int *secondp)
Definition: db_date.c:432
static int numeric_internal_real_to_num(double adouble, int dst_scale, DB_C_NUMERIC num, int *prec, int *scale, bool is_float)
static FP_VALUE_TYPE get_fp_value_type(double d)
#define DB_NUMERIC_UNDERFLOW_LIMIT
Definition: dbtype_def.h:528
#define TWICE_NUM_MAX_PREC
unsigned int time
Definition: dbtype_def.h:777
int db_make_nchar(DB_VALUE *value, const int nchar_length, DB_CONST_C_NCHAR str, const int nchar_str_byte_size, const int codeset, const int collation_id)
static void numeric_shortnum_to_longnum(DB_C_NUMERIC long_answer, DB_C_NUMERIC arg)
static int numeric_compare_pos(DB_C_NUMERIC arg1, DB_C_NUMERIC arg2)
static void numeric_increase_long(DB_C_NUMERIC answer, bool is_long_num)
int db_value_domain_init(DB_VALUE *value, const DB_TYPE type, const int precision, const int scale)
Definition: db_macro.c:153
static void numeric_negative_one(DB_C_NUMERIC answer, int size)
static int numeric_common_prec_scale(const DB_VALUE *dbv1, const DB_VALUE *dbv2, DB_VALUE *dbv1_common, DB_VALUE *dbv2_common)