#include "postgres_fe.h"
#include <ctype.h>
#include <float.h>
#include <limits.h>
#include "pgtypes_error.h"
#include "pgtypes_numeric.h"
#include "pgtypeslib_extern.h"
Go to the source code of this file.
|
| static int | alloc_var (numeric *var, int ndigits) |
| |
| numeric * | PGTYPESnumeric_new (void) |
| |
| decimal * | PGTYPESdecimal_new (void) |
| |
| static int | set_var_from_str (char *str, char **ptr, numeric *dest) |
| |
| static char * | get_str_from_var (numeric *var, int dscale) |
| |
| numeric * | PGTYPESnumeric_from_asc (char *str, char **endptr) |
| |
| char * | PGTYPESnumeric_to_asc (numeric *num, int dscale) |
| |
| static void | zero_var (numeric *var) |
| |
| void | PGTYPESnumeric_free (numeric *var) |
| |
| void | PGTYPESdecimal_free (decimal *var) |
| |
| static int | cmp_abs (numeric *var1, numeric *var2) |
| |
| static int | add_abs (numeric *var1, numeric *var2, numeric *result) |
| |
| static int | sub_abs (numeric *var1, numeric *var2, numeric *result) |
| |
| int | PGTYPESnumeric_add (numeric *var1, numeric *var2, numeric *result) |
| |
| int | PGTYPESnumeric_sub (numeric *var1, numeric *var2, numeric *result) |
| |
| int | PGTYPESnumeric_mul (numeric *var1, numeric *var2, numeric *result) |
| |
| static int | select_div_scale (numeric *var1, numeric *var2, int *rscale) |
| |
| int | PGTYPESnumeric_div (numeric *var1, numeric *var2, numeric *result) |
| |
| int | PGTYPESnumeric_cmp (numeric *var1, numeric *var2) |
| |
| int | PGTYPESnumeric_from_int (signed int int_val, numeric *var) |
| |
| int | PGTYPESnumeric_from_long (signed long int long_val, numeric *var) |
| |
| int | PGTYPESnumeric_copy (numeric *src, numeric *dst) |
| |
| int | PGTYPESnumeric_from_double (double d, numeric *dst) |
| |
| static int | numericvar_to_double (numeric *var, double *dp) |
| |
| int | PGTYPESnumeric_to_double (numeric *nv, double *dp) |
| |
| int | PGTYPESnumeric_to_int (numeric *nv, int *ip) |
| |
| int | PGTYPESnumeric_to_long (numeric *nv, long *lp) |
| |
| int | PGTYPESnumeric_to_decimal (numeric *src, decimal *dst) |
| |
| int | PGTYPESnumeric_from_decimal (decimal *src, numeric *dst) |
| |
◆ digitbuf_alloc
◆ digitbuf_free
◆ init_var
◆ Max
◆ Min
◆ add_abs()
Definition at line 465 of file numeric.c.
466{
474 i1,
475 i2;
477
478
483
490
492 return -1;
494
498 {
499 i1--;
500 i2--;
505
507 {
510 }
511 else
512 {
515 }
516 }
517
519 {
523 }
526
529
537
538 return 0;
539}
#define digitbuf_free(buf)
#define digitbuf_alloc(size)
References digitbuf_alloc, digitbuf_free, fb(), i, Max, and result.
◆ alloc_var()
◆ cmp_abs()
Definition at line 407 of file numeric.c.
408{
409 int i1 = 0;
410 int i2 = 0;
414
416 {
417 if (
var1->digits[i1++] != 0)
418 return 1;
420 }
422 {
423 if (
var2->digits[i2++] != 0)
424 return -1;
426 }
427
429 {
431 {
434 {
436 return 1;
437 return -1;
438 }
439 }
440 }
441
443 {
444 if (
var1->digits[i1++] != 0)
445 return 1;
446 }
448 {
449 if (
var2->digits[i2++] != 0)
450 return -1;
451 }
452
453 return 0;
454}
References fb(), and stat.
◆ get_str_from_var()
Definition at line 226 of file numeric.c.
227{
231 int d;
232
234 {
240 }
241
242
243
244
247 {
249
251
253 {
257 }
258
260 {
264 }
265 }
266 else
268
269
270
271
275
276
277
278
281
282
283
284
286 d = 0;
287
289 {
292 else
295 }
296
297
298
299
300 if (dscale > 0)
301 {
304 {
307 else
310 }
311 }
312
313
314
315
318}
char * pgtypes_alloc(long size)
References numeric::digits, fb(), i, Max, Min, numeric::ndigits, NUMERIC_NAN, NUMERIC_NEG, pgtypes_alloc(), numeric::sign, sprintf, str, and numeric::weight.
◆ numericvar_to_double()
Definition at line 1432 of file numeric.c.
1433{
1434 char *tmp;
1436 char *endptr;
1438
1440 return -1;
1441
1443 {
1445 return -1;
1446 }
1447
1450
1452 return -1;
1453
1454
1455
1456
1460 {
1464 else
1466 return -1;
1467 }
1468
1469
1470 if (*endptr != '\0')
1471 {
1472
1475 return -1;
1476 }
1479 return 0;
1480}
static char * get_str_from_var(const NumericVar *var)
int PGTYPESnumeric_copy(numeric *src, numeric *dst)
numeric * PGTYPESnumeric_new(void)
void PGTYPESnumeric_free(numeric *var)
#define PGTYPES_NUM_BAD_NUMERIC
#define PGTYPES_NUM_OVERFLOW
#define PGTYPES_NUM_UNDERFLOW
References fb(), free, get_str_from_var(), PGTYPES_NUM_BAD_NUMERIC, PGTYPES_NUM_OVERFLOW, PGTYPES_NUM_UNDERFLOW, PGTYPESnumeric_copy(), PGTYPESnumeric_free(), PGTYPESnumeric_new(), and val.
Referenced by PGTYPESnumeric_to_double().
◆ PGTYPESdecimal_free()
◆ PGTYPESdecimal_new()
◆ PGTYPESnumeric_add()
Definition at line 637 of file numeric.c.
638{
639
640
641
643 {
645 {
646
647
648
650 return -1;
652 }
653 else
654 {
655
656
657
659 {
660 case 0:
661
662
663
664
665
669 break;
670
671 case 1:
672
673
674
675
676
678 return -1;
680 break;
681
682 case -1:
683
684
685
686
687
689 return -1;
691 break;
692 }
693 }
694 }
695 else
696 {
698 {
699
700
701
702
703
705 {
706 case 0:
707
708
709
710
711
715 break;
716
717 case 1:
718
719
720
721
722
724 return -1;
726 break;
727
728 case -1:
729
730
731
732
733
735 return -1;
737 break;
738 }
739 }
740 else
741 {
742
743
744
745
746
748 return -1;
750 }
751 }
752
753 return 0;
754}
static void sub_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
static void add_abs(const NumericVar *var1, const NumericVar *var2, NumericVar *result)
static void zero_var(NumericVar *var)
static int cmp_abs(const NumericVar *var1, const NumericVar *var2)
References add_abs(), cmp_abs(), fb(), Max, NUMERIC_NEG, NUMERIC_POS, result, sub_abs(), and zero_var().
Referenced by decadd(), and main().
◆ PGTYPESnumeric_cmp()
◆ PGTYPESnumeric_copy()
Definition at line 1388 of file numeric.c.
1389{
1391
1393 return -1;
1395
1400
1402 return -1;
1403
1406
1407 return 0;
1408}
static void alloc_var(NumericVar *var, int ndigits)
References alloc_var(), numeric::digits, numeric::dscale, fb(), i, numeric::ndigits, numeric::rscale, numeric::sign, numeric::weight, and zero_var().
Referenced by ecpg_get_data(), ecpg_store_input(), main(), numericvar_to_double(), PGTYPESnumeric_from_double(), and PGTYPESnumeric_to_asc().
◆ PGTYPESnumeric_div()
Definition at line 1053 of file numeric.c.
1054{
1070 int rscale;
1074
1075
1076
1077
1080 {
1082 return -1;
1083 }
1084
1085
1086
1087
1090 else
1096
1097
1098
1099
1100 if (
var1->ndigits == 0)
1101 {
1104 return 0;
1105 }
1106
1107
1108
1109
1111 for (
int i = 1;
i < 10;
i++)
1113
1114
1115
1116
1122 goto done;
1126
1127
1128
1129
1136 goto done;
1139
1140
1141
1142
1143
1144
1147 goto done;
1157
1161
1164
1167
1169 {
1174
1178
1180 {
1182 {
1184 long sum = 0;
1185
1189 goto done;
1191 for (
i =
divisor[1].ndigits - 1;
i >= 0;
i--)
1192 {
1195 sum /= 10;
1196 }
1197 }
1198
1201
1204 break;
1205
1207 }
1208
1211 {
1213 break;
1214 }
1215
1218
1220 continue;
1221
1223 goto done;
1224
1230 }
1231
1234 {
1236
1239
1241 {
1245 }
1246 }
1247
1249 {
1253 }
1256 if (
result->ndigits == 0)
1258
1261
1262done:
1263
1264
1265
1266
1269
1270 for (
int i = 1;
i < 10;
i++)
1271 {
1274 }
1275
1277}
static int select_div_scale(const NumericVar *var1, const NumericVar *var2)
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
void err(int eval, const char *fmt,...)
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define PGTYPES_NUM_DIVIDE_ZERO
References buf, cmp_abs(), digitbuf_alloc, digitbuf_free, digits, err(), fb(), i, init_var, memcpy(), NUMERIC_NEG, NUMERIC_POS, PGTYPES_NUM_DIVIDE_ZERO, result, select_div_scale(), sub_abs(), and zero_var().
Referenced by decdiv(), and main().
◆ PGTYPESnumeric_free()
Definition at line 385 of file numeric.c.
References numeric::buf, digitbuf_free, and free.
Referenced by deccall2(), deccall3(), deccvasc(), deccvdbl(), deccvint(), deccvlong(), dectoasc(), dectodbl(), dectoint(), dectolong(), ecpg_get_data(), ecpg_set_compat_sqlda(), ecpg_set_native_sqlda(), ecpg_store_input(), main(), numericvar_to_double(), PGTYPESnumeric_from_asc(), PGTYPESnumeric_from_double(), PGTYPESnumeric_to_asc(), and sqlda_common_total_size().
◆ PGTYPESnumeric_from_asc()
Definition at line 321 of file numeric.c.
322{
324 int ret;
325
328
331
333 if (ret)
334 {
337 }
338
340}
static bool set_var_from_str(const char *str, const char *cp, NumericVar *dest, const char **endptr, Node *escontext)
References fb(), pgtypes_alloc(), PGTYPESnumeric_free(), set_var_from_str(), str, and value.
Referenced by deccvasc(), ecpg_get_data(), ecpg_set_compat_sqlda(), ecpg_set_native_sqlda(), main(), PGTYPESnumeric_from_double(), and sqlda_common_total_size().
◆ PGTYPESnumeric_from_decimal()
Definition at line 1570 of file numeric.c.
1571{
1573
1575
1580
1582 return -1;
1583
1586
1587 return 0;
1588}
NumericDigit digits[DECSIZE]
References alloc_var(), decimal::digits, decimal::dscale, fb(), i, decimal::ndigits, decimal::rscale, decimal::sign, decimal::weight, and zero_var().
Referenced by deccall2(), deccall3(), dectoasc(), dectodbl(), dectoint(), dectolong(), ecpg_store_input(), and main().
◆ PGTYPESnumeric_from_double()
◆ PGTYPESnumeric_from_int()
◆ PGTYPESnumeric_from_long()
Definition at line 1318 of file numeric.c.
1319{
1320
1321
1322
1323
1324
1325
1326
1327
1328 int size = 0;
1333
1335 {
1338 }
1339 else
1341
1343 do
1344 {
1345 size++;
1348
1350 {
1351
1352 size += 2;
1353 }
1354 else
1355 {
1356
1357 size++;
1359 }
1360
1362 return -1;
1363
1367
1369 do
1370 {
1376
1377
1378
1379
1380
1381
1383
1384 return 0;
1385}
References alloc_var(), numeric::digits, numeric::dscale, fb(), i, NUMERIC_NEG, NUMERIC_POS, numeric::rscale, numeric::sign, and numeric::weight.
Referenced by deccvlong(), main(), and PGTYPESnumeric_from_int().
◆ PGTYPESnumeric_mul()
Definition at line 896 of file numeric.c.
897{
905 i1,
906 i2;
907 long sum = 0;
909
914 else
916
918 return -1;
921
923 for (i1 =
var1->ndigits - 1; i1 >= 0; i1--)
924 {
925 sum = 0;
927
928 for (i2 =
var2->ndigits - 1; i2 >= 0; i2--)
929 {
932 sum /= 10;
933 }
935 }
936
939 {
943 while (sum)
944 {
947 sum /= 10;
948 }
949 }
950
952 {
956 }
959
961 {
964 }
965
974
975 return 0;
976}
References digitbuf_alloc, digitbuf_free, fb(), i, NUMERIC_NEG, NUMERIC_POS, and result.
Referenced by decmul(), and main().
◆ PGTYPESnumeric_new()
Definition at line 42 of file numeric.c.
43{
45
48
50 {
53 }
54
55 return var;
56}
References alloc_var(), fb(), free, and pgtypes_alloc().
Referenced by deccall2(), deccall3(), deccvdbl(), deccvint(), deccvlong(), dectoasc(), dectodbl(), dectoint(), dectolong(), ecpg_get_data(), ecpg_store_input(), main(), numericvar_to_double(), and PGTYPESnumeric_to_asc().
◆ PGTYPESnumeric_sub()
Definition at line 765 of file numeric.c.
766{
767
768
769
771 {
773 {
774
775
776
777
778
780 return -1;
782 }
783 else
784 {
785
786
787
788
789
791 {
792 case 0:
793
794
795
796
797
801 break;
802
803 case 1:
804
805
806
807
808
810 return -1;
812 break;
813
814 case -1:
815
816
817
818
819
821 return -1;
823 break;
824 }
825 }
826 }
827 else
828 {
830 {
831
832
833
834
835
837 {
838 case 0:
839
840
841
842
843
847 break;
848
849 case 1:
850
851
852
853
854
856 return -1;
858 break;
859
860 case -1:
861
862
863
864
865
867 return -1;
869 break;
870 }
871 }
872 else
873 {
874
875
876
877
878
880 return -1;
882 }
883 }
884
885 return 0;
886}
References add_abs(), cmp_abs(), fb(), Max, NUMERIC_NEG, NUMERIC_POS, result, sub_abs(), and zero_var().
Referenced by decsub(), and main().
◆ PGTYPESnumeric_to_asc()
◆ PGTYPESnumeric_to_decimal()
Definition at line 1547 of file numeric.c.
1548{
1550
1552 {
1554 return -1;
1555 }
1556
1562
1565
1566 return 0;
1567}
References DECSIZE, numeric::digits, numeric::dscale, fb(), i, numeric::ndigits, PGTYPES_NUM_OVERFLOW, numeric::rscale, numeric::sign, and numeric::weight.
Referenced by deccall3(), deccvasc(), deccvdbl(), deccvint(), deccvlong(), ecpg_get_data(), and main().
◆ PGTYPESnumeric_to_double()
◆ PGTYPESnumeric_to_int()
◆ PGTYPESnumeric_to_long()
◆ select_div_scale()
◆ set_var_from_str()
Definition at line 78 of file numeric.c.
79{
82
85 while (*(*ptr))
86 {
87 if (!
isspace((
unsigned char) *(*ptr)))
88 break;
89 (*ptr)++;
90 }
91
93 {
94 *ptr += 3;
96
97
98 while (*(*ptr))
99 {
100 if (!
isspace((
unsigned char) *(*ptr)))
101 {
103 return -1;
104 }
105 (*ptr)++;
106 }
107
108 return 0;
109 }
110
112 return -1;
116
117 switch (*(*ptr))
118 {
119 case '+':
121 (*ptr)++;
122 break;
123
124 case '-':
126 (*ptr)++;
127 break;
128 }
129
130 if (*(*ptr) == '.')
131 {
133 (*ptr)++;
134 }
135
136 if (!
isdigit((
unsigned char) *(*ptr)))
137 {
139 return -1;
140 }
141
142 while (*(*ptr))
143 {
144 if (
isdigit((
unsigned char) *(*ptr)))
145 {
146 dest->digits[
i++] = *(*ptr)++ -
'0';
149 else
151 }
152 else if (*(*ptr) == '.')
153 {
155 {
157 return -1;
158 }
160 (*ptr)++;
161 }
162 else
163 break;
164 }
166
167
168 if (*(*ptr) == 'e' || *(*ptr) == 'E')
169 {
170 long exponent;
171 char *endptr;
172
173 (*ptr)++;
174 exponent =
strtol(*ptr, &endptr, 10);
175 if (endptr == (*ptr))
176 {
178 return -1;
179 }
180 (*ptr) = endptr;
182 {
184 return -1;
185 }
186 dest->weight += (
int) exponent;
187 dest->dscale -= (
int) exponent;
188 if (
dest->dscale < 0)
190 }
191
192
193 while (*(*ptr))
194 {
195 if (!
isspace((
unsigned char) *(*ptr)))
196 {
198 return -1;
199 }
200 (*ptr)++;
201 }
202
203
204 while (
dest->ndigits > 0 && *(
dest->digits) == 0)
205 {
209 }
210 if (
dest->ndigits == 0)
212
214 return 0;
215}
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
References alloc_var(), fb(), i, NUMERIC_NAN, NUMERIC_NEG, NUMERIC_POS, pg_strncasecmp(), PGTYPES_NUM_BAD_NUMERIC, and str.
◆ sub_abs()
Definition at line 553 of file numeric.c.
554{
562 i1,
563 i2;
565
566
571
578
580 return -1;
582
586 {
587 i1--;
588 i2--;
593
595 {
598 }
599 else
600 {
603 }
604 }
605
607 {
611 }
614
617
625
626 return 0;
627}
References digitbuf_alloc, digitbuf_free, fb(), i, Max, and result.
◆ zero_var()