LCOV - differential code coverage report
Current view: top level - src/backend/nodes - read.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 63.2 % 174 110 64 110
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 6 6 6
Baseline: 16@8cea358b128 Branches: 53.2 % 186 99 87 99
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (60,120] days: 0.0 % 2 0 2
(240..) days: 64.0 % 172 110 62 110
Function coverage date bins:
(240..) days: 100.0 % 6 6 6
Branch coverage date bins:
(240..) days: 53.2 % 186 99 87 99

 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-2024, 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                 :                : /* Static state for pg_strtok */
                                 32                 :                : static const char *pg_strtok_ptr = NULL;
                                 33                 :                : 
                                 34                 :                : /* State flag that determines how readfuncs.c should treat location fields */
                                 35                 :                : #ifdef WRITE_READ_PARSE_PLAN_TREES
                                 36                 :                : bool        restore_location_fields = false;
                                 37                 :                : #endif
                                 38                 :                : 
                                 39                 :                : 
                                 40                 :                : /*
                                 41                 :                :  * stringToNode -
                                 42                 :                :  *    builds a Node tree from its string representation (assumed valid)
                                 43                 :                :  *
                                 44                 :                :  * restore_loc_fields instructs readfuncs.c whether to restore location
                                 45                 :                :  * fields rather than set them to -1.  This is currently only supported
                                 46                 :                :  * in builds with the WRITE_READ_PARSE_PLAN_TREES debugging flag set.
                                 47                 :                :  */
                                 48                 :                : static void *
 2035 tgl@sss.pgh.pa.us          49                 :CBC      159143 : stringToNodeInternal(const char *str, bool restore_loc_fields)
                                 50                 :                : {
                                 51                 :                :     void       *retval;
                                 52                 :                :     const char *save_strtok;
                                 53                 :                : #ifdef WRITE_READ_PARSE_PLAN_TREES
                                 54                 :                :     bool        save_restore_location_fields;
                                 55                 :                : #endif
                                 56                 :                : 
                                 57                 :                :     /*
                                 58                 :                :      * We save and restore the pre-existing state of pg_strtok. This makes the
                                 59                 :                :      * world safe for re-entrant invocation of stringToNode, without incurring
                                 60                 :                :      * a lot of notational overhead by having to pass the next-character
                                 61                 :                :      * pointer around through all the readfuncs.c code.
                                 62                 :                :      */
 8498                            63                 :         159143 :     save_strtok = pg_strtok_ptr;
                                 64                 :                : 
                                 65                 :         159143 :     pg_strtok_ptr = str;        /* point pg_strtok at the string to read */
                                 66                 :                : 
                                 67                 :                :     /*
                                 68                 :                :      * If enabled, likewise save/restore the location field handling flag.
                                 69                 :                :      */
                                 70                 :                : #ifdef WRITE_READ_PARSE_PLAN_TREES
                                 71                 :                :     save_restore_location_fields = restore_location_fields;
                                 72                 :                :     restore_location_fields = restore_loc_fields;
                                 73                 :                : #endif
                                 74                 :                : 
 7168 bruce@momjian.us           75                 :         159143 :     retval = nodeRead(NULL, 0); /* do the reading */
                                 76                 :                : 
 8498 tgl@sss.pgh.pa.us          77                 :         159143 :     pg_strtok_ptr = save_strtok;
                                 78                 :                : 
                                 79                 :                : #ifdef WRITE_READ_PARSE_PLAN_TREES
                                 80                 :                :     restore_location_fields = save_restore_location_fields;
                                 81                 :                : #endif
                                 82                 :                : 
 9716 bruce@momjian.us           83                 :         159143 :     return retval;
                                 84                 :                : }
                                 85                 :                : 
                                 86                 :                : /*
                                 87                 :                :  * Externally visible entry points
                                 88                 :                :  */
                                 89                 :                : void *
 2035 tgl@sss.pgh.pa.us          90                 :         159143 : stringToNode(const char *str)
                                 91                 :                : {
                                 92                 :         159143 :     return stringToNodeInternal(str, false);
                                 93                 :                : }
                                 94                 :                : 
                                 95                 :                : #ifdef WRITE_READ_PARSE_PLAN_TREES
                                 96                 :                : 
                                 97                 :                : void *
                                 98                 :                : stringToNodeWithLocations(const char *str)
                                 99                 :                : {
                                100                 :                :     return stringToNodeInternal(str, true);
                                101                 :                : }
                                102                 :                : 
                                103                 :                : #endif
                                104                 :                : 
                                105                 :                : 
                                106                 :                : /*****************************************************************************
                                107                 :                :  *
                                108                 :                :  * the lisp token parser
                                109                 :                :  *
                                110                 :                :  *****************************************************************************/
                                111                 :                : 
                                112                 :                : /*
                                113                 :                :  * pg_strtok --- retrieve next "token" from a string.
                                114                 :                :  *
                                115                 :                :  * Works kinda like strtok, except it never modifies the source string.
                                116                 :                :  * (Instead of storing nulls into the string, the length of the token
                                117                 :                :  * is returned to the caller.)
                                118                 :                :  * Also, the rules about what is a token are hard-wired rather than being
                                119                 :                :  * configured by passing a set of terminating characters.
                                120                 :                :  *
                                121                 :                :  * The string is assumed to have been initialized already by stringToNode.
                                122                 :                :  *
                                123                 :                :  * The rules for tokens are:
                                124                 :                :  *  * Whitespace (space, tab, newline) always separates tokens.
                                125                 :                :  *  * The characters '(', ')', '{', '}' form individual tokens even
                                126                 :                :  *    without any whitespace around them.
                                127                 :                :  *  * Otherwise, a token is all the characters up to the next whitespace
                                128                 :                :  *    or occurrence of one of the four special characters.
                                129                 :                :  *  * A backslash '\' can be used to quote whitespace or one of the four
                                130                 :                :  *    special characters, so that it is treated as a plain token character.
                                131                 :                :  *    Backslashes themselves must also be backslashed for consistency.
                                132                 :                :  *    Any other character can be, but need not be, backslashed as well.
                                133                 :                :  *  * If the resulting token is '<>' (with no backslash), it is returned
                                134                 :                :  *    as a non-NULL pointer to the token but with length == 0.  Note that
                                135                 :                :  *    there is no other way to get a zero-length token.
                                136                 :                :  *
                                137                 :                :  * Returns a pointer to the start of the next token, and the length of the
                                138                 :                :  * token (including any embedded backslashes!) in *length.  If there are
                                139                 :                :  * no more tokens, NULL and 0 are returned.
                                140                 :                :  *
                                141                 :                :  * NOTE: this routine doesn't remove backslashes; the caller must do so
                                142                 :                :  * if necessary (see "debackslash").
                                143                 :                :  *
                                144                 :                :  * NOTE: prior to release 7.0, this routine also had a special case to treat
                                145                 :                :  * a token starting with '"' as extending to the next '"'.  This code was
                                146                 :                :  * broken, however, since it would fail to cope with a string containing an
                                147                 :                :  * embedded '"'.  I have therefore removed this special case, and instead
                                148                 :                :  * introduced rules for using backslashes to quote characters.  Higher-level
                                149                 :                :  * code should add backslashes to a string constant to ensure it is treated
                                150                 :                :  * as a single token.
                                151                 :                :  */
                                152                 :                : const char *
 8498                           153                 :       46703772 : pg_strtok(int *length)
                                154                 :                : {
                                155                 :                :     const char *local_str;      /* working pointer to string */
                                156                 :                :     const char *ret_str;        /* start of token to return */
                                157                 :                : 
                                158                 :       46703772 :     local_str = pg_strtok_ptr;
                                159                 :                : 
 8857                           160   [ +  +  -  +  :       86337071 :     while (*local_str == ' ' || *local_str == '\n' || *local_str == '\t')
                                              -  + ]
                                161                 :       39633299 :         local_str++;
                                162                 :                : 
                                163         [ -  + ]:       46703772 :     if (*local_str == '\0')
                                164                 :                :     {
 8857 tgl@sss.pgh.pa.us         165                 :UBC           0 :         *length = 0;
 8498                           166                 :              0 :         pg_strtok_ptr = local_str;
 8857                           167                 :              0 :         return NULL;            /* no more tokens */
                                168                 :                :     }
                                169                 :                : 
                                170                 :                :     /*
                                171                 :                :      * Now pointing at start of next token.
                                172                 :                :      */
 8857 tgl@sss.pgh.pa.us         173                 :CBC    46703772 :     ret_str = local_str;
                                174                 :                : 
                                175   [ +  +  +  + ]:       46703772 :     if (*local_str == '(' || *local_str == ')' ||
                                176   [ +  +  +  + ]:       43760956 :         *local_str == '{' || *local_str == '}')
                                177                 :                :     {
                                178                 :                :         /* special 1-character token */
                                179                 :        6913896 :         local_str++;
                                180                 :                :     }
                                181                 :                :     else
                                182                 :                :     {
                                183                 :                :         /* Normal token, possibly containing backslashes */
                                184                 :       39789876 :         while (*local_str != '\0' &&
                                185   [ +  +  +  - ]:      278040261 :                *local_str != ' ' && *local_str != '\n' &&
                                186         [ +  - ]:      241187207 :                *local_str != '\t' &&
                                187   [ +  -  +  + ]:      241187207 :                *local_str != '(' && *local_str != ')' &&
                                188   [ +  +  +  -  :      518172970 :                *local_str != '{' && *local_str != '}')
                                              +  + ]
                                189                 :                :         {
                                190   [ +  +  +  - ]:      238265749 :             if (*local_str == '\\' && local_str[1] != '\0')
                                191                 :           8176 :                 local_str += 2;
                                192                 :                :             else
                                193                 :      238257573 :                 local_str++;
                                194                 :                :         }
                                195                 :                :     }
                                196                 :                : 
                                197                 :       46703772 :     *length = local_str - ret_str;
                                198                 :                : 
                                199                 :                :     /* Recognize special case for "empty" token */
                                200   [ +  +  +  +  :       46703772 :     if (*length == 2 && ret_str[0] == '<' && ret_str[1] == '>')
                                              +  - ]
                                201                 :        1068612 :         *length = 0;
                                202                 :                : 
 8498                           203                 :       46703772 :     pg_strtok_ptr = local_str;
                                204                 :                : 
 8857                           205                 :       46703772 :     return ret_str;
                                206                 :                : }
                                207                 :                : 
                                208                 :                : /*
                                209                 :                :  * debackslash -
                                210                 :                :  *    create a palloc'd string holding the given token.
                                211                 :                :  *    any protective backslashes in the token are removed.
                                212                 :                :  */
                                213                 :                : char *
 2035                           214                 :        1442394 : debackslash(const char *token, int length)
                                215                 :                : {
 8768 bruce@momjian.us          216                 :        1442394 :     char       *result = palloc(length + 1);
                                217                 :        1442394 :     char       *ptr = result;
                                218                 :                : 
 8857 tgl@sss.pgh.pa.us         219         [ +  + ]:       14641502 :     while (length > 0)
                                220                 :                :     {
                                221   [ +  +  +  - ]:       13199108 :         if (*token == '\\' && length > 1)
                                222                 :           8176 :             token++, length--;
                                223                 :       13199108 :         *ptr++ = *token++;
                                224                 :       13199108 :         length--;
                                225                 :                :     }
                                226                 :        1442394 :     *ptr = '\0';
                                227                 :        1442394 :     return result;
                                228                 :                : }
                                229                 :                : 
                                230                 :                : #define RIGHT_PAREN (1000000 + 1)
                                231                 :                : #define LEFT_PAREN  (1000000 + 2)
                                232                 :                : #define LEFT_BRACE  (1000000 + 3)
                                233                 :                : #define OTHER_TOKEN (1000000 + 4)
                                234                 :                : 
                                235                 :                : /*
                                236                 :                :  * nodeTokenType -
                                237                 :                :  *    returns the type of the node token contained in token.
                                238                 :                :  *    It returns one of the following valid NodeTags:
                                239                 :                :  *      T_Integer, T_Float, T_Boolean, T_String, T_BitString
                                240                 :                :  *    and some of its own:
                                241                 :                :  *      RIGHT_PAREN, LEFT_PAREN, LEFT_BRACE, OTHER_TOKEN
                                242                 :                :  *
                                243                 :                :  *    Assumption: the ascii representation is legal
                                244                 :                :  */
                                245                 :                : static NodeTag
 2035                           246                 :        4680552 : nodeTokenType(const char *token, int length)
                                247                 :                : {
                                248                 :                :     NodeTag     retval;
                                249                 :                :     const char *numptr;
                                250                 :                :     int         numlen;
                                251                 :                : 
                                252                 :                :     /*
                                253                 :                :      * Check if the token is a number
                                254                 :                :      */
 8819                           255                 :        4680552 :     numptr = token;
                                256                 :        4680552 :     numlen = length;
                                257   [ +  -  -  + ]:        4680552 :     if (*numptr == '+' || *numptr == '-')
 8819 tgl@sss.pgh.pa.us         258                 :UBC           0 :         numptr++, numlen--;
 8533 tgl@sss.pgh.pa.us         259   [ +  +  +  -  :CBC     4680552 :     if ((numlen > 0 && isdigit((unsigned char) *numptr)) ||
                                              +  + ]
 6756 bruce@momjian.us          260   [ -  +  -  - ]:        1167027 :         (numlen > 1 && *numptr == '.' && isdigit((unsigned char) numptr[1])))
                                261                 :                :     {
                                262                 :                :         /*
                                263                 :                :          * Yes.  Figure out whether it is integral or float; this requires
                                264                 :                :          * both a syntax check and a range check. strtoint() can do both for
                                265                 :                :          * us. We know the token will end at a character that strtoint will
                                266                 :                :          * stop at, so we do not need to modify the string.
                                267                 :                :          */
                                268                 :                :         char       *endptr;
                                269                 :                : 
 8819 tgl@sss.pgh.pa.us         270                 :UBC           0 :         errno = 0;
  568 peter@eisentraut.org      271                 :              0 :         (void) strtoint(numptr, &endptr, 10);
 2224 peter_e@gmx.net           272   [ #  #  #  # ]:              0 :         if (endptr != token + length || errno == ERANGE)
 8819 tgl@sss.pgh.pa.us         273                 :              0 :             return T_Float;
                                274                 :              0 :         return T_Integer;
                                275                 :                :     }
                                276                 :                : 
                                277                 :                :     /*
                                278                 :                :      * these three cases do not need length checks, since pg_strtok() will
                                279                 :                :      * always treat them as single-byte tokens
                                280                 :                :      */
 9716 bruce@momjian.us          281         [ +  + ]:CBC     4680552 :     else if (*token == '(')
                                282                 :         513054 :         retval = LEFT_PAREN;
                                283         [ -  + ]:        4167498 :     else if (*token == ')')
 9716 bruce@momjian.us          284                 :UBC           0 :         retval = RIGHT_PAREN;
 9716 bruce@momjian.us          285         [ +  + ]:CBC     4167498 :     else if (*token == '{')
 7283 tgl@sss.pgh.pa.us         286                 :        1985540 :         retval = LEFT_BRACE;
  818 peter@eisentraut.org      287   [ +  +  +  -  :        2181958 :     else if ((length == 4 && strncmp(token, "true", 4) == 0) ||
                                              +  + ]
                                288         [ -  + ]:          63042 :              (length == 5 && strncmp(token, "false", 5) == 0))
  821 peter@eisentraut.org      289                 :UBC           0 :         retval = T_Boolean;
 3036 peter_e@gmx.net           290   [ +  +  +  -  :CBC     2181958 :     else if (*token == '"' && length > 1 && token[length - 1] == '"')
                                              +  - ]
 8857 tgl@sss.pgh.pa.us         291                 :        1167027 :         retval = T_String;
  568 peter@eisentraut.org      292   [ +  -  -  + ]:        1014931 :     else if (*token == 'b' || *token == 'x')
 8566 peter_e@gmx.net           293                 :UBC           0 :         retval = T_BitString;
                                294                 :                :     else
 7283 tgl@sss.pgh.pa.us         295                 :CBC     1014931 :         retval = OTHER_TOKEN;
 9357 bruce@momjian.us          296                 :        4680552 :     return retval;
                                297                 :                : }
                                298                 :                : 
                                299                 :                : /*
                                300                 :                :  * nodeRead -
                                301                 :                :  *    Slightly higher-level reader.
                                302                 :                :  *
                                303                 :                :  * This routine applies some semantic knowledge on top of the purely
                                304                 :                :  * lexical tokenizer pg_strtok().   It can read
                                305                 :                :  *  * Value token nodes (integers, floats, booleans, or strings);
                                306                 :                :  *  * General nodes (via parseNodeString() from readfuncs.c);
                                307                 :                :  *  * Lists of the above;
                                308                 :                :  *  * Lists of integers, OIDs, or TransactionIds.
                                309                 :                :  * The return value is declared void *, not Node *, to avoid having to
                                310                 :                :  * cast it explicitly in callers that assign to fields of different types.
                                311                 :                :  *
                                312                 :                :  * External callers should always pass NULL/0 for the arguments.  Internally
                                313                 :                :  * a non-NULL token may be passed when the upper recursion level has already
                                314                 :                :  * scanned the first token of a node's representation.
                                315                 :                :  *
                                316                 :                :  * We assume pg_strtok is already initialized with a string to read (hence
                                317                 :                :  * this should only be invoked from within a stringToNode operation).
                                318                 :                :  */
                                319                 :                : void *
 2035 tgl@sss.pgh.pa.us         320                 :        4680552 : nodeRead(const char *token, int tok_len)
                                321                 :                : {
                                322                 :                :     Node       *result;
                                323                 :                :     NodeTag     type;
                                324                 :                : 
 7283                           325         [ +  + ]:        4680552 :     if (token == NULL)          /* need to read a token? */
                                326                 :                :     {
                                327                 :        2161889 :         token = pg_strtok(&tok_len);
                                328                 :                : 
                                329         [ -  + ]:        2161889 :         if (token == NULL)      /* end of input */
 7283 tgl@sss.pgh.pa.us         330                 :UBC           0 :             return NULL;
                                331                 :                :     }
                                332                 :                : 
 9716 bruce@momjian.us          333                 :CBC     4680552 :     type = nodeTokenType(token, tok_len);
                                334                 :                : 
 5200 peter_e@gmx.net           335   [ +  +  -  +  :        4680552 :     switch ((int) type)
                                     -  -  -  +  -  
                                                 - ]
                                336                 :                :     {
 7283 tgl@sss.pgh.pa.us         337                 :        1985540 :         case LEFT_BRACE:
                                338                 :        1985540 :             result = parseNodeString();
 8498                           339                 :        1985540 :             token = pg_strtok(&tok_len);
                                340   [ +  -  -  + ]:        1985540 :             if (token == NULL || token[0] != '}')
 7572 tgl@sss.pgh.pa.us         341         [ #  # ]:UBC           0 :                 elog(ERROR, "did not find '}' at end of input node");
 9715 bruce@momjian.us          342                 :CBC     1985540 :             break;
                                343                 :         513054 :         case LEFT_PAREN:
                                344                 :                :             {
 7283 tgl@sss.pgh.pa.us         345                 :         513054 :                 List       *l = NIL;
                                346                 :                : 
                                347                 :                :                 /*----------
                                348                 :                :                  * Could be an integer list:    (i int int ...)
                                349                 :                :                  * or an OID list:              (o int int ...)
                                350                 :                :                  * or an XID list:              (x int int ...)
                                351                 :                :                  * or a bitmapset:              (b int int ...)
                                352                 :                :                  * or a list of nodes/values:   (node node ...)
                                353                 :                :                  *----------
                                354                 :                :                  */
 7281                           355                 :         513054 :                 token = pg_strtok(&tok_len);
                                356         [ -  + ]:         513054 :                 if (token == NULL)
 7281 tgl@sss.pgh.pa.us         357         [ #  # ]:UBC           0 :                     elog(ERROR, "unterminated List structure");
 7281 tgl@sss.pgh.pa.us         358   [ +  +  +  + ]:CBC      513054 :                 if (tok_len == 1 && token[0] == 'i')
                                359                 :                :                 {
                                360                 :                :                     /* List of integers */
                                361                 :                :                     for (;;)
                                362                 :         565368 :                     {
                                363                 :                :                         int         val;
                                364                 :                :                         char       *endptr;
                                365                 :                : 
                                366                 :         592175 :                         token = pg_strtok(&tok_len);
                                367         [ -  + ]:         592175 :                         if (token == NULL)
 7281 tgl@sss.pgh.pa.us         368         [ #  # ]:UBC           0 :                             elog(ERROR, "unterminated List structure");
 7281 tgl@sss.pgh.pa.us         369         [ +  + ]:CBC      592175 :                         if (token[0] == ')')
                                370                 :          26807 :                             break;
                                371                 :         565368 :                         val = (int) strtol(token, &endptr, 10);
                                372         [ -  + ]:         565368 :                         if (endptr != token + tok_len)
 7281 tgl@sss.pgh.pa.us         373         [ #  # ]:UBC           0 :                             elog(ERROR, "unrecognized integer: \"%.*s\"",
                                374                 :                :                                  tok_len, token);
 7259 neilc@samurai.com         375                 :CBC      565368 :                         l = lappend_int(l, val);
                                376                 :                :                     }
  518 tgl@sss.pgh.pa.us         377                 :          26807 :                     result = (Node *) l;
                                378                 :                :                 }
 7281                           379   [ +  +  +  + ]:         486247 :                 else if (tok_len == 1 && token[0] == 'o')
                                380                 :                :                 {
                                381                 :                :                     /* List of OIDs */
                                382                 :                :                     for (;;)
                                383                 :          35327 :                     {
                                384                 :                :                         Oid         val;
                                385                 :                :                         char       *endptr;
                                386                 :                : 
                                387                 :          46857 :                         token = pg_strtok(&tok_len);
                                388         [ -  + ]:          46857 :                         if (token == NULL)
 7281 tgl@sss.pgh.pa.us         389         [ #  # ]:UBC           0 :                             elog(ERROR, "unterminated List structure");
 7281 tgl@sss.pgh.pa.us         390         [ +  + ]:CBC       46857 :                         if (token[0] == ')')
                                391                 :          11530 :                             break;
                                392                 :          35327 :                         val = (Oid) strtoul(token, &endptr, 10);
                                393         [ -  + ]:          35327 :                         if (endptr != token + tok_len)
 7281 tgl@sss.pgh.pa.us         394         [ #  # ]:UBC           0 :                             elog(ERROR, "unrecognized OID: \"%.*s\"",
                                395                 :                :                                  tok_len, token);
 7259 neilc@samurai.com         396                 :CBC       35327 :                         l = lappend_oid(l, val);
                                397                 :                :                     }
  518 tgl@sss.pgh.pa.us         398                 :          11530 :                     result = (Node *) l;
                                399                 :                :                 }
  641 alvherre@alvh.no-ip.      400   [ +  +  -  + ]:         474717 :                 else if (tok_len == 1 && token[0] == 'x')
                                401                 :                :                 {
                                402                 :                :                     /* List of TransactionIds */
                                403                 :                :                     for (;;)
  641 alvherre@alvh.no-ip.      404                 :UBC           0 :                     {
                                405                 :                :                         TransactionId val;
                                406                 :                :                         char       *endptr;
                                407                 :                : 
                                408                 :              0 :                         token = pg_strtok(&tok_len);
                                409         [ #  # ]:              0 :                         if (token == NULL)
                                410         [ #  # ]:              0 :                             elog(ERROR, "unterminated List structure");
                                411         [ #  # ]:              0 :                         if (token[0] == ')')
                                412                 :              0 :                             break;
                                413                 :              0 :                         val = (TransactionId) strtoul(token, &endptr, 10);
                                414         [ #  # ]:              0 :                         if (endptr != token + tok_len)
                                415         [ #  # ]:              0 :                             elog(ERROR, "unrecognized Xid: \"%.*s\"",
                                416                 :                :                                  tok_len, token);
                                417                 :              0 :                         l = lappend_xid(l, val);
                                418                 :                :                     }
  518 tgl@sss.pgh.pa.us         419                 :              0 :                     result = (Node *) l;
                                420                 :                :                 }
  518 tgl@sss.pgh.pa.us         421   [ +  +  +  - ]:CBC      474717 :                 else if (tok_len == 1 && token[0] == 'b')
  518 tgl@sss.pgh.pa.us         422                 :UBC           0 :                 {
                                423                 :                :                     /* Bitmapset -- see also _readBitmapset() */
                                424                 :              0 :                     Bitmapset  *bms = NULL;
                                425                 :                : 
                                426                 :                :                     for (;;)
                                427                 :              0 :                     {
                                428                 :                :                         int         val;
                                429                 :                :                         char       *endptr;
                                430                 :                : 
                                431                 :              0 :                         token = pg_strtok(&tok_len);
                                432         [ #  # ]:              0 :                         if (token == NULL)
                                433         [ #  # ]:              0 :                             elog(ERROR, "unterminated Bitmapset structure");
                                434   [ #  #  #  # ]:              0 :                         if (tok_len == 1 && token[0] == ')')
                                435                 :              0 :                             break;
                                436                 :              0 :                         val = (int) strtol(token, &endptr, 10);
                                437         [ #  # ]:              0 :                         if (endptr != token + tok_len)
                                438         [ #  # ]:              0 :                             elog(ERROR, "unrecognized integer: \"%.*s\"",
                                439                 :                :                                  tok_len, token);
                                440                 :              0 :                         bms = bms_add_member(bms, val);
                                441                 :                :                     }
                                442                 :              0 :                     result = (Node *) bms;
                                443                 :                :                 }
                                444                 :                :                 else
                                445                 :                :                 {
                                446                 :                :                     /* List of other node types */
                                447                 :                :                     for (;;)
                                448                 :                :                     {
                                449                 :                :                         /* We have already scanned next token... */
 7281 tgl@sss.pgh.pa.us         450         [ +  + ]:CBC     2993380 :                         if (token[0] == ')')
                                451                 :         474717 :                             break;
                                452                 :        2518663 :                         l = lappend(l, nodeRead(token, tok_len));
                                453                 :        2518663 :                         token = pg_strtok(&tok_len);
                                454         [ -  + ]:        2518663 :                         if (token == NULL)
 7281 tgl@sss.pgh.pa.us         455         [ #  # ]:UBC           0 :                             elog(ERROR, "unterminated List structure");
                                456                 :                :                     }
  518 tgl@sss.pgh.pa.us         457                 :CBC      474717 :                     result = (Node *) l;
                                458                 :                :                 }
 7283                           459                 :         513054 :                 break;
                                460                 :                :             }
 9715 bruce@momjian.us          461                 :UBC           0 :         case RIGHT_PAREN:
 7283 tgl@sss.pgh.pa.us         462         [ #  # ]:              0 :             elog(ERROR, "unexpected right parenthesis");
                                463                 :                :             result = NULL;      /* keep compiler happy */
                                464                 :                :             break;
 7283 tgl@sss.pgh.pa.us         465                 :CBC     1014931 :         case OTHER_TOKEN:
 8857                           466         [ +  - ]:        1014931 :             if (tok_len == 0)
                                467                 :                :             {
                                468                 :                :                 /* must be "<>" --- represents a null pointer */
 7283                           469                 :        1014931 :                 result = NULL;
                                470                 :                :             }
                                471                 :                :             else
                                472                 :                :             {
 7283 tgl@sss.pgh.pa.us         473         [ #  # ]:UBC           0 :                 elog(ERROR, "unrecognized token: \"%.*s\"", tok_len, token);
                                474                 :                :                 result = NULL;  /* keep compiler happy */
                                475                 :                :             }
 9715 bruce@momjian.us          476                 :CBC     1014931 :             break;
 9715 bruce@momjian.us          477                 :UBC           0 :         case T_Integer:
                                478                 :                : 
                                479                 :                :             /*
                                480                 :                :              * we know that the token terminates on a char atoi will stop at
                                481                 :                :              */
 2225 peter_e@gmx.net           482                 :              0 :             result = (Node *) makeInteger(atoi(token));
 9715 bruce@momjian.us          483                 :              0 :             break;
 8819 tgl@sss.pgh.pa.us         484                 :              0 :         case T_Float:
                                485                 :                :             {
 8768 bruce@momjian.us          486                 :              0 :                 char       *fval = (char *) palloc(tok_len + 1);
                                487                 :                : 
 8819 tgl@sss.pgh.pa.us         488                 :              0 :                 memcpy(fval, token, tok_len);
                                489                 :              0 :                 fval[tok_len] = '\0';
 7283                           490                 :              0 :                 result = (Node *) makeFloat(fval);
                                491                 :                :             }
 8819                           492                 :              0 :             break;
  821 peter@eisentraut.org      493                 :              0 :         case T_Boolean:
                                494                 :              0 :             result = (Node *) makeBoolean(token[0] == 't');
                                495                 :              0 :             break;
 9715 bruce@momjian.us          496                 :CBC     1167027 :         case T_String:
                                497                 :                :             /* need to remove leading and trailing quotes, and backslashes */
 7283 tgl@sss.pgh.pa.us         498                 :        1167027 :             result = (Node *) makeString(debackslash(token + 1, tok_len - 2));
 9715 bruce@momjian.us          499                 :        1167027 :             break;
 8566 peter_e@gmx.net           500                 :UBC           0 :         case T_BitString:
                                501                 :                :             /* need to remove backslashes, but there are no quotes */
   61 tgl@sss.pgh.pa.us         502                 :              0 :             result = (Node *) makeBitString(debackslash(token, tok_len));
                                503                 :              0 :             break;
 9715 bruce@momjian.us          504                 :              0 :         default:
 7572 tgl@sss.pgh.pa.us         505         [ #  # ]:              0 :             elog(ERROR, "unrecognized node type: %d", (int) type);
                                506                 :                :             result = NULL;      /* keep compiler happy */
                                507                 :                :             break;
                                508                 :                :     }
                                509                 :                : 
 7283 tgl@sss.pgh.pa.us         510                 :CBC     4680552 :     return (void *) result;
                                511                 :                : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622