PostgreSQL Source Code git master
numutils.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * numutils.c
4 * utility functions for I/O of built-in numeric types.
5 *
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/utils/adt/numutils.c
12 *
13 *-------------------------------------------------------------------------
14 */
15#include "postgres.h"
16
17#include <math.h>
18#include <limits.h>
19#include <ctype.h>
20
21#include "common/int.h"
22#include "port/pg_bitutils.h"
23#include "utils/builtins.h"
24
25/*
26 * A table of all two-digit numbers. This is used to speed up decimal digit
27 * generation by copying pairs of digits into the final output.
28 */
29static const char DIGIT_TABLE[200] =
30"00" "01" "02" "03" "04" "05" "06" "07" "08" "09"
31"10" "11" "12" "13" "14" "15" "16" "17" "18" "19"
32"20" "21" "22" "23" "24" "25" "26" "27" "28" "29"
33"30" "31" "32" "33" "34" "35" "36" "37" "38" "39"
34"40" "41" "42" "43" "44" "45" "46" "47" "48" "49"
35"50" "51" "52" "53" "54" "55" "56" "57" "58" "59"
36"60" "61" "62" "63" "64" "65" "66" "67" "68" "69"
37"70" "71" "72" "73" "74" "75" "76" "77" "78" "79"
38"80" "81" "82" "83" "84" "85" "86" "87" "88" "89"
39"90" "91" "92" "93" "94" "95" "96" "97" "98" "99";
40
41/*
42 * Adapted from http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
43 */
44static inline int
46{
47 int t;
48 static const uint32 PowersOfTen[] = {
49 1, 10, 100,
50 1000, 10000, 100000,
51 1000000, 10000000, 100000000,
52 1000000000
53 };
54
55 /*
56 * Compute base-10 logarithm by dividing the base-2 logarithm by a
57 * good-enough approximation of the base-2 logarithm of 10
58 */
59 t = (pg_leftmost_one_pos32(v) + 1) * 1233 / 4096;
60 return t + (v >= PowersOfTen[t]);
61}
62
63static inline int
65{
66 int t;
67 static const uint64 PowersOfTen[] = {
69 UINT64CONST(100), UINT64CONST(1000),
70 UINT64CONST(10000), UINT64CONST(100000),
71 UINT64CONST(1000000), UINT64CONST(10000000),
72 UINT64CONST(100000000), UINT64CONST(1000000000),
73 UINT64CONST(10000000000), UINT64CONST(100000000000),
74 UINT64CONST(1000000000000), UINT64CONST(10000000000000),
75 UINT64CONST(100000000000000), UINT64CONST(1000000000000000),
76 UINT64CONST(10000000000000000), UINT64CONST(100000000000000000),
77 UINT64CONST(1000000000000000000), UINT64CONST(10000000000000000000)
78 };
79
80 /*
81 * Compute base-10 logarithm by dividing the base-2 logarithm by a
82 * good-enough approximation of the base-2 logarithm of 10
83 */
84 t = (pg_leftmost_one_pos64(v) + 1) * 1233 / 4096;
85 return t + (v >= PowersOfTen[t]);
86}
87
88static const int8 hexlookup[128] = {
89 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
90 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
91 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
92 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
93 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
94 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
95 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
96 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
97};
98
99/*
100 * Convert input string to a signed 16 bit integer. Input strings may be
101 * expressed in base-10, hexadecimal, octal, or binary format, all of which
102 * can be prefixed by an optional sign character, either '+' (the default) or
103 * '-' for negative numbers. Hex strings are recognized by the digits being
104 * prefixed by 0x or 0X while octal strings are recognized by the 0o or 0O
105 * prefix. The binary representation is recognized by the 0b or 0B prefix.
106 *
107 * Allows any number of leading or trailing whitespace characters. Digits may
108 * optionally be separated by a single underscore character. These can only
109 * come between digits and not before or after the digits. Underscores have
110 * no effect on the return value and are supported only to assist in improving
111 * the human readability of the input strings.
112 *
113 * pg_strtoint16() will throw ereport() upon bad input format or overflow;
114 * while pg_strtoint16_safe() instead returns such complaints in *escontext,
115 * if it's an ErrorSaveContext.
116*
117 * NB: Accumulate input as an unsigned number, to deal with two's complement
118 * representation of the most negative number, which can't be represented as a
119 * signed positive number.
120 */
121int16
122pg_strtoint16(const char *s)
123{
124 return pg_strtoint16_safe(s, NULL);
125}
126
127int16
128pg_strtoint16_safe(const char *s, Node *escontext)
129{
130 const char *ptr = s;
131 const char *firstdigit;
132 uint16 tmp = 0;
133 bool neg = false;
134 unsigned char digit;
135 int16 result;
136
137 /*
138 * The majority of cases are likely to be base-10 digits without any
139 * underscore separator characters. We'll first try to parse the string
140 * with the assumption that's the case and only fallback on a slower
141 * implementation which handles hex, octal and binary strings and
142 * underscores if the fastpath version cannot parse the string.
143 */
144
145 /* leave it up to the slow path to look for leading spaces */
146
147 if (*ptr == '-')
148 {
149 ptr++;
150 neg = true;
151 }
152
153 /* a leading '+' is uncommon so leave that for the slow path */
154
155 /* process the first digit */
156 digit = (*ptr - '0');
157
158 /*
159 * Exploit unsigned arithmetic to save having to check both the upper and
160 * lower bounds of the digit.
161 */
162 if (likely(digit < 10))
163 {
164 ptr++;
165 tmp = digit;
166 }
167 else
168 {
169 /* we need at least one digit */
170 goto slow;
171 }
172
173 /* process remaining digits */
174 for (;;)
175 {
176 digit = (*ptr - '0');
177
178 if (digit >= 10)
179 break;
180
181 ptr++;
182
183 if (unlikely(tmp > -(PG_INT16_MIN / 10)))
184 goto out_of_range;
185
186 tmp = tmp * 10 + digit;
187 }
188
189 /* when the string does not end in a digit, let the slow path handle it */
190 if (unlikely(*ptr != '\0'))
191 goto slow;
192
193 if (neg)
194 {
195 if (unlikely(pg_neg_u16_overflow(tmp, &result)))
196 goto out_of_range;
197 return result;
198 }
199
200 if (unlikely(tmp > PG_INT16_MAX))
201 goto out_of_range;
202
203 return (int16) tmp;
204
205slow:
206 tmp = 0;
207 ptr = s;
208 /* no need to reset neg */
209
210 /* skip leading spaces */
211 while (isspace((unsigned char) *ptr))
212 ptr++;
213
214 /* handle sign */
215 if (*ptr == '-')
216 {
217 ptr++;
218 neg = true;
219 }
220 else if (*ptr == '+')
221 ptr++;
222
223 /* process digits */
224 if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
225 {
226 firstdigit = ptr += 2;
227
228 for (;;)
229 {
230 if (isxdigit((unsigned char) *ptr))
231 {
232 if (unlikely(tmp > -(PG_INT16_MIN / 16)))
233 goto out_of_range;
234
235 tmp = tmp * 16 + hexlookup[(unsigned char) *ptr++];
236 }
237 else if (*ptr == '_')
238 {
239 /* underscore must be followed by more digits */
240 ptr++;
241 if (*ptr == '\0' || !isxdigit((unsigned char) *ptr))
242 goto invalid_syntax;
243 }
244 else
245 break;
246 }
247 }
248 else if (ptr[0] == '0' && (ptr[1] == 'o' || ptr[1] == 'O'))
249 {
250 firstdigit = ptr += 2;
251
252 for (;;)
253 {
254 if (*ptr >= '0' && *ptr <= '7')
255 {
256 if (unlikely(tmp > -(PG_INT16_MIN / 8)))
257 goto out_of_range;
258
259 tmp = tmp * 8 + (*ptr++ - '0');
260 }
261 else if (*ptr == '_')
262 {
263 /* underscore must be followed by more digits */
264 ptr++;
265 if (*ptr == '\0' || *ptr < '0' || *ptr > '7')
266 goto invalid_syntax;
267 }
268 else
269 break;
270 }
271 }
272 else if (ptr[0] == '0' && (ptr[1] == 'b' || ptr[1] == 'B'))
273 {
274 firstdigit = ptr += 2;
275
276 for (;;)
277 {
278 if (*ptr >= '0' && *ptr <= '1')
279 {
280 if (unlikely(tmp > -(PG_INT16_MIN / 2)))
281 goto out_of_range;
282
283 tmp = tmp * 2 + (*ptr++ - '0');
284 }
285 else if (*ptr == '_')
286 {
287 /* underscore must be followed by more digits */
288 ptr++;
289 if (*ptr == '\0' || *ptr < '0' || *ptr > '1')
290 goto invalid_syntax;
291 }
292 else
293 break;
294 }
295 }
296 else
297 {
298 firstdigit = ptr;
299
300 for (;;)
301 {
302 if (*ptr >= '0' && *ptr <= '9')
303 {
304 if (unlikely(tmp > -(PG_INT16_MIN / 10)))
305 goto out_of_range;
306
307 tmp = tmp * 10 + (*ptr++ - '0');
308 }
309 else if (*ptr == '_')
310 {
311 /* underscore may not be first */
312 if (unlikely(ptr == firstdigit))
313 goto invalid_syntax;
314 /* and it must be followed by more digits */
315 ptr++;
316 if (*ptr == '\0' || !isdigit((unsigned char) *ptr))
317 goto invalid_syntax;
318 }
319 else
320 break;
321 }
322 }
323
324 /* require at least one digit */
325 if (unlikely(ptr == firstdigit))
326 goto invalid_syntax;
327
328 /* allow trailing whitespace, but not other trailing chars */
329 while (isspace((unsigned char) *ptr))
330 ptr++;
331
332 if (unlikely(*ptr != '\0'))
333 goto invalid_syntax;
334
335 if (neg)
336 {
337 if (unlikely(pg_neg_u16_overflow(tmp, &result)))
338 goto out_of_range;
339 return result;
340 }
341
342 if (tmp > PG_INT16_MAX)
343 goto out_of_range;
344
345 return (int16) tmp;
346
347out_of_range:
348 ereturn(escontext, 0,
349 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
350 errmsg("value \"%s\" is out of range for type %s",
351 s, "smallint")));
352
353invalid_syntax:
354 ereturn(escontext, 0,
355 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
356 errmsg("invalid input syntax for type %s: \"%s\"",
357 "smallint", s)));
358}
359
360/*
361 * Convert input string to a signed 32 bit integer. Input strings may be
362 * expressed in base-10, hexadecimal, octal, or binary format, all of which
363 * can be prefixed by an optional sign character, either '+' (the default) or
364 * '-' for negative numbers. Hex strings are recognized by the digits being
365 * prefixed by 0x or 0X while octal strings are recognized by the 0o or 0O
366 * prefix. The binary representation is recognized by the 0b or 0B prefix.
367 *
368 * Allows any number of leading or trailing whitespace characters. Digits may
369 * optionally be separated by a single underscore character. These can only
370 * come between digits and not before or after the digits. Underscores have
371 * no effect on the return value and are supported only to assist in improving
372 * the human readability of the input strings.
373 *
374 * pg_strtoint32() will throw ereport() upon bad input format or overflow;
375 * while pg_strtoint32_safe() instead returns such complaints in *escontext,
376 * if it's an ErrorSaveContext.
377 *
378 * NB: Accumulate input as an unsigned number, to deal with two's complement
379 * representation of the most negative number, which can't be represented as a
380 * signed positive number.
381 */
382int32
383pg_strtoint32(const char *s)
384{
385 return pg_strtoint32_safe(s, NULL);
386}
387
388int32
389pg_strtoint32_safe(const char *s, Node *escontext)
390{
391 const char *ptr = s;
392 const char *firstdigit;
393 uint32 tmp = 0;
394 bool neg = false;
395 unsigned char digit;
396 int32 result;
397
398 /*
399 * The majority of cases are likely to be base-10 digits without any
400 * underscore separator characters. We'll first try to parse the string
401 * with the assumption that's the case and only fallback on a slower
402 * implementation which handles hex, octal and binary strings and
403 * underscores if the fastpath version cannot parse the string.
404 */
405
406 /* leave it up to the slow path to look for leading spaces */
407
408 if (*ptr == '-')
409 {
410 ptr++;
411 neg = true;
412 }
413
414 /* a leading '+' is uncommon so leave that for the slow path */
415
416 /* process the first digit */
417 digit = (*ptr - '0');
418
419 /*
420 * Exploit unsigned arithmetic to save having to check both the upper and
421 * lower bounds of the digit.
422 */
423 if (likely(digit < 10))
424 {
425 ptr++;
426 tmp = digit;
427 }
428 else
429 {
430 /* we need at least one digit */
431 goto slow;
432 }
433
434 /* process remaining digits */
435 for (;;)
436 {
437 digit = (*ptr - '0');
438
439 if (digit >= 10)
440 break;
441
442 ptr++;
443
444 if (unlikely(tmp > -(PG_INT32_MIN / 10)))
445 goto out_of_range;
446
447 tmp = tmp * 10 + digit;
448 }
449
450 /* when the string does not end in a digit, let the slow path handle it */
451 if (unlikely(*ptr != '\0'))
452 goto slow;
453
454 if (neg)
455 {
456 if (unlikely(pg_neg_u32_overflow(tmp, &result)))
457 goto out_of_range;
458 return result;
459 }
460
461 if (unlikely(tmp > PG_INT32_MAX))
462 goto out_of_range;
463
464 return (int32) tmp;
465
466slow:
467 tmp = 0;
468 ptr = s;
469 /* no need to reset neg */
470
471 /* skip leading spaces */
472 while (isspace((unsigned char) *ptr))
473 ptr++;
474
475 /* handle sign */
476 if (*ptr == '-')
477 {
478 ptr++;
479 neg = true;
480 }
481 else if (*ptr == '+')
482 ptr++;
483
484 /* process digits */
485 if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
486 {
487 firstdigit = ptr += 2;
488
489 for (;;)
490 {
491 if (isxdigit((unsigned char) *ptr))
492 {
493 if (unlikely(tmp > -(PG_INT32_MIN / 16)))
494 goto out_of_range;
495
496 tmp = tmp * 16 + hexlookup[(unsigned char) *ptr++];
497 }
498 else if (*ptr == '_')
499 {
500 /* underscore must be followed by more digits */
501 ptr++;
502 if (*ptr == '\0' || !isxdigit((unsigned char) *ptr))
503 goto invalid_syntax;
504 }
505 else
506 break;
507 }
508 }
509 else if (ptr[0] == '0' && (ptr[1] == 'o' || ptr[1] == 'O'))
510 {
511 firstdigit = ptr += 2;
512
513 for (;;)
514 {
515 if (*ptr >= '0' && *ptr <= '7')
516 {
517 if (unlikely(tmp > -(PG_INT32_MIN / 8)))
518 goto out_of_range;
519
520 tmp = tmp * 8 + (*ptr++ - '0');
521 }
522 else if (*ptr == '_')
523 {
524 /* underscore must be followed by more digits */
525 ptr++;
526 if (*ptr == '\0' || *ptr < '0' || *ptr > '7')
527 goto invalid_syntax;
528 }
529 else
530 break;
531 }
532 }
533 else if (ptr[0] == '0' && (ptr[1] == 'b' || ptr[1] == 'B'))
534 {
535 firstdigit = ptr += 2;
536
537 for (;;)
538 {
539 if (*ptr >= '0' && *ptr <= '1')
540 {
541 if (unlikely(tmp > -(PG_INT32_MIN / 2)))
542 goto out_of_range;
543
544 tmp = tmp * 2 + (*ptr++ - '0');
545 }
546 else if (*ptr == '_')
547 {
548 /* underscore must be followed by more digits */
549 ptr++;
550 if (*ptr == '\0' || *ptr < '0' || *ptr > '1')
551 goto invalid_syntax;
552 }
553 else
554 break;
555 }
556 }
557 else
558 {
559 firstdigit = ptr;
560
561 for (;;)
562 {
563 if (*ptr >= '0' && *ptr <= '9')
564 {
565 if (unlikely(tmp > -(PG_INT32_MIN / 10)))
566 goto out_of_range;
567
568 tmp = tmp * 10 + (*ptr++ - '0');
569 }
570 else if (*ptr == '_')
571 {
572 /* underscore may not be first */
573 if (unlikely(ptr == firstdigit))
574 goto invalid_syntax;
575 /* and it must be followed by more digits */
576 ptr++;
577 if (*ptr == '\0' || !isdigit((unsigned char) *ptr))
578 goto invalid_syntax;
579 }
580 else
581 break;
582 }
583 }
584
585 /* require at least one digit */
586 if (unlikely(ptr == firstdigit))
587 goto invalid_syntax;
588
589 /* allow trailing whitespace, but not other trailing chars */
590 while (isspace((unsigned char) *ptr))
591 ptr++;
592
593 if (unlikely(*ptr != '\0'))
594 goto invalid_syntax;
595
596 if (neg)
597 {
598 if (unlikely(pg_neg_u32_overflow(tmp, &result)))
599 goto out_of_range;
600 return result;
601 }
602
603 if (tmp > PG_INT32_MAX)
604 goto out_of_range;
605
606 return (int32) tmp;
607
608out_of_range:
609 ereturn(escontext, 0,
610 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
611 errmsg("value \"%s\" is out of range for type %s",
612 s, "integer")));
613
614invalid_syntax:
615 ereturn(escontext, 0,
616 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
617 errmsg("invalid input syntax for type %s: \"%s\"",
618 "integer", s)));
619}
620
621/*
622 * Convert input string to a signed 64 bit integer. Input strings may be
623 * expressed in base-10, hexadecimal, octal, or binary format, all of which
624 * can be prefixed by an optional sign character, either '+' (the default) or
625 * '-' for negative numbers. Hex strings are recognized by the digits being
626 * prefixed by 0x or 0X while octal strings are recognized by the 0o or 0O
627 * prefix. The binary representation is recognized by the 0b or 0B prefix.
628 *
629 * Allows any number of leading or trailing whitespace characters. Digits may
630 * optionally be separated by a single underscore character. These can only
631 * come between digits and not before or after the digits. Underscores have
632 * no effect on the return value and are supported only to assist in improving
633 * the human readability of the input strings.
634 *
635 * pg_strtoint64() will throw ereport() upon bad input format or overflow;
636 * while pg_strtoint64_safe() instead returns such complaints in *escontext,
637 * if it's an ErrorSaveContext.
638 *
639 * NB: Accumulate input as an unsigned number, to deal with two's complement
640 * representation of the most negative number, which can't be represented as a
641 * signed positive number.
642 */
643int64
644pg_strtoint64(const char *s)
645{
646 return pg_strtoint64_safe(s, NULL);
647}
648
649int64
650pg_strtoint64_safe(const char *s, Node *escontext)
651{
652 const char *ptr = s;
653 const char *firstdigit;
654 uint64 tmp = 0;
655 bool neg = false;
656 unsigned char digit;
657 int64 result;
658
659 /*
660 * The majority of cases are likely to be base-10 digits without any
661 * underscore separator characters. We'll first try to parse the string
662 * with the assumption that's the case and only fallback on a slower
663 * implementation which handles hex, octal and binary strings and
664 * underscores if the fastpath version cannot parse the string.
665 */
666
667 /* leave it up to the slow path to look for leading spaces */
668
669 if (*ptr == '-')
670 {
671 ptr++;
672 neg = true;
673 }
674
675 /* a leading '+' is uncommon so leave that for the slow path */
676
677 /* process the first digit */
678 digit = (*ptr - '0');
679
680 /*
681 * Exploit unsigned arithmetic to save having to check both the upper and
682 * lower bounds of the digit.
683 */
684 if (likely(digit < 10))
685 {
686 ptr++;
687 tmp = digit;
688 }
689 else
690 {
691 /* we need at least one digit */
692 goto slow;
693 }
694
695 /* process remaining digits */
696 for (;;)
697 {
698 digit = (*ptr - '0');
699
700 if (digit >= 10)
701 break;
702
703 ptr++;
704
705 if (unlikely(tmp > -(PG_INT64_MIN / 10)))
706 goto out_of_range;
707
708 tmp = tmp * 10 + digit;
709 }
710
711 /* when the string does not end in a digit, let the slow path handle it */
712 if (unlikely(*ptr != '\0'))
713 goto slow;
714
715 if (neg)
716 {
717 if (unlikely(pg_neg_u64_overflow(tmp, &result)))
718 goto out_of_range;
719 return result;
720 }
721
722 if (unlikely(tmp > PG_INT64_MAX))
723 goto out_of_range;
724
725 return (int64) tmp;
726
727slow:
728 tmp = 0;
729 ptr = s;
730 /* no need to reset neg */
731
732 /* skip leading spaces */
733 while (isspace((unsigned char) *ptr))
734 ptr++;
735
736 /* handle sign */
737 if (*ptr == '-')
738 {
739 ptr++;
740 neg = true;
741 }
742 else if (*ptr == '+')
743 ptr++;
744
745 /* process digits */
746 if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
747 {
748 firstdigit = ptr += 2;
749
750 for (;;)
751 {
752 if (isxdigit((unsigned char) *ptr))
753 {
754 if (unlikely(tmp > -(PG_INT64_MIN / 16)))
755 goto out_of_range;
756
757 tmp = tmp * 16 + hexlookup[(unsigned char) *ptr++];
758 }
759 else if (*ptr == '_')
760 {
761 /* underscore must be followed by more digits */
762 ptr++;
763 if (*ptr == '\0' || !isxdigit((unsigned char) *ptr))
764 goto invalid_syntax;
765 }
766 else
767 break;
768 }
769 }
770 else if (ptr[0] == '0' && (ptr[1] == 'o' || ptr[1] == 'O'))
771 {
772 firstdigit = ptr += 2;
773
774 for (;;)
775 {
776 if (*ptr >= '0' && *ptr <= '7')
777 {
778 if (unlikely(tmp > -(PG_INT64_MIN / 8)))
779 goto out_of_range;
780
781 tmp = tmp * 8 + (*ptr++ - '0');
782 }
783 else if (*ptr == '_')
784 {
785 /* underscore must be followed by more digits */
786 ptr++;
787 if (*ptr == '\0' || *ptr < '0' || *ptr > '7')
788 goto invalid_syntax;
789 }
790 else
791 break;
792 }
793 }
794 else if (ptr[0] == '0' && (ptr[1] == 'b' || ptr[1] == 'B'))
795 {
796 firstdigit = ptr += 2;
797
798 for (;;)
799 {
800 if (*ptr >= '0' && *ptr <= '1')
801 {
802 if (unlikely(tmp > -(PG_INT64_MIN / 2)))
803 goto out_of_range;
804
805 tmp = tmp * 2 + (*ptr++ - '0');
806 }
807 else if (*ptr == '_')
808 {
809 /* underscore must be followed by more digits */
810 ptr++;
811 if (*ptr == '\0' || *ptr < '0' || *ptr > '1')
812 goto invalid_syntax;
813 }
814 else
815 break;
816 }
817 }
818 else
819 {
820 firstdigit = ptr;
821
822 for (;;)
823 {
824 if (*ptr >= '0' && *ptr <= '9')
825 {
826 if (unlikely(tmp > -(PG_INT64_MIN / 10)))
827 goto out_of_range;
828
829 tmp = tmp * 10 + (*ptr++ - '0');
830 }
831 else if (*ptr == '_')
832 {
833 /* underscore may not be first */
834 if (unlikely(ptr == firstdigit))
835 goto invalid_syntax;
836 /* and it must be followed by more digits */
837 ptr++;
838 if (*ptr == '\0' || !isdigit((unsigned char) *ptr))
839 goto invalid_syntax;
840 }
841 else
842 break;
843 }
844 }
845
846 /* require at least one digit */
847 if (unlikely(ptr == firstdigit))
848 goto invalid_syntax;
849
850 /* allow trailing whitespace, but not other trailing chars */
851 while (isspace((unsigned char) *ptr))
852 ptr++;
853
854 if (unlikely(*ptr != '\0'))
855 goto invalid_syntax;
856
857 if (neg)
858 {
859 if (unlikely(pg_neg_u64_overflow(tmp, &result)))
860 goto out_of_range;
861 return result;
862 }
863
864 if (tmp > PG_INT64_MAX)
865 goto out_of_range;
866
867 return (int64) tmp;
868
869out_of_range:
870 ereturn(escontext, 0,
871 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
872 errmsg("value \"%s\" is out of range for type %s",
873 s, "bigint")));
874
875invalid_syntax:
876 ereturn(escontext, 0,
877 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
878 errmsg("invalid input syntax for type %s: \"%s\"",
879 "bigint", s)));
880}
881
882/*
883 * Convert input string to an unsigned 32 bit integer.
884 *
885 * Allows any number of leading or trailing whitespace characters.
886 *
887 * If endloc isn't NULL, store a pointer to the rest of the string there,
888 * so that caller can parse the rest. Otherwise, it's an error if anything
889 * but whitespace follows.
890 *
891 * typname is what is reported in error messages.
892 *
893 * If escontext points to an ErrorSaveContext node, that is filled instead
894 * of throwing an error; the caller must check SOFT_ERROR_OCCURRED()
895 * to detect errors.
896 */
897uint32
898uint32in_subr(const char *s, char **endloc,
899 const char *typname, Node *escontext)
900{
901 uint32 result;
902 unsigned long cvt;
903 char *endptr;
904
905 errno = 0;
906 cvt = strtoul(s, &endptr, 0);
907
908 /*
909 * strtoul() normally only sets ERANGE. On some systems it may also set
910 * EINVAL, which simply means it couldn't parse the input string. Be sure
911 * to report that the same way as the standard error indication (that
912 * endptr == s).
913 */
914 if ((errno && errno != ERANGE) || endptr == s)
915 ereturn(escontext, 0,
916 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
917 errmsg("invalid input syntax for type %s: \"%s\"",
918 typname, s)));
919
920 if (errno == ERANGE)
921 ereturn(escontext, 0,
922 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
923 errmsg("value \"%s\" is out of range for type %s",
924 s, typname)));
925
926 if (endloc)
927 {
928 /* caller wants to deal with rest of string */
929 *endloc = endptr;
930 }
931 else
932 {
933 /* allow only whitespace after number */
934 while (*endptr && isspace((unsigned char) *endptr))
935 endptr++;
936 if (*endptr)
937 ereturn(escontext, 0,
938 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
939 errmsg("invalid input syntax for type %s: \"%s\"",
940 typname, s)));
941 }
942
943 result = (uint32) cvt;
944
945 /*
946 * Cope with possibility that unsigned long is wider than uint32, in which
947 * case strtoul will not raise an error for some values that are out of
948 * the range of uint32.
949 *
950 * For backwards compatibility, we want to accept inputs that are given
951 * with a minus sign, so allow the input value if it matches after either
952 * signed or unsigned extension to long.
953 *
954 * To ensure consistent results on 32-bit and 64-bit platforms, make sure
955 * the error message is the same as if strtoul() had returned ERANGE.
956 */
957#if PG_UINT32_MAX != ULONG_MAX
958 if (cvt != (unsigned long) result &&
959 cvt != (unsigned long) ((int) result))
960 ereturn(escontext, 0,
961 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
962 errmsg("value \"%s\" is out of range for type %s",
963 s, typname)));
964#endif
965
966 return result;
967}
968
969/*
970 * Convert input string to an unsigned 64 bit integer.
971 *
972 * Allows any number of leading or trailing whitespace characters.
973 *
974 * If endloc isn't NULL, store a pointer to the rest of the string there,
975 * so that caller can parse the rest. Otherwise, it's an error if anything
976 * but whitespace follows.
977 *
978 * typname is what is reported in error messages.
979 *
980 * If escontext points to an ErrorSaveContext node, that is filled instead
981 * of throwing an error; the caller must check SOFT_ERROR_OCCURRED()
982 * to detect errors.
983 */
984uint64
985uint64in_subr(const char *s, char **endloc,
986 const char *typname, Node *escontext)
987{
988 uint64 result;
989 char *endptr;
990
991 errno = 0;
992 result = strtou64(s, &endptr, 0);
993
994 /*
995 * strtoul[l] normally only sets ERANGE. On some systems it may also set
996 * EINVAL, which simply means it couldn't parse the input string. Be sure
997 * to report that the same way as the standard error indication (that
998 * endptr == s).
999 */
1000 if ((errno && errno != ERANGE) || endptr == s)
1001 ereturn(escontext, 0,
1002 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1003 errmsg("invalid input syntax for type %s: \"%s\"",
1004 typname, s)));
1005
1006 if (errno == ERANGE)
1007 ereturn(escontext, 0,
1008 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1009 errmsg("value \"%s\" is out of range for type %s",
1010 s, typname)));
1011
1012 if (endloc)
1013 {
1014 /* caller wants to deal with rest of string */
1015 *endloc = endptr;
1016 }
1017 else
1018 {
1019 /* allow only whitespace after number */
1020 while (*endptr && isspace((unsigned char) *endptr))
1021 endptr++;
1022 if (*endptr)
1023 ereturn(escontext, 0,
1024 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1025 errmsg("invalid input syntax for type %s: \"%s\"",
1026 typname, s)));
1027 }
1028
1029 return result;
1030}
1031
1032/*
1033 * pg_itoa: converts a signed 16-bit integer to its string representation
1034 * and returns strlen(a).
1035 *
1036 * Caller must ensure that 'a' points to enough memory to hold the result
1037 * (at least 7 bytes, counting a leading sign and trailing NUL).
1038 *
1039 * It doesn't seem worth implementing this separately.
1040 */
1041int
1043{
1044 return pg_ltoa((int32) i, a);
1045}
1046
1047/*
1048 * pg_ultoa_n: converts an unsigned 32-bit integer to its string representation,
1049 * not NUL-terminated, and returns the length of that string representation
1050 *
1051 * Caller must ensure that 'a' points to enough memory to hold the result (at
1052 * least 10 bytes)
1053 */
1054int
1056{
1057 int olength,
1058 i = 0;
1059
1060 /* Degenerate case */
1061 if (value == 0)
1062 {
1063 *a = '0';
1064 return 1;
1065 }
1066
1067 olength = decimalLength32(value);
1068
1069 /* Compute the result string. */
1070 while (value >= 10000)
1071 {
1072 const uint32 c = value - 10000 * (value / 10000);
1073 const uint32 c0 = (c % 100) << 1;
1074 const uint32 c1 = (c / 100) << 1;
1075
1076 char *pos = a + olength - i;
1077
1078 value /= 10000;
1079
1080 memcpy(pos - 2, DIGIT_TABLE + c0, 2);
1081 memcpy(pos - 4, DIGIT_TABLE + c1, 2);
1082 i += 4;
1083 }
1084 if (value >= 100)
1085 {
1086 const uint32 c = (value % 100) << 1;
1087
1088 char *pos = a + olength - i;
1089
1090 value /= 100;
1091
1092 memcpy(pos - 2, DIGIT_TABLE + c, 2);
1093 i += 2;
1094 }
1095 if (value >= 10)
1096 {
1097 const uint32 c = value << 1;
1098
1099 char *pos = a + olength - i;
1100
1101 memcpy(pos - 2, DIGIT_TABLE + c, 2);
1102 }
1103 else
1104 {
1105 *a = (char) ('0' + value);
1106 }
1107
1108 return olength;
1109}
1110
1111/*
1112 * pg_ltoa: converts a signed 32-bit integer to its string representation and
1113 * returns strlen(a).
1114 *
1115 * It is the caller's responsibility to ensure that a is at least 12 bytes long,
1116 * which is enough room to hold a minus sign, a maximally long int32, and the
1117 * above terminating NUL.
1118 */
1119int
1121{
1122 uint32 uvalue = (uint32) value;
1123 int len = 0;
1124
1125 if (value < 0)
1126 {
1127 uvalue = (uint32) 0 - uvalue;
1128 a[len++] = '-';
1129 }
1130 len += pg_ultoa_n(uvalue, a + len);
1131 a[len] = '\0';
1132 return len;
1133}
1134
1135/*
1136 * Get the decimal representation, not NUL-terminated, and return the length of
1137 * same. Caller must ensure that a points to at least MAXINT8LEN bytes.
1138 */
1139int
1141{
1142 int olength,
1143 i = 0;
1144 uint32 value2;
1145
1146 /* Degenerate case */
1147 if (value == 0)
1148 {
1149 *a = '0';
1150 return 1;
1151 }
1152
1153 olength = decimalLength64(value);
1154
1155 /* Compute the result string. */
1156 while (value >= 100000000)
1157 {
1158 const uint64 q = value / 100000000;
1159 uint32 value3 = (uint32) (value - 100000000 * q);
1160
1161 const uint32 c = value3 % 10000;
1162 const uint32 d = value3 / 10000;
1163 const uint32 c0 = (c % 100) << 1;
1164 const uint32 c1 = (c / 100) << 1;
1165 const uint32 d0 = (d % 100) << 1;
1166 const uint32 d1 = (d / 100) << 1;
1167
1168 char *pos = a + olength - i;
1169
1170 value = q;
1171
1172 memcpy(pos - 2, DIGIT_TABLE + c0, 2);
1173 memcpy(pos - 4, DIGIT_TABLE + c1, 2);
1174 memcpy(pos - 6, DIGIT_TABLE + d0, 2);
1175 memcpy(pos - 8, DIGIT_TABLE + d1, 2);
1176 i += 8;
1177 }
1178
1179 /* Switch to 32-bit for speed */
1180 value2 = (uint32) value;
1181
1182 if (value2 >= 10000)
1183 {
1184 const uint32 c = value2 - 10000 * (value2 / 10000);
1185 const uint32 c0 = (c % 100) << 1;
1186 const uint32 c1 = (c / 100) << 1;
1187
1188 char *pos = a + olength - i;
1189
1190 value2 /= 10000;
1191
1192 memcpy(pos - 2, DIGIT_TABLE + c0, 2);
1193 memcpy(pos - 4, DIGIT_TABLE + c1, 2);
1194 i += 4;
1195 }
1196 if (value2 >= 100)
1197 {
1198 const uint32 c = (value2 % 100) << 1;
1199 char *pos = a + olength - i;
1200
1201 value2 /= 100;
1202
1203 memcpy(pos - 2, DIGIT_TABLE + c, 2);
1204 i += 2;
1205 }
1206 if (value2 >= 10)
1207 {
1208 const uint32 c = value2 << 1;
1209 char *pos = a + olength - i;
1210
1211 memcpy(pos - 2, DIGIT_TABLE + c, 2);
1212 }
1213 else
1214 *a = (char) ('0' + value2);
1215
1216 return olength;
1217}
1218
1219/*
1220 * pg_lltoa: converts a signed 64-bit integer to its string representation and
1221 * returns strlen(a).
1222 *
1223 * Caller must ensure that 'a' points to enough memory to hold the result
1224 * (at least MAXINT8LEN + 1 bytes, counting a leading sign and trailing NUL).
1225 */
1226int
1228{
1229 uint64 uvalue = value;
1230 int len = 0;
1231
1232 if (value < 0)
1233 {
1234 uvalue = (uint64) 0 - uvalue;
1235 a[len++] = '-';
1236 }
1237
1238 len += pg_ulltoa_n(uvalue, a + len);
1239 a[len] = '\0';
1240 return len;
1241}
1242
1243
1244/*
1245 * pg_ultostr_zeropad
1246 * Converts 'value' into a decimal string representation stored at 'str'.
1247 * 'minwidth' specifies the minimum width of the result; any extra space
1248 * is filled up by prefixing the number with zeros.
1249 *
1250 * Returns the ending address of the string result (the last character written
1251 * plus 1). Note that no NUL terminator is written.
1252 *
1253 * The intended use-case for this function is to build strings that contain
1254 * multiple individual numbers, for example:
1255 *
1256 * str = pg_ultostr_zeropad(str, hours, 2);
1257 * *str++ = ':';
1258 * str = pg_ultostr_zeropad(str, mins, 2);
1259 * *str++ = ':';
1260 * str = pg_ultostr_zeropad(str, secs, 2);
1261 * *str = '\0';
1262 *
1263 * Note: Caller must ensure that 'str' points to enough memory to hold the
1264 * result.
1265 */
1266char *
1268{
1269 int len;
1270
1271 Assert(minwidth > 0);
1272
1273 if (value < 100 && minwidth == 2) /* Short cut for common case */
1274 {
1275 memcpy(str, DIGIT_TABLE + value * 2, 2);
1276 return str + 2;
1277 }
1278
1279 len = pg_ultoa_n(value, str);
1280 if (len >= minwidth)
1281 return str + len;
1282
1283 memmove(str + minwidth - len, str, len);
1284 memset(str, '0', minwidth - len);
1285 return str + minwidth;
1286}
1287
1288/*
1289 * pg_ultostr
1290 * Converts 'value' into a decimal string representation stored at 'str'.
1291 *
1292 * Returns the ending address of the string result (the last character written
1293 * plus 1). Note that no NUL terminator is written.
1294 *
1295 * The intended use-case for this function is to build strings that contain
1296 * multiple individual numbers, for example:
1297 *
1298 * str = pg_ultostr(str, a);
1299 * *str++ = ' ';
1300 * str = pg_ultostr(str, b);
1301 * *str = '\0';
1302 *
1303 * Note: Caller must ensure that 'str' points to enough memory to hold the
1304 * result.
1305 */
1306char *
1308{
1309 int len = pg_ultoa_n(value, str);
1310
1311 return str + len;
1312}
#define PG_INT32_MAX
Definition: c.h:546
#define likely(x)
Definition: c.h:332
#define Assert(condition)
Definition: c.h:815
int64_t int64
Definition: c.h:485
int16_t int16
Definition: c.h:483
int8_t int8
Definition: c.h:482
#define PG_INT16_MIN
Definition: c.h:542
int32_t int32
Definition: c.h:484
#define PG_INT64_MAX
Definition: c.h:549
#define PG_INT64_MIN
Definition: c.h:548
uint64_t uint64
Definition: c.h:489
uint16_t uint16
Definition: c.h:487
#define unlikely(x)
Definition: c.h:333
uint32_t uint32
Definition: c.h:488
#define PG_INT32_MIN
Definition: c.h:545
#define UINT64CONST(x)
Definition: c.h:503
#define PG_INT16_MAX
Definition: c.h:543
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ereturn(context, dummy_value,...)
Definition: elog.h:277
const char * str
static struct @162 value
static bool pg_neg_u32_overflow(uint32 a, int32 *result)
Definition: int.h:493
static bool pg_neg_u16_overflow(uint16 a, int16 *result)
Definition: int.h:420
static bool pg_neg_u64_overflow(uint64 a, int64 *result)
Definition: int.h:576
int a
Definition: isn.c:68
int i
Definition: isn.c:72
int64 pg_strtoint64_safe(const char *s, Node *escontext)
Definition: numutils.c:650
uint64 uint64in_subr(const char *s, char **endloc, const char *typname, Node *escontext)
Definition: numutils.c:985
int64 pg_strtoint64(const char *s)
Definition: numutils.c:644
int pg_ltoa(int32 value, char *a)
Definition: numutils.c:1120
char * pg_ultostr_zeropad(char *str, uint32 value, int32 minwidth)
Definition: numutils.c:1267
int32 pg_strtoint32_safe(const char *s, Node *escontext)
Definition: numutils.c:389
int pg_ulltoa_n(uint64 value, char *a)
Definition: numutils.c:1140
int16 pg_strtoint16(const char *s)
Definition: numutils.c:122
static const char DIGIT_TABLE[200]
Definition: numutils.c:29
static int decimalLength32(const uint32 v)
Definition: numutils.c:45
uint32 uint32in_subr(const char *s, char **endloc, const char *typname, Node *escontext)
Definition: numutils.c:898
int pg_lltoa(int64 value, char *a)
Definition: numutils.c:1227
char * pg_ultostr(char *str, uint32 value)
Definition: numutils.c:1307
static int decimalLength64(const uint64 v)
Definition: numutils.c:64
int pg_itoa(int16 i, char *a)
Definition: numutils.c:1042
int32 pg_strtoint32(const char *s)
Definition: numutils.c:383
int16 pg_strtoint16_safe(const char *s, Node *escontext)
Definition: numutils.c:128
static const int8 hexlookup[128]
Definition: numutils.c:88
int pg_ultoa_n(uint32 value, char *a)
Definition: numutils.c:1055
static int pg_leftmost_one_pos32(uint32 word)
Definition: pg_bitutils.h:41
static int pg_leftmost_one_pos64(uint64 word)
Definition: pg_bitutils.h:72
const void size_t len
NameData typname
Definition: pg_type.h:41
char * c
Definition: nodes.h:129