LCOV - differential code coverage report
Current view: top level - src/backend/nodes - read.c (source / functions) Coverage Total Hit UNC UBC GNC CBC DUB DCB
Current: ba12a202ce1b5581dc0ed149cf3f637d7897ad5d vs 2866d8c7dbfc9d882a7d80fef93fbbe763709932 Lines: 68.4 % 174 119 2 53 16 103 2 21
Current Date: 2026-08-27 14:31:44 +0300 Functions: 85.7 % 7 6 1 3 3 2
Baseline: lcov-20260827-baseline Branches: 57.0 % 186 106 80 106
Baseline Date: 2026-08-27 14:31:58 +0300 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(1,7] days: 88.9 % 18 16 2 16
(360..) days: 66.0 % 156 103 53 103
Function coverage date bins:
(1,7] days: 100.0 % 2 2 2
(360..) days: 80.0 % 5 4 1 1 3
Branch coverage date bins:
(360..) days: 57.0 % 186 106 80 106

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * read.c
                                  4                 :                :  *    routines to convert a string (legal ascii representation of node) back
                                  5                 :                :  *    to nodes
                                  6                 :                :  *
                                  7                 :                :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
                                  8                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                  9                 :                :  *
                                 10                 :                :  *
                                 11                 :                :  * IDENTIFICATION
                                 12                 :                :  *    src/backend/nodes/read.c
                                 13                 :                :  *
                                 14                 :                :  * HISTORY
                                 15                 :                :  *    AUTHOR            DATE            MAJOR EVENT
                                 16                 :                :  *    Andrew Yu         Nov 2, 1994     file creation
                                 17                 :                :  *
                                 18                 :                :  *-------------------------------------------------------------------------
                                 19                 :                :  */
                                 20                 :                : #include "postgres.h"
                                 21                 :                : 
                                 22                 :                : #include <ctype.h>
                                 23                 :                : 
                                 24                 :                : #include "common/string.h"
                                 25                 :                : #include "nodes/bitmapset.h"
                                 26                 :                : #include "nodes/pg_list.h"
                                 27                 :                : #include "nodes/readfuncs.h"
                                 28                 :                : #include "nodes/value.h"
                                 29                 :                : 
                                 30                 :                : 
                                 31                 :                : /*
                                 32                 :                :  * stringToNode -
                                 33                 :                :  *    builds a Node tree from its string representation (assumed valid)
                                 34                 :                :  *
                                 35                 :                :  * restore_loc_fields instructs readfuncs.c whether to restore location
                                 36                 :                :  * fields rather than set them to -1.  This is currently only supported
                                 37                 :                :  * in builds with DEBUG_NODE_TESTS_ENABLED defined.
                                 38                 :                :  */
                                 39                 :                : static void *
 2900 tgl@sss.pgh.pa.us          40                 :CBC      253713 : stringToNodeInternal(const char *str, bool restore_loc_fields)
                                 41                 :                : {
                                 42                 :                :     ReadNodeContext ctx;
                                 43                 :                : 
                                 44                 :                :     /* initialize the context  */
    3 michael@paquier.xyz        45                 :GNC      253713 :     ctx.str = str;
                                 46                 :                : #ifdef DEBUG_NODE_TESTS_ENABLED
                                 47                 :         253713 :     ctx.restore_location_fields = restore_loc_fields;
                                 48                 :                : #endif
                                 49                 :                : 
                                 50                 :                :     /* do the reading, and return */
                                 51                 :         253713 :     return nodeRead(&ctx, NULL, 0);
                                 52                 :                : }
                                 53                 :                : 
                                 54                 :                : /*
                                 55                 :                :  * Externally visible entry points
                                 56                 :                :  */
                                 57                 :                : void *
 2900 tgl@sss.pgh.pa.us          58                 :CBC      253713 : stringToNode(const char *str)
                                 59                 :                : {
                                 60                 :         253713 :     return stringToNodeInternal(str, false);
                                 61                 :                : }
                                 62                 :                : 
                                 63                 :                : #ifdef DEBUG_NODE_TESTS_ENABLED
                                 64                 :                : 
                                 65                 :                : void *
 2900 tgl@sss.pgh.pa.us          66                 :UBC           0 : stringToNodeWithLocations(const char *str)
                                 67                 :                : {
                                 68                 :              0 :     return stringToNodeInternal(str, true);
                                 69                 :                : }
                                 70                 :                : 
                                 71                 :                : #endif
                                 72                 :                : 
                                 73                 :                : 
                                 74                 :                : /*****************************************************************************
                                 75                 :                :  *
                                 76                 :                :  * the lisp token parser
                                 77                 :                :  *
                                 78                 :                :  *****************************************************************************/
                                 79                 :                : 
                                 80                 :                : /*
                                 81                 :                :  * pg_strtok --- retrieve next "token" from a string.
                                 82                 :                :  *
                                 83                 :                :  * Works kinda like strtok, except it never modifies the source string.
                                 84                 :                :  * (Instead of storing nulls into the string, the length of the token
                                 85                 :                :  * is returned to the caller.)
                                 86                 :                :  * Also, the rules about what is a token are hard-wired rather than being
                                 87                 :                :  * configured by passing a set of terminating characters.
                                 88                 :                :  *
                                 89                 :                :  * The rules for tokens are:
                                 90                 :                :  *  * Whitespace (space, tab, newline) always separates tokens.
                                 91                 :                :  *  * The characters '(', ')', '{', '}' form individual tokens even
                                 92                 :                :  *    without any whitespace around them.
                                 93                 :                :  *  * Otherwise, a token is all the characters up to the next whitespace
                                 94                 :                :  *    or occurrence of one of the four special characters.
                                 95                 :                :  *  * A backslash '\' can be used to quote whitespace or one of the four
                                 96                 :                :  *    special characters, so that it is treated as a plain token character.
                                 97                 :                :  *    Backslashes themselves must also be backslashed for consistency.
                                 98                 :                :  *    Any other character can be, but need not be, backslashed as well.
                                 99                 :                :  *  * If the resulting token is '<>' (with no backslash), it is returned
                                100                 :                :  *    as a non-NULL pointer to the token but with length == 0.  Note that
                                101                 :                :  *    there is no other way to get a zero-length token.
                                102                 :                :  *
                                103                 :                :  * Returns a pointer to the start of the next token, and the length of the
                                104                 :                :  * token (including any embedded backslashes!) in *length.  If there are
                                105                 :                :  * no more tokens, NULL and 0 are returned.
                                106                 :                :  *
                                107                 :                :  * NOTE: this routine doesn't remove backslashes; the caller must do so
                                108                 :                :  * if necessary (see "debackslash").
                                109                 :                :  *
                                110                 :                :  * NOTE: prior to release 7.0, this routine also had a special case to treat
                                111                 :                :  * a token starting with '"' as extending to the next '"'.  This code was
                                112                 :                :  * broken, however, since it would fail to cope with a string containing an
                                113                 :                :  * embedded '"'.  I have therefore removed this special case, and instead
                                114                 :                :  * introduced rules for using backslashes to quote characters.  Higher-level
                                115                 :                :  * code should add backslashes to a string constant to ensure it is treated
                                116                 :                :  * as a single token.
                                117                 :                :  */
                                118                 :                : const char *
    3 michael@paquier.xyz       119                 :GNC    89084090 : pg_strtok(ReadNodeContext *ctx, int *length)
                                120                 :                : {
                                121                 :                :     const char *local_str;      /* working pointer to string */
                                122                 :                :     const char *ret_str;        /* start of token to return */
                                123                 :                : 
                                124                 :       89084090 :     local_str = ctx->str;
                                125                 :                : 
 9722 tgl@sss.pgh.pa.us         126   [ +  +  -  +  :CBC   165281467 :     while (*local_str == ' ' || *local_str == '\n' || *local_str == '\t')
                                              -  + ]
                                127                 :       76197377 :         local_str++;
                                128                 :                : 
                                129         [ -  + ]:       89084090 :     if (*local_str == '\0')
                                130                 :                :     {
 9722 tgl@sss.pgh.pa.us         131                 :UBC           0 :         *length = 0;
    3 michael@paquier.xyz       132                 :UNC           0 :         ctx->str = local_str;
 9722 tgl@sss.pgh.pa.us         133                 :UBC           0 :         return NULL;            /* no more tokens */
                                134                 :                :     }
                                135                 :                : 
                                136                 :                :     /*
                                137                 :                :      * Now pointing at start of next token.
                                138                 :                :      */
 9722 tgl@sss.pgh.pa.us         139                 :CBC    89084090 :     ret_str = local_str;
                                140                 :                : 
                                141   [ +  +  +  + ]:       89084090 :     if (*local_str == '(' || *local_str == ')' ||
                                142   [ +  +  +  + ]:       83686266 :         *local_str == '{' || *local_str == '}')
                                143                 :                :     {
                                144                 :                :         /* special 1-character token */
                                145                 :       12637864 :         local_str++;
                                146                 :                :     }
                                147                 :                :     else
                                148                 :                :     {
                                149                 :                :         /* Normal token, possibly containing backslashes */
                                150                 :       76446226 :         while (*local_str != '\0' &&
                                151   [ +  +  +  - ]:      537772566 :                *local_str != ' ' && *local_str != '\n' &&
                                152         [ +  - ]:      466705224 :                *local_str != '\t' &&
                                153   [ +  -  +  + ]:      466705224 :                *local_str != '(' && *local_str != ')' &&
                                154   [ +  +  +  -  :     1002532235 :                *local_str != '{' && *local_str != '}')
                                              +  + ]
                                155                 :                :         {
                                156   [ +  +  +  - ]:      461350102 :             if (*local_str == '\\' && local_str[1] != '\0')
                                157                 :            880 :                 local_str += 2;
                                158                 :                :             else
                                159                 :      461349222 :                 local_str++;
                                160                 :                :         }
                                161                 :                :     }
                                162                 :                : 
                                163                 :       89084090 :     *length = local_str - ret_str;
                                164                 :                : 
                                165                 :                :     /* Recognize special case for "empty" token */
                                166   [ +  +  +  +  :       89084090 :     if (*length == 2 && ret_str[0] == '<' && ret_str[1] == '>')
                                              +  - ]
                                167                 :        1948068 :         *length = 0;
                                168                 :                : 
    3 michael@paquier.xyz       169                 :GNC    89084090 :     ctx->str = local_str;
                                170                 :                : 
 9722 tgl@sss.pgh.pa.us         171                 :CBC    89084090 :     return ret_str;
                                172                 :                : }
                                173                 :                : 
                                174                 :                : /*
                                175                 :                :  * debackslash -
                                176                 :                :  *    create a palloc'd string holding the given token.
                                177                 :                :  *    any protective backslashes in the token are removed.
                                178                 :                :  */
                                179                 :                : char *
 2900                           180                 :        2589840 : debackslash(const char *token, int length)
                                181                 :                : {
 9633 bruce@momjian.us          182                 :        2589840 :     char       *result = palloc(length + 1);
                                183                 :        2589840 :     char       *ptr = result;
                                184                 :                : 
 9722 tgl@sss.pgh.pa.us         185         [ +  + ]:       26393331 :     while (length > 0)
                                186                 :                :     {
                                187   [ +  +  +  - ]:       23803491 :         if (*token == '\\' && length > 1)
                                188                 :            880 :             token++, length--;
                                189                 :       23803491 :         *ptr++ = *token++;
                                190                 :       23803491 :         length--;
                                191                 :                :     }
                                192                 :        2589840 :     *ptr = '\0';
                                193                 :        2589840 :     return result;
                                194                 :                : }
                                195                 :                : 
                                196                 :                : #define RIGHT_PAREN (1000000 + 1)
                                197                 :                : #define LEFT_PAREN  (1000000 + 2)
                                198                 :                : #define LEFT_BRACE  (1000000 + 3)
                                199                 :                : #define OTHER_TOKEN (1000000 + 4)
                                200                 :                : 
                                201                 :                : /*
                                202                 :                :  * nodeTokenType -
                                203                 :                :  *    returns the type of the node token contained in token.
                                204                 :                :  *    It returns one of the following valid NodeTags:
                                205                 :                :  *      T_Integer, T_Float, T_Boolean, T_String, T_BitString
                                206                 :                :  *    and some of its own:
                                207                 :                :  *      RIGHT_PAREN, LEFT_PAREN, LEFT_BRACE, OTHER_TOKEN
                                208                 :                :  *
                                209                 :                :  *    Assumption: the ascii representation is legal
                                210                 :                :  */
                                211                 :                : static NodeTag
 2900                           212                 :        8412623 : nodeTokenType(const char *token, int length)
                                213                 :                : {
                                214                 :                :     NodeTag     retval;
                                215                 :                :     const char *numptr;
                                216                 :                :     int         numlen;
                                217                 :                : 
                                218                 :                :     /*
                                219                 :                :      * Check if the token is a number
                                220                 :                :      */
 9684                           221                 :        8412623 :     numptr = token;
                                222                 :        8412623 :     numlen = length;
                                223   [ +  -  -  + ]:        8412623 :     if (*numptr == '+' || *numptr == '-')
 9684 tgl@sss.pgh.pa.us         224                 :UBC           0 :         numptr++, numlen--;
 9398 tgl@sss.pgh.pa.us         225   [ +  +  +  -  :CBC     8412623 :     if ((numlen > 0 && isdigit((unsigned char) *numptr)) ||
                                              +  + ]
 7621 bruce@momjian.us          226   [ -  +  -  - ]:        2099450 :         (numlen > 1 && *numptr == '.' && isdigit((unsigned char) numptr[1])))
                                227                 :                :     {
                                228                 :                :         /*
                                229                 :                :          * Yes.  Figure out whether it is integral or float; this requires
                                230                 :                :          * both a syntax check and a range check. strtoint() can do both for
                                231                 :                :          * us. We know the token will end at a character that strtoint will
                                232                 :                :          * stop at, so we do not need to modify the string.
                                233                 :                :          */
                                234                 :                :         char       *endptr;
                                235                 :                : 
 9684 tgl@sss.pgh.pa.us         236                 :UBC           0 :         errno = 0;
 1433 peter@eisentraut.org      237                 :              0 :         (void) strtoint(numptr, &endptr, 10);
 3089 peter_e@gmx.net           238   [ #  #  #  # ]:              0 :         if (endptr != token + length || errno == ERANGE)
 9684 tgl@sss.pgh.pa.us         239                 :              0 :             return T_Float;
                                240                 :              0 :         return T_Integer;
                                241                 :                :     }
                                242                 :                : 
                                243                 :                :     /*
                                244                 :                :      * these three cases do not need length checks, since pg_strtok() will
                                245                 :                :      * always treat them as single-byte tokens
                                246                 :                :      */
10581 bruce@momjian.us          247         [ +  + ]:CBC     8412623 :     else if (*token == '(')
                                248                 :         934713 :         retval = LEFT_PAREN;
                                249         [ -  + ]:        7477910 :     else if (*token == ')')
10581 bruce@momjian.us          250                 :UBC           0 :         retval = RIGHT_PAREN;
10581 bruce@momjian.us          251         [ +  + ]:CBC     7477910 :     else if (*token == '{')
 8148 tgl@sss.pgh.pa.us         252                 :        3620020 :         retval = LEFT_BRACE;
 1683 peter@eisentraut.org      253   [ +  +  +  -  :        3857890 :     else if ((length == 4 && strncmp(token, "true", 4) == 0) ||
                                              +  + ]
                                254         [ -  + ]:         106842 :              (length == 5 && strncmp(token, "false", 5) == 0))
 1686 peter@eisentraut.org      255                 :UBC           0 :         retval = T_Boolean;
 3901 peter_e@gmx.net           256   [ +  +  +  -  :CBC     3857890 :     else if (*token == '"' && length > 1 && token[length - 1] == '"')
                                              +  - ]
 9722 tgl@sss.pgh.pa.us         257                 :        2099450 :         retval = T_String;
 1433 peter@eisentraut.org      258   [ +  -  -  + ]:        1758440 :     else if (*token == 'b' || *token == 'x')
 9431 peter_e@gmx.net           259                 :UBC           0 :         retval = T_BitString;
                                260                 :                :     else
 8148 tgl@sss.pgh.pa.us         261                 :CBC     1758440 :         retval = OTHER_TOKEN;
10222 bruce@momjian.us          262                 :        8412623 :     return retval;
                                263                 :                : }
                                264                 :                : 
                                265                 :                : /*
                                266                 :                :  * nodeRead -
                                267                 :                :  *    Slightly higher-level reader.
                                268                 :                :  *
                                269                 :                :  * This routine applies some semantic knowledge on top of the purely
                                270                 :                :  * lexical tokenizer pg_strtok().   It can read
                                271                 :                :  *  * Value token nodes (integers, floats, booleans, or strings);
                                272                 :                :  *  * General nodes (via parseNodeString() from readfuncs.c);
                                273                 :                :  *  * Lists of the above;
                                274                 :                :  *  * Lists of integers, OIDs, or TransactionIds.
                                275                 :                :  * The return value is declared void *, not Node *, to avoid having to
                                276                 :                :  * cast it explicitly in callers that assign to fields of different types.
                                277                 :                :  *
                                278                 :                :  * External callers should always pass NULL/0 for the arguments.  Internally
                                279                 :                :  * a non-NULL token may be passed when the upper recursion level has already
                                280                 :                :  * scanned the first token of a node's representation.
                                281                 :                :  *
                                282                 :                :  * We assume pg_strtok is already initialized with a string to read (hence
                                283                 :                :  * this should only be invoked from within a stringToNode operation).
                                284                 :                :  */
                                285                 :                : void *
    3 michael@paquier.xyz       286                 :GNC     8412623 : nodeRead(ReadNodeContext *ctx, const char *token, int tok_len)
                                287                 :                : {
                                288                 :                :     Node       *result;
                                289                 :                :     NodeTag     type;
                                290                 :                : 
 8148 tgl@sss.pgh.pa.us         291         [ +  + ]:CBC     8412623 :     if (token == NULL)          /* need to read a token? */
                                292                 :                :     {
    3 michael@paquier.xyz       293                 :GNC     3876992 :         token = pg_strtok(ctx, &tok_len);
                                294                 :                : 
 8148 tgl@sss.pgh.pa.us         295         [ -  + ]:CBC     3876992 :         if (token == NULL)      /* end of input */
 8148 tgl@sss.pgh.pa.us         296                 :UBC           0 :             return NULL;
                                297                 :                :     }
                                298                 :                : 
10581 bruce@momjian.us          299                 :CBC     8412623 :     type = nodeTokenType(token, tok_len);
                                300                 :                : 
 6065 peter_e@gmx.net           301   [ +  +  -  +  :        8412623 :     switch ((int) type)
                                     -  -  -  +  -  
                                                 - ]
                                302                 :                :     {
 8148 tgl@sss.pgh.pa.us         303                 :        3620020 :         case LEFT_BRACE:
    3 michael@paquier.xyz       304                 :GNC     3620020 :             result = parseNodeString(ctx);
                                305                 :        3620020 :             token = pg_strtok(ctx, &tok_len);
 9363 tgl@sss.pgh.pa.us         306   [ +  -  -  + ]:CBC     3620020 :             if (token == NULL || token[0] != '}')
 8437 tgl@sss.pgh.pa.us         307         [ #  # ]:UBC           0 :                 elog(ERROR, "did not find '}' at end of input node");
10580 bruce@momjian.us          308                 :CBC     3620020 :             break;
                                309                 :         934713 :         case LEFT_PAREN:
                                310                 :                :             {
 8148 tgl@sss.pgh.pa.us         311                 :         934713 :                 List       *l = NIL;
                                312                 :                : 
                                313                 :                :                 /*----------
                                314                 :                :                  * Could be an integer list:    (i int int ...)
                                315                 :                :                  * or an OID list:              (o int int ...)
                                316                 :                :                  * or an XID list:              (x int int ...)
                                317                 :                :                  * or a bitmapset:              (b int int ...)
                                318                 :                :                  * or a list of nodes/values:   (node node ...)
                                319                 :                :                  *----------
                                320                 :                :                  */
    3 michael@paquier.xyz       321                 :GNC      934713 :                 token = pg_strtok(ctx, &tok_len);
 8146 tgl@sss.pgh.pa.us         322         [ -  + ]:CBC      934713 :                 if (token == NULL)
 8146 tgl@sss.pgh.pa.us         323         [ #  # ]:UBC           0 :                     elog(ERROR, "unterminated List structure");
 8146 tgl@sss.pgh.pa.us         324   [ +  +  +  + ]:CBC      934713 :                 if (tok_len == 1 && token[0] == 'i')
                                325                 :                :                 {
                                326                 :                :                     /* List of integers */
                                327                 :                :                     for (;;)
                                328                 :        1047730 :                     {
                                329                 :                :                         int         val;
                                330                 :                :                         char       *endptr;
                                331                 :                : 
    3 michael@paquier.xyz       332                 :GNC     1099144 :                         token = pg_strtok(ctx, &tok_len);
 8146 tgl@sss.pgh.pa.us         333         [ -  + ]:CBC     1099144 :                         if (token == NULL)
 8146 tgl@sss.pgh.pa.us         334         [ #  # ]:UBC           0 :                             elog(ERROR, "unterminated List structure");
 8146 tgl@sss.pgh.pa.us         335         [ +  + ]:CBC     1099144 :                         if (token[0] == ')')
                                336                 :          51414 :                             break;
                                337                 :        1047730 :                         val = (int) strtol(token, &endptr, 10);
                                338         [ -  + ]:        1047730 :                         if (endptr != token + tok_len)
 8146 tgl@sss.pgh.pa.us         339         [ #  # ]:UBC           0 :                             elog(ERROR, "unrecognized integer: \"%.*s\"",
                                340                 :                :                                  tok_len, token);
 8124 neilc@samurai.com         341                 :CBC     1047730 :                         l = lappend_int(l, val);
                                342                 :                :                     }
 1383 tgl@sss.pgh.pa.us         343                 :          51414 :                     result = (Node *) l;
                                344                 :                :                 }
 8146                           345   [ +  +  +  + ]:         883299 :                 else if (tok_len == 1 && token[0] == 'o')
                                346                 :                :                 {
                                347                 :                :                     /* List of OIDs */
                                348                 :                :                     for (;;)
                                349                 :          96764 :                     {
                                350                 :                :                         Oid         val;
                                351                 :                :                         char       *endptr;
                                352                 :                : 
    3 michael@paquier.xyz       353                 :GNC      119263 :                         token = pg_strtok(ctx, &tok_len);
 8146 tgl@sss.pgh.pa.us         354         [ -  + ]:CBC      119263 :                         if (token == NULL)
 8146 tgl@sss.pgh.pa.us         355         [ #  # ]:UBC           0 :                             elog(ERROR, "unterminated List structure");
 8146 tgl@sss.pgh.pa.us         356         [ +  + ]:CBC      119263 :                         if (token[0] == ')')
                                357                 :          22499 :                             break;
                                358                 :          96764 :                         val = (Oid) strtoul(token, &endptr, 10);
                                359         [ -  + ]:          96764 :                         if (endptr != token + tok_len)
 8146 tgl@sss.pgh.pa.us         360         [ #  # ]:UBC           0 :                             elog(ERROR, "unrecognized OID: \"%.*s\"",
                                361                 :                :                                  tok_len, token);
 8124 neilc@samurai.com         362                 :CBC       96764 :                         l = lappend_oid(l, val);
                                363                 :                :                     }
 1383 tgl@sss.pgh.pa.us         364                 :          22499 :                     result = (Node *) l;
                                365                 :                :                 }
 1506 alvherre@alvh.no-ip.      366   [ +  +  -  + ]:         860800 :                 else if (tok_len == 1 && token[0] == 'x')
                                367                 :                :                 {
                                368                 :                :                     /* List of TransactionIds */
                                369                 :                :                     for (;;)
 1506 alvherre@alvh.no-ip.      370                 :UBC           0 :                     {
                                371                 :                :                         TransactionId val;
                                372                 :                :                         char       *endptr;
                                373                 :                : 
    3 michael@paquier.xyz       374                 :UNC           0 :                         token = pg_strtok(ctx, &tok_len);
 1506 alvherre@alvh.no-ip.      375         [ #  # ]:UBC           0 :                         if (token == NULL)
                                376         [ #  # ]:              0 :                             elog(ERROR, "unterminated List structure");
                                377         [ #  # ]:              0 :                         if (token[0] == ')')
                                378                 :              0 :                             break;
                                379                 :              0 :                         val = (TransactionId) strtoul(token, &endptr, 10);
                                380         [ #  # ]:              0 :                         if (endptr != token + tok_len)
                                381         [ #  # ]:              0 :                             elog(ERROR, "unrecognized Xid: \"%.*s\"",
                                382                 :                :                                  tok_len, token);
                                383                 :              0 :                         l = lappend_xid(l, val);
                                384                 :                :                     }
 1383 tgl@sss.pgh.pa.us         385                 :              0 :                     result = (Node *) l;
                                386                 :                :                 }
 1383 tgl@sss.pgh.pa.us         387   [ +  +  +  + ]:CBC      860800 :                 else if (tok_len == 1 && token[0] == 'b')
                                388                 :            552 :                 {
                                389                 :                :                     /* Bitmapset -- see also _readBitmapset() */
                                390                 :            552 :                     Bitmapset  *bms = NULL;
                                391                 :                : 
                                392                 :                :                     for (;;)
                                393                 :           1324 :                     {
                                394                 :                :                         int         val;
                                395                 :                :                         char       *endptr;
                                396                 :                : 
    3 michael@paquier.xyz       397                 :GNC        1876 :                         token = pg_strtok(ctx, &tok_len);
 1383 tgl@sss.pgh.pa.us         398         [ -  + ]:CBC        1876 :                         if (token == NULL)
 1383 tgl@sss.pgh.pa.us         399         [ #  # ]:UBC           0 :                             elog(ERROR, "unterminated Bitmapset structure");
 1383 tgl@sss.pgh.pa.us         400   [ +  +  +  + ]:CBC        1876 :                         if (tok_len == 1 && token[0] == ')')
                                401                 :            552 :                             break;
                                402                 :           1324 :                         val = (int) strtol(token, &endptr, 10);
                                403         [ -  + ]:           1324 :                         if (endptr != token + tok_len)
 1383 tgl@sss.pgh.pa.us         404         [ #  # ]:UBC           0 :                             elog(ERROR, "unrecognized integer: \"%.*s\"",
                                405                 :                :                                  tok_len, token);
 1383 tgl@sss.pgh.pa.us         406                 :CBC        1324 :                         bms = bms_add_member(bms, val);
                                407                 :                :                     }
                                408                 :            552 :                     result = (Node *) bms;
                                409                 :                :                 }
                                410                 :                :                 else
                                411                 :                :                 {
                                412                 :                :                     /* List of other node types */
                                413                 :                :                     for (;;)
                                414                 :                :                     {
                                415                 :                :                         /* We have already scanned next token... */
 8146                           416         [ +  + ]:        5395879 :                         if (token[0] == ')')
                                417                 :         860248 :                             break;
    3 michael@paquier.xyz       418                 :GNC     4535631 :                         l = lappend(l, nodeRead(ctx, token, tok_len));
                                419                 :        4535631 :                         token = pg_strtok(ctx, &tok_len);
 8146 tgl@sss.pgh.pa.us         420         [ -  + ]:CBC     4535631 :                         if (token == NULL)
 8146 tgl@sss.pgh.pa.us         421         [ #  # ]:UBC           0 :                             elog(ERROR, "unterminated List structure");
                                422                 :                :                     }
 1383 tgl@sss.pgh.pa.us         423                 :CBC      860248 :                     result = (Node *) l;
                                424                 :                :                 }
 8148                           425                 :         934713 :                 break;
                                426                 :                :             }
10580 bruce@momjian.us          427                 :UBC           0 :         case RIGHT_PAREN:
 8148 tgl@sss.pgh.pa.us         428         [ #  # ]:              0 :             elog(ERROR, "unexpected right parenthesis");
                                429                 :                :             result = NULL;      /* keep compiler happy */
                                430                 :                :             break;
 8148 tgl@sss.pgh.pa.us         431                 :CBC     1758440 :         case OTHER_TOKEN:
 9722                           432         [ +  - ]:        1758440 :             if (tok_len == 0)
                                433                 :                :             {
                                434                 :                :                 /* must be "<>" --- represents a null pointer */
 8148                           435                 :        1758440 :                 result = NULL;
                                436                 :                :             }
                                437                 :                :             else
                                438                 :                :             {
 8148 tgl@sss.pgh.pa.us         439         [ #  # ]:UBC           0 :                 elog(ERROR, "unrecognized token: \"%.*s\"", tok_len, token);
                                440                 :                :                 result = NULL;  /* keep compiler happy */
                                441                 :                :             }
10580 bruce@momjian.us          442                 :CBC     1758440 :             break;
10580 bruce@momjian.us          443                 :UBC           0 :         case T_Integer:
                                444                 :                : 
                                445                 :                :             /*
                                446                 :                :              * we know that the token terminates on a char atoi will stop at
                                447                 :                :              */
 3090 peter_e@gmx.net           448                 :              0 :             result = (Node *) makeInteger(atoi(token));
10580 bruce@momjian.us          449                 :              0 :             break;
 9684 tgl@sss.pgh.pa.us         450                 :              0 :         case T_Float:
                                451                 :                :             {
 9633 bruce@momjian.us          452                 :              0 :                 char       *fval = (char *) palloc(tok_len + 1);
                                453                 :                : 
 9684 tgl@sss.pgh.pa.us         454                 :              0 :                 memcpy(fval, token, tok_len);
                                455                 :              0 :                 fval[tok_len] = '\0';
 8148                           456                 :              0 :                 result = (Node *) makeFloat(fval);
                                457                 :                :             }
 9684                           458                 :              0 :             break;
 1686 peter@eisentraut.org      459                 :              0 :         case T_Boolean:
                                460                 :              0 :             result = (Node *) makeBoolean(token[0] == 't');
                                461                 :              0 :             break;
10580 bruce@momjian.us          462                 :CBC     2099450 :         case T_String:
                                463                 :                :             /* need to remove leading and trailing quotes, and backslashes */
 8148 tgl@sss.pgh.pa.us         464                 :        2099450 :             result = (Node *) makeString(debackslash(token + 1, tok_len - 2));
10580 bruce@momjian.us          465                 :        2099450 :             break;
 9431 peter_e@gmx.net           466                 :UBC           0 :         case T_BitString:
                                467                 :                :             /* need to remove backslashes, but there are no quotes */
  926 tgl@sss.pgh.pa.us         468                 :              0 :             result = (Node *) makeBitString(debackslash(token, tok_len));
                                469                 :              0 :             break;
10580 bruce@momjian.us          470                 :              0 :         default:
 8437 tgl@sss.pgh.pa.us         471         [ #  # ]:              0 :             elog(ERROR, "unrecognized node type: %d", (int) type);
                                472                 :                :             result = NULL;      /* keep compiler happy */
                                473                 :                :             break;
                                474                 :                :     }
                                475                 :                : 
  637 peter@eisentraut.org      476                 :CBC     8412623 :     return result;
                                477                 :                : }
        

Generated by: LCOV version 2.0-1