LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - numutils.c (source / functions) Coverage Total Hit UNC LBC UIC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 91.3 % 380 347 29 2 2 11 89 194 53 20 260 2 32
Current Date: 2023-04-08 17:13:01 Functions: 88.2 % 17 15 2 8 5 2 2 12 1
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (60,120] days: 85.4 % 185 158 27 158 1
Legend: Lines: hit not hit (120,180] days: 93.9 % 33 31 2 31 2
(180,240] days: 100.0 % 3 3 3
(240..) days: 97.5 % 159 155 2 2 11 89 2 53 17 111
Function coverage date bins:
(60,120] days: 100.0 % 2 2 2
(120,180] days: 100.0 % 3 3 3
(240..) days: 58.8 % 17 10 2 8 2 2 3

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * numutils.c
                                  4                 :  *    utility functions for I/O of built-in numeric types.
                                  5                 :  *
                                  6                 :  * Portions Copyright (c) 1996-2023, 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 "utils/builtins.h"
                                 23                 : #include "port/pg_bitutils.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                 :  */
                                 29                 : static 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                 :  */
                                 44                 : static inline int
 1163 rhodiumtoad                45 CBC     7125011 : decimalLength32(const uint32 v)
                                 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         7125011 :     t = (pg_leftmost_one_pos32(v) + 1) * 1233 / 4096;
                                 60         7125011 :     return t + (v >= PowersOfTen[t]);
                                 61                 : }
                                 62                 : 
                                 63                 : static inline int
                                 64          269388 : decimalLength64(const uint64 v)
                                 65                 : {
                                 66                 :     int         t;
                                 67                 :     static const uint64 PowersOfTen[] = {
                                 68                 :         UINT64CONST(1), UINT64CONST(10),
                                 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          269388 :     t = (pg_leftmost_one_pos64(v) + 1) * 1233 / 4096;
                                 85          269388 :     return t + (v >= PowersOfTen[t]);
                                 86                 : }
                                 87                 : 
                                 88                 : static 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.
                                101                 :  *
                                102                 :  * Allows any number of leading or trailing whitespace characters.
                                103                 :  *
                                104                 :  * pg_strtoint16() will throw ereport() upon bad input format or overflow;
                                105                 :  * while pg_strtoint16_safe() instead returns such complaints in *escontext,
                                106                 :  * if it's an ErrorSaveContext.
                                107                 : *
                                108                 :  * NB: Accumulate input as an unsigned number, to deal with two's complement
                                109                 :  * representation of the most negative number, which can't be represented as a
                                110                 :  * signed positive number.
                                111                 :  */
                                112                 : int16
 1722 andres                    113 UIC           0 : pg_strtoint16(const char *s)
                                114                 : {
  121 tgl                       115 UNC           0 :     return pg_strtoint16_safe(s, NULL);
                                116                 : }
                                117                 : 
                                118                 : int16
  121 tgl                       119 GNC     2839236 : pg_strtoint16_safe(const char *s, Node *escontext)
                                120                 : {
 1722 andres                    121 GIC     2839236 :     const char *ptr = s;
                                122                 :     const char *firstdigit;
  126 drowley                   123 GNC     2839236 :     uint16      tmp = 0;
 1722 andres                    124 GIC     2839236 :     bool        neg = false;
                                125                 : 
                                126                 :     /* skip leading spaces */
                                127         2839266 :     while (likely(*ptr) && isspace((unsigned char) *ptr))
                                128              30 :         ptr++;
                                129                 : 
                                130                 :     /* handle sign */
                                131         2839236 :     if (*ptr == '-')
                                132                 :     {
                                133           92468 :         ptr++;
 1722 andres                    134 GBC       92468 :         neg = true;
                                135                 :     }
                                136         2746768 :     else if (*ptr == '+')
 1722 andres                    137 UIC           0 :         ptr++;
                                138                 : 
                                139                 :     /* process digits */
  116 peter                     140 GNC     2839236 :     if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
 1722 andres                    141 ECB             :     {
  116 peter                     142 GNC          21 :         firstdigit = ptr += 2;
                                143                 : 
   64 dean.a.rasheed            144              90 :         while (*ptr)
                                145                 :         {
                                146              69 :             if (isxdigit((unsigned char) *ptr))
                                147                 :             {
                                148              66 :                 if (unlikely(tmp > -(PG_INT16_MIN / 16)))
   64 dean.a.rasheed            149 UNC           0 :                     goto out_of_range;
                                150                 : 
   64 dean.a.rasheed            151 GNC          66 :                 tmp = tmp * 16 + hexlookup[(unsigned char) *ptr++];
                                152                 :             }
                                153               3 :             else if (*ptr == '_')
                                154                 :             {
                                155                 :                 /* underscore must be followed by more digits */
                                156               3 :                 ptr++;
                                157               3 :                 if (*ptr == '\0' || !isxdigit((unsigned char) *ptr))
   64 dean.a.rasheed            158 UNC           0 :                     goto invalid_syntax;
                                159                 :             }
                                160                 :             else
                                161               0 :                 break;
                                162                 :         }
                                163                 :     }
  116 peter                     164 GNC     2839215 :     else if (ptr[0] == '0' && (ptr[1] == 'o' || ptr[1] == 'O'))
                                165                 :     {
                                166              21 :         firstdigit = ptr += 2;
                                167                 : 
   64 dean.a.rasheed            168             111 :         while (*ptr)
                                169                 :         {
                                170              90 :             if (*ptr >= '0' && *ptr <= '7')
                                171                 :             {
                                172              87 :                 if (unlikely(tmp > -(PG_INT16_MIN / 8)))
   64 dean.a.rasheed            173 UNC           0 :                     goto out_of_range;
                                174                 : 
   64 dean.a.rasheed            175 GNC          87 :                 tmp = tmp * 8 + (*ptr++ - '0');
                                176                 :             }
                                177               3 :             else if (*ptr == '_')
                                178                 :             {
                                179                 :                 /* underscore must be followed by more digits */
                                180               3 :                 ptr++;
                                181               3 :                 if (*ptr == '\0' || *ptr < '0' || *ptr > '7')
   64 dean.a.rasheed            182 UNC           0 :                     goto invalid_syntax;
                                183                 :             }
                                184                 :             else
                                185               0 :                 break;
                                186                 :         }
                                187                 :     }
  116 peter                     188 GNC     2839194 :     else if (ptr[0] == '0' && (ptr[1] == 'b' || ptr[1] == 'B'))
                                189                 :     {
                                190              21 :         firstdigit = ptr += 2;
                                191                 : 
   64 dean.a.rasheed            192             252 :         while (*ptr)
                                193                 :         {
                                194             231 :             if (*ptr >= '0' && *ptr <= '1')
                                195                 :             {
                                196             225 :                 if (unlikely(tmp > -(PG_INT16_MIN / 2)))
   64 dean.a.rasheed            197 UNC           0 :                     goto out_of_range;
                                198                 : 
   64 dean.a.rasheed            199 GNC         225 :                 tmp = tmp * 2 + (*ptr++ - '0');
                                200                 :             }
                                201               6 :             else if (*ptr == '_')
                                202                 :             {
                                203                 :                 /* underscore must be followed by more digits */
                                204               6 :                 ptr++;
                                205               6 :                 if (*ptr == '\0' || *ptr < '0' || *ptr > '1')
   64 dean.a.rasheed            206 UNC           0 :                     goto invalid_syntax;
                                207                 :             }
                                208                 :             else
                                209               0 :                 break;
                                210                 :         }
                                211                 :     }
                                212                 :     else
                                213                 :     {
  116 peter                     214 GNC     2839173 :         firstdigit = ptr;
                                215                 : 
   64 dean.a.rasheed            216         5755048 :         while (*ptr)
                                217                 :         {
                                218         2915921 :             if (isdigit((unsigned char) *ptr))
                                219                 :             {
                                220         2915875 :                 if (unlikely(tmp > -(PG_INT16_MIN / 10)))
                                221               9 :                     goto out_of_range;
                                222                 : 
                                223         2915866 :                 tmp = tmp * 10 + (*ptr++ - '0');
                                224                 :             }
                                225              46 :             else if (*ptr == '_')
                                226                 :             {
                                227                 :                 /* underscore may not be first */
                                228              18 :                 if (unlikely(ptr == firstdigit))
                                229               3 :                     goto invalid_syntax;
                                230                 :                 /* and it must be followed by more digits */
                                231              15 :                 ptr++;
                                232              15 :                 if (*ptr == '\0' || !isdigit((unsigned char) *ptr))
                                233               6 :                     goto invalid_syntax;
                                234                 :             }
                                235                 :             else
                                236              28 :                 break;
                                237                 :         }
                                238                 :     }
                                239                 : 
                                240                 :     /* require at least one digit */
  116 peter                     241         2839218 :     if (unlikely(ptr == firstdigit))
                                242              27 :         goto invalid_syntax;
 1722 andres                    243 ECB             : 
                                244                 :     /* allow trailing whitespace, but not other trailing chars */
 1722 andres                    245 CBC     2839209 :     while (*ptr != '\0' && isspace((unsigned char) *ptr))
                                246              18 :         ptr++;
                                247                 : 
                                248         2839191 :     if (unlikely(*ptr != '\0'))
 1722 andres                    249 GBC          10 :         goto invalid_syntax;
                                250                 : 
  126 drowley                   251 GNC     2839181 :     if (neg)
 1722 andres                    252 ECB             :     {
                                253                 :         /* check the negative equivalent will fit without overflowing */
  126 drowley                   254 GNC       92465 :         if (tmp > (uint16) (-(PG_INT16_MIN + 1)) + 1)
 1722 andres                    255 GIC           9 :             goto out_of_range;
  126 drowley                   256 GNC       92456 :         return -((int16) tmp);
                                257                 :     }
 1722 andres                    258 ECB             : 
  126 drowley                   259 GNC     2746716 :     if (tmp > PG_INT16_MAX)
                                260               9 :         goto out_of_range;
                                261                 : 
                                262         2746707 :     return (int16) tmp;
 1722 andres                    263 ECB             : 
 1722 andres                    264 GBC          27 : out_of_range:
  121 tgl                       265 GNC          27 :     ereturn(escontext, 0,
 1722 andres                    266 ECB             :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                267                 :              errmsg("value \"%s\" is out of range for type %s",
                                268                 :                     s, "smallint")));
                                269                 : 
 1722 andres                    270 GIC          46 : invalid_syntax:
  121 tgl                       271 GNC          46 :     ereturn(escontext, 0,
 1722 andres                    272 ECB             :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 1722 andres                    273 EUB             :              errmsg("invalid input syntax for type %s: \"%s\"",
                                274                 :                     "smallint", s)));
                                275                 : }
                                276                 : 
 1722 andres                    277 ECB             : /*
                                278                 :  * Convert input string to a signed 32 bit integer.
                                279                 :  *
                                280                 :  * Allows any number of leading or trailing whitespace characters.
                                281                 :  *
                                282                 :  * pg_strtoint32() will throw ereport() upon bad input format or overflow;
                                283                 :  * while pg_strtoint32_safe() instead returns such complaints in *escontext,
                                284                 :  * if it's an ErrorSaveContext.
                                285                 :  *
                                286                 :  * NB: Accumulate input as an unsigned number, to deal with two's complement
                                287                 :  * representation of the most negative number, which can't be represented as a
                                288                 :  * signed positive number.
 1722 andres                    289 EUB             :  */
                                290                 : int32
 1722 andres                    291 CBC        5811 : pg_strtoint32(const char *s)
                                292                 : {
  121 tgl                       293 GNC        5811 :     return pg_strtoint32_safe(s, NULL);
                                294                 : }
                                295                 : 
                                296                 : int32
                                297         3790902 : pg_strtoint32_safe(const char *s, Node *escontext)
                                298                 : {
 1722 andres                    299 CBC     3790902 :     const char *ptr = s;
                                300                 :     const char *firstdigit;
  126 drowley                   301 GNC     3790902 :     uint32      tmp = 0;
 1722 andres                    302 GIC     3790902 :     bool        neg = false;
 1722 andres                    303 ECB             : 
                                304                 :     /* skip leading spaces */
 1722 andres                    305 GBC     3790971 :     while (likely(*ptr) && isspace((unsigned char) *ptr))
 1722 andres                    306 GIC          69 :         ptr++;
                                307                 : 
 1722 andres                    308 EUB             :     /* handle sign */
 1722 andres                    309 GIC     3790902 :     if (*ptr == '-')
                                310                 :     {
 1722 andres                    311 CBC      162292 :         ptr++;
 1722 andres                    312 GIC      162292 :         neg = true;
 1722 andres                    313 ECB             :     }
 1722 andres                    314 GIC     3628610 :     else if (*ptr == '+')
 1722 andres                    315 LBC           0 :         ptr++;
                                316                 : 
                                317                 :     /* process digits */
  116 peter                     318 GNC     3790902 :     if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
                                319                 :     {
                                320            1566 :         firstdigit = ptr += 2;
                                321                 : 
   64 dean.a.rasheed            322            7986 :         while (*ptr)
                                323                 :         {
                                324            6432 :             if (isxdigit((unsigned char) *ptr))
                                325                 :             {
                                326            6426 :                 if (unlikely(tmp > -(PG_INT32_MIN / 16)))
                                327              12 :                     goto out_of_range;
                                328                 : 
                                329            6414 :                 tmp = tmp * 16 + hexlookup[(unsigned char) *ptr++];
                                330                 :             }
                                331               6 :             else if (*ptr == '_')
                                332                 :             {
                                333                 :                 /* underscore must be followed by more digits */
                                334               6 :                 ptr++;
                                335               6 :                 if (*ptr == '\0' || !isxdigit((unsigned char) *ptr))
   64 dean.a.rasheed            336 UNC           0 :                     goto invalid_syntax;
                                337                 :             }
                                338                 :             else
                                339               0 :                 break;
                                340                 :         }
 1722 andres                    341 EUB             :     }
  116 peter                     342 GNC     3789336 :     else if (ptr[0] == '0' && (ptr[1] == 'o' || ptr[1] == 'O'))
                                343                 :     {
                                344              51 :         firstdigit = ptr += 2;
                                345                 : 
   64 dean.a.rasheed            346             486 :         while (*ptr)
                                347                 :         {
                                348             447 :             if (*ptr >= '0' && *ptr <= '7')
                                349                 :             {
                                350             441 :                 if (unlikely(tmp > -(PG_INT32_MIN / 8)))
                                351              12 :                     goto out_of_range;
                                352                 : 
                                353             429 :                 tmp = tmp * 8 + (*ptr++ - '0');
                                354                 :             }
                                355               6 :             else if (*ptr == '_')
                                356                 :             {
                                357                 :                 /* underscore must be followed by more digits */
                                358               6 :                 ptr++;
                                359               6 :                 if (*ptr == '\0' || *ptr < '0' || *ptr > '7')
   64 dean.a.rasheed            360 UNC           0 :                     goto invalid_syntax;
                                361                 :             }
                                362                 :             else
                                363               0 :                 break;
                                364                 :         }
                                365                 :     }
  116 peter                     366 GNC     3789285 :     else if (ptr[0] == '0' && (ptr[1] == 'b' || ptr[1] == 'B'))
                                367                 :     {
                                368              52 :         firstdigit = ptr += 2;
                                369                 : 
   64 dean.a.rasheed            370            1311 :         while (*ptr)
                                371                 :         {
                                372            1272 :             if (*ptr >= '0' && *ptr <= '1')
                                373                 :             {
                                374            1260 :                 if (unlikely(tmp > -(PG_INT32_MIN / 2)))
                                375              13 :                     goto out_of_range;
                                376                 : 
                                377            1247 :                 tmp = tmp * 2 + (*ptr++ - '0');
                                378                 :             }
                                379              12 :             else if (*ptr == '_')
                                380                 :             {
                                381                 :                 /* underscore must be followed by more digits */
                                382              12 :                 ptr++;
                                383              12 :                 if (*ptr == '\0' || *ptr < '0' || *ptr > '1')
   64 dean.a.rasheed            384 UNC           0 :                     goto invalid_syntax;
                                385                 :             }
                                386                 :             else
                                387               0 :                 break;
                                388                 :         }
                                389                 :     }
                                390                 :     else
                                391                 :     {
  116 peter                     392 GNC     3789233 :         firstdigit = ptr;
                                393                 : 
   64 dean.a.rasheed            394        12517752 :         while (*ptr)
                                395                 :         {
                                396         8729164 :             if (isdigit((unsigned char) *ptr))
                                397                 :             {
                                398         8728999 :                 if (unlikely(tmp > -(PG_INT32_MIN / 10)))
                                399             549 :                     goto out_of_range;
                                400                 : 
                                401         8728450 :                 tmp = tmp * 10 + (*ptr++ - '0');
                                402                 :             }
                                403             165 :             else if (*ptr == '_')
                                404                 :             {
                                405                 :                 /* underscore may not be first */
                                406              78 :                 if (unlikely(ptr == firstdigit))
                                407               3 :                     goto invalid_syntax;
                                408                 :                 /* and it must be followed by more digits */
                                409              75 :                 ptr++;
                                410              75 :                 if (*ptr == '\0' || !isdigit((unsigned char) *ptr))
                                411               6 :                     goto invalid_syntax;
                                412                 :             }
                                413                 :             else
                                414              87 :                 break;
                                415                 :         }
                                416                 :     }
                                417                 : 
                                418                 :     /* require at least one digit */
  116 peter                     419         3790307 :     if (unlikely(ptr == firstdigit))
                                420              90 :         goto invalid_syntax;
                                421                 : 
                                422                 :     /* allow trailing whitespace, but not other trailing chars */
 1722 andres                    423 GBC     3790259 :     while (*ptr != '\0' && isspace((unsigned char) *ptr))
 1722 andres                    424 GIC          42 :         ptr++;
                                425                 : 
                                426         3790217 :     if (unlikely(*ptr != '\0'))
                                427               9 :         goto invalid_syntax;
 1722 andres                    428 ECB             : 
  126 drowley                   429 GNC     3790208 :     if (neg)
 1722 andres                    430 ECB             :     {
                                431                 :         /* check the negative equivalent will fit without overflowing */
  126 drowley                   432 GNC      162289 :         if (tmp > (uint32) (-(PG_INT32_MIN + 1)) + 1)
 1722 andres                    433 GIC           9 :             goto out_of_range;
  126 drowley                   434 GNC      162280 :         return -((int32) tmp);
 1722 andres                    435 ECB             :     }
                                436                 : 
  126 drowley                   437 GNC     3627919 :     if (tmp > PG_INT32_MAX)
                                438             107 :         goto out_of_range;
                                439                 : 
                                440         3627812 :     return (int32) tmp;
                                441                 : 
 1722 andres                    442 CBC         702 : out_of_range:
  121 tgl                       443 GNC         702 :     ereturn(escontext, 0,
                                444                 :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
 1722 andres                    445 ECB             :              errmsg("value \"%s\" is out of range for type %s",
                                446                 :                     s, "integer")));
                                447                 : 
 1722 andres                    448 CBC         108 : invalid_syntax:
  121 tgl                       449 GNC         108 :     ereturn(escontext, 0,
 1722 andres                    450 ECB             :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                451                 :              errmsg("invalid input syntax for type %s: \"%s\"",
                                452                 :                     "integer", s)));
                                453                 : }
                                454                 : 
                                455                 : /*
  419 peter                     456                 :  * Convert input string to a signed 64 bit integer.
                                457                 :  *
                                458                 :  * Allows any number of leading or trailing whitespace characters.
  121 tgl                       459                 :  *
                                460                 :  * pg_strtoint64() will throw ereport() upon bad input format or overflow;
                                461                 :  * while pg_strtoint64_safe() instead returns such complaints in *escontext,
                                462                 :  * if it's an ErrorSaveContext.
                                463                 :  *
                                464                 :  * NB: Accumulate input as an unsigned number, to deal with two's complement
                                465                 :  * representation of the most negative number, which can't be represented as a
                                466                 :  * signed positive number.
  419 peter                     467                 :  */
                                468                 : int64
  419 peter                     469 LBC           0 : pg_strtoint64(const char *s)
                                470                 : {
  121 tgl                       471 UNC           0 :     return pg_strtoint64_safe(s, NULL);
                                472                 : }
  121 tgl                       473 ECB             : 
                                474                 : int64
  121 tgl                       475 GNC       69193 : pg_strtoint64_safe(const char *s, Node *escontext)
                                476                 : {
  419 peter                     477           69193 :     const char *ptr = s;
                                478                 :     const char *firstdigit;
  126 drowley                   479           69193 :     uint64      tmp = 0;
  419 peter                     480           69193 :     bool        neg = false;
  419 peter                     481 ECB             : 
                                482                 :     /* skip leading spaces */
  419 peter                     483 GIC       69230 :     while (*ptr && isspace((unsigned char) *ptr))
                                484              37 :         ptr++;
                                485                 : 
                                486                 :     /* handle sign */
  419 peter                     487 CBC       69193 :     if (*ptr == '-')
  419 peter                     488 ECB             :     {
  419 peter                     489 GIC         721 :         ptr++;
                                490             721 :         neg = true;
                                491                 :     }
                                492           68472 :     else if (*ptr == '+')
                                493              21 :         ptr++;
                                494                 : 
                                495                 :     /* process digits */
  116 peter                     496 GNC       69193 :     if (ptr[0] == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
                                497                 :     {
                                498              42 :         firstdigit = ptr += 2;
                                499                 : 
   64 dean.a.rasheed            500             534 :         while (*ptr)
                                501                 :         {
                                502             492 :             if (isxdigit((unsigned char) *ptr))
                                503                 :             {
                                504             489 :                 if (unlikely(tmp > -(PG_INT64_MIN / 16)))
   64 dean.a.rasheed            505 UNC           0 :                     goto out_of_range;
                                506                 : 
   64 dean.a.rasheed            507 GNC         489 :                 tmp = tmp * 16 + hexlookup[(unsigned char) *ptr++];
                                508                 :             }
                                509               3 :             else if (*ptr == '_')
                                510                 :             {
                                511                 :                 /* underscore must be followed by more digits */
                                512               3 :                 ptr++;
                                513               3 :                 if (*ptr == '\0' || !isxdigit((unsigned char) *ptr))
   64 dean.a.rasheed            514 UNC           0 :                     goto invalid_syntax;
                                515                 :             }
                                516                 :             else
                                517               0 :                 break;
                                518                 :         }
                                519                 :     }
  116 peter                     520 GNC       69151 :     else if (ptr[0] == '0' && (ptr[1] == 'o' || ptr[1] == 'O'))
                                521                 :     {
                                522              42 :         firstdigit = ptr += 2;
                                523                 : 
   64 dean.a.rasheed            524             684 :         while (*ptr)
                                525                 :         {
                                526             642 :             if (*ptr >= '0' && *ptr <= '7')
                                527                 :             {
                                528             639 :                 if (unlikely(tmp > -(PG_INT64_MIN / 8)))
   64 dean.a.rasheed            529 UNC           0 :                     goto out_of_range;
                                530                 : 
   64 dean.a.rasheed            531 GNC         639 :                 tmp = tmp * 8 + (*ptr++ - '0');
                                532                 :             }
                                533               3 :             else if (*ptr == '_')
                                534                 :             {
                                535                 :                 /* underscore must be followed by more digits */
                                536               3 :                 ptr++;
                                537               3 :                 if (*ptr == '\0' || *ptr < '0' || *ptr > '7')
   64 dean.a.rasheed            538 UNC           0 :                     goto invalid_syntax;
                                539                 :             }
                                540                 :             else
                                541               0 :                 break;
                                542                 :         }
                                543                 :     }
  116 peter                     544 GNC       69109 :     else if (ptr[0] == '0' && (ptr[1] == 'b' || ptr[1] == 'B'))
                                545                 :     {
                                546              42 :         firstdigit = ptr += 2;
                                547                 : 
   64 dean.a.rasheed            548            1902 :         while (*ptr)
                                549                 :         {
                                550            1860 :             if (*ptr >= '0' && *ptr <= '1')
                                551                 :             {
                                552            1854 :                 if (unlikely(tmp > -(PG_INT64_MIN / 2)))
   64 dean.a.rasheed            553 UNC           0 :                     goto out_of_range;
                                554                 : 
   64 dean.a.rasheed            555 GNC        1854 :                 tmp = tmp * 2 + (*ptr++ - '0');
                                556                 :             }
                                557               6 :             else if (*ptr == '_')
                                558                 :             {
                                559                 :                 /* underscore must be followed by more digits */
                                560               6 :                 ptr++;
                                561               6 :                 if (*ptr == '\0' || *ptr < '0' || *ptr > '1')
   64 dean.a.rasheed            562 UNC           0 :                     goto invalid_syntax;
                                563                 :             }
                                564                 :             else
                                565               0 :                 break;
                                566                 :         }
                                567                 :     }
                                568                 :     else
                                569                 :     {
  116 peter                     570 GNC       69067 :         firstdigit = ptr;
                                571                 : 
   64 dean.a.rasheed            572          255870 :         while (*ptr)
                                573                 :         {
                                574          191641 :             if (isdigit((unsigned char) *ptr))
                                575                 :             {
                                576          186856 :                 if (unlikely(tmp > -(PG_INT64_MIN / 10)))
                                577             114 :                     goto out_of_range;
                                578                 : 
                                579          186742 :                 tmp = tmp * 10 + (*ptr++ - '0');
                                580                 :             }
                                581            4785 :             else if (*ptr == '_')
                                582                 :             {
                                583                 :                 /* underscore may not be first */
                                584              70 :                 if (unlikely(ptr == firstdigit))
                                585               3 :                     goto invalid_syntax;
                                586                 :                 /* and it must be followed by more digits */
                                587              67 :                 ptr++;
                                588              67 :                 if (*ptr == '\0' || !isdigit((unsigned char) *ptr))
                                589               6 :                     goto invalid_syntax;
                                590                 :             }
                                591                 :             else
                                592            4715 :                 break;
                                593                 :         }
                                594                 :     }
                                595                 : 
                                596                 :     /* require at least one digit */
  116 peter                     597           69070 :     if (unlikely(ptr == firstdigit))
                                598              47 :         goto invalid_syntax;
  419 peter                     599 ECB             : 
                                600                 :     /* allow trailing whitespace, but not other trailing chars */
  419 peter                     601 CBC       69056 :     while (*ptr != '\0' && isspace((unsigned char) *ptr))
  419 peter                     602 GIC          33 :         ptr++;
                                603                 : 
                                604           69023 :     if (unlikely(*ptr != '\0'))
  419 peter                     605 CBC        4677 :         goto invalid_syntax;
                                606                 : 
  126 drowley                   607 GNC       64346 :     if (neg)
                                608                 :     {
                                609                 :         /* check the negative equivalent will fit without overflowing */
                                610             497 :         if (tmp > (uint64) (-(PG_INT64_MIN + 1)) + 1)
  419 peter                     611 GIC          27 :             goto out_of_range;
  126 drowley                   612 GNC         470 :         return -((int64) tmp);
  419 peter                     613 ECB             :     }
                                614                 : 
  126 drowley                   615 GNC       63849 :     if (tmp > PG_INT64_MAX)
                                616              27 :         goto out_of_range;
                                617                 : 
                                618           63822 :     return (int64) tmp;
                                619                 : 
  419 peter                     620 CBC         168 : out_of_range:
  121 tgl                       621 GNC         168 :     ereturn(escontext, 0,
  419 peter                     622 ECB             :             (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                623                 :              errmsg("value \"%s\" is out of range for type %s",
                                624                 :                     s, "bigint")));
                                625                 : 
  419 peter                     626 GBC        4733 : invalid_syntax:
  121 tgl                       627 GNC        4733 :     ereturn(escontext, 0,
                                628                 :             (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
  419 peter                     629 ECB             :              errmsg("invalid input syntax for type %s: \"%s\"",
                                630                 :                     "bigint", s)));
                                631                 : }
                                632                 : 
                                633                 : /*
                                634                 :  * Convert input string to an unsigned 32 bit integer.
                                635                 :  *
                                636                 :  * Allows any number of leading or trailing whitespace characters.
                                637                 :  *
                                638                 :  * If endloc isn't NULL, store a pointer to the rest of the string there,
                                639                 :  * so that caller can parse the rest.  Otherwise, it's an error if anything
                                640                 :  * but whitespace follows.
                                641                 :  *
                                642                 :  * typname is what is reported in error messges.
                                643                 :  *
                                644                 :  * If escontext points to an ErrorSaveContext node, that is filled instead
                                645                 :  * of throwing an error; the caller must check SOFT_ERROR_OCCURRED()
                                646                 :  * to detect errors.
                                647                 :  */
                                648                 : uint32
  103 tgl                       649 GNC    19202698 : uint32in_subr(const char *s, char **endloc,
                                650                 :               const char *typname, Node *escontext)
                                651                 : {
                                652                 :     uint32      result;
                                653                 :     unsigned long cvt;
                                654                 :     char       *endptr;
                                655                 : 
                                656        19202698 :     errno = 0;
                                657        19202698 :     cvt = strtoul(s, &endptr, 0);
                                658                 : 
                                659                 :     /*
                                660                 :      * strtoul() normally only sets ERANGE.  On some systems it may also set
                                661                 :      * EINVAL, which simply means it couldn't parse the input string.  Be sure
                                662                 :      * to report that the same way as the standard error indication (that
                                663                 :      * endptr == s).
                                664                 :      */
                                665        19202698 :     if ((errno && errno != ERANGE) || endptr == s)
                                666              30 :         ereturn(escontext, 0,
                                667                 :                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                668                 :                  errmsg("invalid input syntax for type %s: \"%s\"",
                                669                 :                         typname, s)));
                                670                 : 
                                671        19202668 :     if (errno == ERANGE)
                                672               6 :         ereturn(escontext, 0,
                                673                 :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                674                 :                  errmsg("value \"%s\" is out of range for type %s",
                                675                 :                         s, typname)));
                                676                 : 
                                677        19202662 :     if (endloc)
                                678                 :     {
                                679                 :         /* caller wants to deal with rest of string */
                                680         1846623 :         *endloc = endptr;
                                681                 :     }
                                682                 :     else
                                683                 :     {
                                684                 :         /* allow only whitespace after number */
                                685        17356096 :         while (*endptr && isspace((unsigned char) *endptr))
                                686              57 :             endptr++;
                                687        17356039 :         if (*endptr)
                                688              18 :             ereturn(escontext, 0,
                                689                 :                     (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                690                 :                      errmsg("invalid input syntax for type %s: \"%s\"",
                                691                 :                             typname, s)));
                                692                 :     }
                                693                 : 
                                694        19202644 :     result = (uint32) cvt;
                                695                 : 
                                696                 :     /*
                                697                 :      * Cope with possibility that unsigned long is wider than uint32, in which
                                698                 :      * case strtoul will not raise an error for some values that are out of
                                699                 :      * the range of uint32.
                                700                 :      *
                                701                 :      * For backwards compatibility, we want to accept inputs that are given
                                702                 :      * with a minus sign, so allow the input value if it matches after either
                                703                 :      * signed or unsigned extension to long.
                                704                 :      *
                                705                 :      * To ensure consistent results on 32-bit and 64-bit platforms, make sure
                                706                 :      * the error message is the same as if strtoul() had returned ERANGE.
                                707                 :      */
                                708                 : #if PG_UINT32_MAX != ULONG_MAX
                                709        19202644 :     if (cvt != (unsigned long) result &&
                                710              21 :         cvt != (unsigned long) ((int) result))
                                711              15 :         ereturn(escontext, 0,
                                712                 :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                713                 :                  errmsg("value \"%s\" is out of range for type %s",
                                714                 :                         s, typname)));
                                715                 : #endif
                                716                 : 
                                717        19202629 :     return result;
                                718                 : }
                                719                 : 
                                720                 : /*
                                721                 :  * Convert input string to an unsigned 64 bit integer.
                                722                 :  *
                                723                 :  * Allows any number of leading or trailing whitespace characters.
                                724                 :  *
                                725                 :  * If endloc isn't NULL, store a pointer to the rest of the string there,
                                726                 :  * so that caller can parse the rest.  Otherwise, it's an error if anything
                                727                 :  * but whitespace follows.
                                728                 :  *
                                729                 :  * typname is what is reported in error messges.
                                730                 :  *
                                731                 :  * If escontext points to an ErrorSaveContext node, that is filled instead
                                732                 :  * of throwing an error; the caller must check SOFT_ERROR_OCCURRED()
                                733                 :  * to detect errors.
                                734                 :  */
                                735                 : uint64
                                736             433 : uint64in_subr(const char *s, char **endloc,
                                737                 :               const char *typname, Node *escontext)
                                738                 : {
                                739                 :     uint64      result;
                                740                 :     char       *endptr;
                                741                 : 
                                742             433 :     errno = 0;
                                743             433 :     result = strtou64(s, &endptr, 0);
                                744                 : 
                                745                 :     /*
                                746                 :      * strtoul[l] normally only sets ERANGE.  On some systems it may also set
                                747                 :      * EINVAL, which simply means it couldn't parse the input string.  Be sure
                                748                 :      * to report that the same way as the standard error indication (that
                                749                 :      * endptr == s).
                                750                 :      */
                                751             433 :     if ((errno && errno != ERANGE) || endptr == s)
                                752               9 :         ereturn(escontext, 0,
                                753                 :                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                754                 :                  errmsg("invalid input syntax for type %s: \"%s\"",
                                755                 :                         typname, s)));
                                756                 : 
                                757             424 :     if (errno == ERANGE)
                                758               3 :         ereturn(escontext, 0,
                                759                 :                 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
                                760                 :                  errmsg("value \"%s\" is out of range for type %s",
                                761                 :                         s, typname)));
                                762                 : 
                                763             421 :     if (endloc)
                                764                 :     {
                                765                 :         /* caller wants to deal with rest of string */
  103 tgl                       766 UNC           0 :         *endloc = endptr;
                                767                 :     }
                                768                 :     else
                                769                 :     {
                                770                 :         /* allow only whitespace after number */
  103 tgl                       771 GNC         421 :         while (*endptr && isspace((unsigned char) *endptr))
  103 tgl                       772 UNC           0 :             endptr++;
  103 tgl                       773 GNC         421 :         if (*endptr)
  103 tgl                       774 UNC           0 :             ereturn(escontext, 0,
                                775                 :                     (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                776                 :                      errmsg("invalid input syntax for type %s: \"%s\"",
                                777                 :                             typname, s)));
                                778                 :     }
                                779                 : 
  103 tgl                       780 GNC         421 :     return result;
  103 tgl                       781 ECB             : }
                                782                 : 
 9770 scrappy                   783                 : /*
                                784                 :  * pg_itoa: converts a signed 16-bit integer to its string representation
 1030 drowley                   785                 :  * and returns strlen(a).
 4524 rhaas                     786                 :  *
                                787                 :  * Caller must ensure that 'a' points to enough memory to hold the result
                                788                 :  * (at least 7 bytes, counting a leading sign and trailing NUL).
                                789                 :  *
                                790                 :  * It doesn't seem worth implementing this separately.
                                791                 :  */
                                792                 : int
 8286 tgl                       793 CBC      116946 : pg_itoa(int16 i, char *a)
 9770 scrappy                   794 ECB             : {
 1030 drowley                   795 GBC      116946 :     return pg_ltoa((int32) i, a);
                                796                 : }
                                797                 : 
 4524 rhaas                     798 EUB             : /*
                                799                 :  * pg_ultoa_n: converts an unsigned 32-bit integer to its string representation,
                                800                 :  * not NUL-terminated, and returns the length of that string representation
 4524 rhaas                     801 ECB             :  *
                                802                 :  * Caller must ensure that 'a' points to enough memory to hold the result (at
 1163 rhodiumtoad               803                 :  * least 10 bytes)
                                804                 :  */
                                805                 : int
 1163 rhodiumtoad               806 GIC     9102061 : pg_ultoa_n(uint32 value, char *a)
 4524 rhaas                     807 ECB             : {
                                808                 :     int         olength,
 1163 rhodiumtoad               809 CBC     9102061 :                 i = 0;
 4524 rhaas                     810 ECB             : 
                                811                 :     /* Degenerate case */
 1163 rhodiumtoad               812 CBC     9102061 :     if (value == 0)
                                813                 :     {
                                814         1977050 :         *a = '0';
 1163 rhodiumtoad               815 GIC     1977050 :         return 1;
                                816                 :     }
 4524 rhaas                     817 ECB             : 
 1163 rhodiumtoad               818 CBC     7125011 :     olength = decimalLength32(value);
 1163 rhodiumtoad               819 EUB             : 
                                820                 :     /* Compute the result string. */
 1163 rhodiumtoad               821 GIC     8329457 :     while (value >= 10000)
 4524 rhaas                     822 EUB             :     {
 1163 rhodiumtoad               823 GIC     1204446 :         const uint32 c = value - 10000 * (value / 10000);
                                824         1204446 :         const uint32 c0 = (c % 100) << 1;
 1163 rhodiumtoad               825 CBC     1204446 :         const uint32 c1 = (c / 100) << 1;
                                826                 : 
                                827         1204446 :         char       *pos = a + olength - i;
                                828                 : 
                                829         1204446 :         value /= 10000;
                                830                 : 
                                831         1204446 :         memcpy(pos - 2, DIGIT_TABLE + c0, 2);
 1163 rhodiumtoad               832 GIC     1204446 :         memcpy(pos - 4, DIGIT_TABLE + c1, 2);
 1163 rhodiumtoad               833 CBC     1204446 :         i += 4;
 1163 rhodiumtoad               834 ECB             :     }
 1163 rhodiumtoad               835 GIC     7125011 :     if (value >= 100)
 1163 rhodiumtoad               836 ECB             :     {
 1163 rhodiumtoad               837 GIC     3011180 :         const uint32 c = (value % 100) << 1;
 1163 rhodiumtoad               838 ECB             : 
 1163 rhodiumtoad               839 GIC     3011180 :         char       *pos = a + olength - i;
                                840                 : 
 1163 rhodiumtoad               841 CBC     3011180 :         value /= 100;
 4524 rhaas                     842 ECB             : 
 1163 rhodiumtoad               843 GBC     3011180 :         memcpy(pos - 2, DIGIT_TABLE + c, 2);
 1163 rhodiumtoad               844 GIC     3011180 :         i += 2;
                                845                 :     }
 1163 rhodiumtoad               846 GBC     7125011 :     if (value >= 10)
                                847                 :     {
 1163 rhodiumtoad               848 GIC     3467438 :         const uint32 c = value << 1;
                                849                 : 
                                850         3467438 :         char       *pos = a + olength - i;
 4523 tgl                       851 ECB             : 
 1163 rhodiumtoad               852 GIC     3467438 :         memcpy(pos - 2, DIGIT_TABLE + c, 2);
 1163 rhodiumtoad               853 ECB             :     }
                                854                 :     else
                                855                 :     {
 1163 rhodiumtoad               856 GIC     3657573 :         *a = (char) ('0' + value);
 4524 rhaas                     857 ECB             :     }
 1163 rhodiumtoad               858                 : 
 1163 rhodiumtoad               859 GIC     7125011 :     return olength;
 9770 scrappy                   860 ECB             : }
                                861                 : 
                                862                 : /*
                                863                 :  * pg_ltoa: converts a signed 32-bit integer to its string representation and
                                864                 :  * returns strlen(a).
                                865                 :  *
 1163 rhodiumtoad               866                 :  * It is the caller's responsibility to ensure that a is at least 12 bytes long,
                                867                 :  * which is enough room to hold a minus sign, a maximally long int32, and the
                                868                 :  * above terminating NUL.
 9770 scrappy                   869                 :  */
 1030 drowley                   870                 : int
 1163 rhodiumtoad               871 GIC     9035743 : pg_ltoa(int32 value, char *a)
                                872                 : {
 1163 rhodiumtoad               873 CBC     9035743 :     uint32      uvalue = (uint32) value;
 1030 drowley                   874 GIC     9035743 :     int         len = 0;
                                875                 : 
 1163 rhodiumtoad               876         9035743 :     if (value < 0)
                                877                 :     {
 1163 rhodiumtoad               878 CBC       45769 :         uvalue = (uint32) 0 - uvalue;
 1030 drowley                   879           45769 :         a[len++] = '-';
                                880                 :     }
 1030 drowley                   881 GIC     9035743 :     len += pg_ultoa_n(uvalue, a + len);
 1163 rhodiumtoad               882 CBC     9035743 :     a[len] = '\0';
 1030 drowley                   883         9035743 :     return len;
                                884                 : }
 1163 rhodiumtoad               885 ECB             : 
                                886                 : /*
                                887                 :  * Get the decimal representation, not NUL-terminated, and return the length of
                                888                 :  * same.  Caller must ensure that a points to at least MAXINT8LEN bytes.
                                889                 :  */
                                890                 : int
 1163 rhodiumtoad               891 CBC      291901 : pg_ulltoa_n(uint64 value, char *a)
 1163 rhodiumtoad               892 ECB             : {
                                893                 :     int         olength,
 1163 rhodiumtoad               894 GIC      291901 :                 i = 0;
                                895                 :     uint32      value2;
 1163 rhodiumtoad               896 ECB             : 
                                897                 :     /* Degenerate case */
 1163 rhodiumtoad               898 GIC      291901 :     if (value == 0)
 4524 rhaas                     899 ECB             :     {
 1163 rhodiumtoad               900 GIC       22513 :         *a = '0';
 1163 rhodiumtoad               901 CBC       22513 :         return 1;
 4524 rhaas                     902 ECB             :     }
                                903                 : 
 1163 rhodiumtoad               904 GIC      269388 :     olength = decimalLength64(value);
                                905                 : 
                                906                 :     /* Compute the result string. */
 1163 rhodiumtoad               907 CBC      277395 :     while (value >= 100000000)
 4524 rhaas                     908 ECB             :     {
 1163 rhodiumtoad               909 GIC        8007 :         const uint64 q = value / 100000000;
  186 drowley                   910 GNC        8007 :         uint32      value3 = (uint32) (value - 100000000 * q);
                                911                 : 
                                912            8007 :         const uint32 c = value3 % 10000;
                                913            8007 :         const uint32 d = value3 / 10000;
 1163 rhodiumtoad               914 GIC        8007 :         const uint32 c0 = (c % 100) << 1;
                                915            8007 :         const uint32 c1 = (c / 100) << 1;
                                916            8007 :         const uint32 d0 = (d % 100) << 1;
                                917            8007 :         const uint32 d1 = (d / 100) << 1;
                                918                 : 
                                919            8007 :         char       *pos = a + olength - i;
                                920                 : 
                                921            8007 :         value = q;
                                922                 : 
                                923            8007 :         memcpy(pos - 2, DIGIT_TABLE + c0, 2);
                                924            8007 :         memcpy(pos - 4, DIGIT_TABLE + c1, 2);
                                925            8007 :         memcpy(pos - 6, DIGIT_TABLE + d0, 2);
                                926            8007 :         memcpy(pos - 8, DIGIT_TABLE + d1, 2);
                                927            8007 :         i += 8;
 1163 rhodiumtoad               928 EUB             :     }
                                929                 : 
                                930                 :     /* Switch to 32-bit for speed */
 1163 rhodiumtoad               931 GIC      269388 :     value2 = (uint32) value;
                                932                 : 
                                933          269388 :     if (value2 >= 10000)
 1163 rhodiumtoad               934 ECB             :     {
 1163 rhodiumtoad               935 GIC       13146 :         const uint32 c = value2 - 10000 * (value2 / 10000);
 1163 rhodiumtoad               936 CBC       13146 :         const uint32 c0 = (c % 100) << 1;
 1163 rhodiumtoad               937 GIC       13146 :         const uint32 c1 = (c / 100) << 1;
 1163 rhodiumtoad               938 ECB             : 
 1163 rhodiumtoad               939 CBC       13146 :         char       *pos = a + olength - i;
                                940                 : 
 1163 rhodiumtoad               941 GIC       13146 :         value2 /= 10000;
 1163 rhodiumtoad               942 ECB             : 
 1163 rhodiumtoad               943 CBC       13146 :         memcpy(pos - 2, DIGIT_TABLE + c0, 2);
 1163 rhodiumtoad               944 GIC       13146 :         memcpy(pos - 4, DIGIT_TABLE + c1, 2);
                                945           13146 :         i += 4;
 1163 rhodiumtoad               946 ECB             :     }
 1163 rhodiumtoad               947 GIC      269388 :     if (value2 >= 100)
 4524 rhaas                     948 ECB             :     {
 1163 rhodiumtoad               949 CBC      107670 :         const uint32 c = (value2 % 100) << 1;
 1163 rhodiumtoad               950 GIC      107670 :         char       *pos = a + olength - i;
 4523 tgl                       951 ECB             : 
 1163 rhodiumtoad               952 CBC      107670 :         value2 /= 100;
                                953                 : 
 1163 rhodiumtoad               954 GIC      107670 :         memcpy(pos - 2, DIGIT_TABLE + c, 2);
 1163 rhodiumtoad               955 CBC      107670 :         i += 2;
                                956                 :     }
                                957          269388 :     if (value2 >= 10)
                                958                 :     {
                                959           62193 :         const uint32 c = value2 << 1;
 1163 rhodiumtoad               960 GIC       62193 :         char       *pos = a + olength - i;
 1163 rhodiumtoad               961 ECB             : 
 1163 rhodiumtoad               962 GIC       62193 :         memcpy(pos - 2, DIGIT_TABLE + c, 2);
 1163 rhodiumtoad               963 ECB             :     }
 1163 rhodiumtoad               964 EUB             :     else
 1163 rhodiumtoad               965 GIC      207195 :         *a = (char) ('0' + value2);
 1163 rhodiumtoad               966 ECB             : 
 1163 rhodiumtoad               967 GIC      269388 :     return olength;
 1163 rhodiumtoad               968 ECB             : }
                                969                 : 
                                970                 : /*
 1030 drowley                   971                 :  * pg_lltoa: converts a signed 64-bit integer to its string representation and
                                972                 :  * returns strlen(a).
 1163 rhodiumtoad               973 EUB             :  *
                                974                 :  * Caller must ensure that 'a' points to enough memory to hold the result
                                975                 :  * (at least MAXINT8LEN + 1 bytes, counting a leading sign and trailing NUL).
                                976                 :  */
                                977                 : int
 1163 rhodiumtoad               978 GIC      150974 : pg_lltoa(int64 value, char *a)
 1163 rhodiumtoad               979 ECB             : {
 1163 rhodiumtoad               980 GIC      150974 :     uint64      uvalue = value;
 1030 drowley                   981 CBC      150974 :     int         len = 0;
                                982                 : 
 1163 rhodiumtoad               983          150974 :     if (value < 0)
                                984                 :     {
                                985            1181 :         uvalue = (uint64) 0 - uvalue;
 1030 drowley                   986 GIC        1181 :         a[len++] = '-';
 1163 rhodiumtoad               987 ECB             :     }
 1030 drowley                   988 EUB             : 
 1030 drowley                   989 GIC      150974 :     len += pg_ulltoa_n(uvalue, a + len);
 1030 drowley                   990 CBC      150974 :     a[len] = '\0';
 1030 drowley                   991 GIC      150974 :     return len;
 9770 scrappy                   992 ECB             : }
                                993                 : 
                                994                 : 
 2619 tgl                       995                 : /*
 1163 rhodiumtoad               996                 :  * pg_ultostr_zeropad
 2619 tgl                       997 EUB             :  *      Converts 'value' into a decimal string representation stored at 'str'.
                                998                 :  *      'minwidth' specifies the minimum width of the result; any extra space
                                999                 :  *      is filled up by prefixing the number with zeros.
                               1000                 :  *
                               1001                 :  * Returns the ending address of the string result (the last character written
                               1002                 :  * plus 1).  Note that no NUL terminator is written.
 2619 tgl                      1003 ECB             :  *
                               1004                 :  * The intended use-case for this function is to build strings that contain
                               1005                 :  * multiple individual numbers, for example:
                               1006                 :  *
 1034 drowley                  1007                 :  *  str = pg_ultostr_zeropad(str, hours, 2);
                               1008                 :  *  *str++ = ':';
                               1009                 :  *  str = pg_ultostr_zeropad(str, mins, 2);
                               1010                 :  *  *str++ = ':';
                               1011                 :  *  str = pg_ultostr_zeropad(str, secs, 2);
 2619 tgl                      1012 EUB             :  *  *str = '\0';
                               1013                 :  *
 2619 tgl                      1014 ECB             :  * Note: Caller must ensure that 'str' points to enough memory to hold the
                               1015                 :  * result.
                               1016                 :  */
                               1017                 : char *
 1163 rhodiumtoad              1018 GIC      412262 : pg_ultostr_zeropad(char *str, uint32 value, int32 minwidth)
 2619 tgl                      1019 ECB             : {
 1163 rhodiumtoad              1020                 :     int         len;
 2619 tgl                      1021 EUB             : 
 2619 tgl                      1022 GIC      412262 :     Assert(minwidth > 0);
                               1023                 : 
 1163 rhodiumtoad              1024 GBC      412262 :     if (value < 100 && minwidth == 2)    /* Short cut for common case */
                               1025                 :     {
 1163 rhodiumtoad              1026 GIC      347598 :         memcpy(str, DIGIT_TABLE + value * 2, 2);
                               1027          347598 :         return str + 2;
                               1028                 :     }
 2619 tgl                      1029 ECB             : 
 1163 rhodiumtoad              1030 GIC       64664 :     len = pg_ultoa_n(value, str);
 1163 rhodiumtoad              1031 CBC       64664 :     if (len >= minwidth)
 1163 rhodiumtoad              1032 GIC       64325 :         return str + len;
 2619 tgl                      1033 ECB             : 
 1163 rhodiumtoad              1034 GIC         339 :     memmove(str + minwidth - len, str, len);
 1163 rhodiumtoad              1035 CBC         339 :     memset(str, '0', minwidth - len);
                               1036             339 :     return str + minwidth;
                               1037                 : }
 2619 tgl                      1038 ECB             : 
                               1039                 : /*
 1034 drowley                  1040                 :  * pg_ultostr
                               1041                 :  *      Converts 'value' into a decimal string representation stored at 'str'.
                               1042                 :  *
 2619 tgl                      1043                 :  * Returns the ending address of the string result (the last character written
                               1044                 :  * plus 1).  Note that no NUL terminator is written.
                               1045                 :  *
                               1046                 :  * The intended use-case for this function is to build strings that contain
                               1047                 :  * multiple individual numbers, for example:
                               1048                 :  *
                               1049                 :  *  str = pg_ultostr(str, a);
                               1050                 :  *  *str++ = ' ';
 1034 drowley                  1051                 :  *  str = pg_ultostr(str, b);
                               1052                 :  *  *str = '\0';
                               1053                 :  *
                               1054                 :  * Note: Caller must ensure that 'str' points to enough memory to hold the
                               1055                 :  * result.
 2619 tgl                      1056                 :  */
                               1057                 : char *
 1163 rhodiumtoad              1058 GIC        1638 : pg_ultostr(char *str, uint32 value)
                               1059                 : {
 1163 rhodiumtoad              1060 CBC        1638 :     int         len = pg_ultoa_n(value, str);
 2619 tgl                      1061 ECB             : 
 1163 rhodiumtoad              1062 GIC        1638 :     return str + len;
 2619 tgl                      1063 ECB             : }
        

Generated by: LCOV version v1.16-55-g56c0a2a