LCOV - code coverage report
Current view: top level - src/backend/nodes - readfuncs.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 74.0 % 646 478
Test Date: 2026-01-26 10:56:24 Functions: 73.3 % 15 11
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 61.3 % 1610 987

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * readfuncs.c
       4                 :             :  *        Reader functions for Postgres tree nodes.
       5                 :             :  *
       6                 :             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7                 :             :  * Portions Copyright (c) 1994, Regents of the University of California
       8                 :             :  *
       9                 :             :  *
      10                 :             :  * IDENTIFICATION
      11                 :             :  *        src/backend/nodes/readfuncs.c
      12                 :             :  *
      13                 :             :  * NOTES
      14                 :             :  *        Parse location fields are written out by outfuncs.c, but only for
      15                 :             :  *        debugging use.  When reading a location field, we normally discard
      16                 :             :  *        the stored value and set the location field to -1 (ie, "unknown").
      17                 :             :  *        This is because nodes coming from a stored rule should not be thought
      18   [ +  +  +  + ]:      194998 :  *        to have a known location in the current query's text.
      19                 :       11514 :  *
      20   [ +  +  +  - ]:      183484 :  *        However, if restore_location_fields is true, we do restore location
      21                 :           0 :  *        fields from the string.  This is currently intended only for use by the
      22   [ +  +  +  + ]:      183484 :  *        debug_write_read_parse_plan_trees test code, which doesn't want to cause
      23                 :          39 :  *        any change in the node contents.
      24   [ +  +  +  - ]:      183445 :  *
      25                 :           0 :  *-------------------------------------------------------------------------
      26   [ +  +  +  + ]:      183445 :  */
      27                 :       61211 : #include "postgres.h"
      28   [ +  +  +  + ]:      122234 : 
      29                 :       29560 : #include "miscadmin.h"
      30   [ +  +  +  + ]:       92674 : #include "nodes/bitmapset.h"
      31                 :        1692 : #include "nodes/readfuncs.h"
      32   [ +  +  +  + ]:       90982 : 
      33                 :         665 : 
      34   [ +  +  +  + ]:       90317 : /*
      35                 :           3 :  * Macros to simplify reading of different kinds of fields.  Use these
      36   [ +  +  +  + ]:       90314 :  * wherever possible to reduce the chance for silly typos.  Note that these
      37                 :          43 :  * hard-wire conventions about the names of the local variables in a Read
      38   [ -  +  #  # ]:       90271 :  * routine.
      39                 :           0 :  */
      40   [ +  +  +  + ]:       90271 : 
      41                 :           2 : /* Macros for declaring appropriate local variables */
      42   [ +  +  +  + ]:       90269 : 
      43                 :         237 : /* A few guys need only local_node */
      44   [ +  +  +  + ]:       90032 : #define READ_LOCALS_NO_FIELDS(nodeTypeName) \
      45                 :        5493 :         nodeTypeName *local_node = makeNode(nodeTypeName)
      46   [ +  +  +  + ]:       84539 : 
      47                 :          13 : /* And a few guys need only the pg_strtok support fields */
      48   [ +  +  +  + ]:       84526 : #define READ_TEMP_LOCALS()      \
      49                 :        9527 :         const char *token;              \
      50   [ +  +  +  + ]:       74999 :         int                     length
      51                 :           4 : 
      52   [ +  +  +  + ]:       74995 : /* ... but most need both */
      53                 :          86 : #define READ_LOCALS(nodeTypeName)                       \
      54   [ +  +  +  + ]:       74909 :         READ_LOCALS_NO_FIELDS(nodeTypeName);    \
      55                 :         359 :         READ_TEMP_LOCALS()
      56   [ +  +  +  + ]:       74550 : 
      57                 :        1561 : /* Read an integer field (anything written as ":fldname %d") */
      58   [ +  +  +  + ]:       72989 : #define READ_INT_FIELD(fldname) \
      59                 :         442 :         token = pg_strtok(&length);         /* skip :fldname */ \
      60   [ +  +  +  + ]:       72547 :         token = pg_strtok(&length);         /* get field value */ \
      61                 :           8 :         local_node->fldname = atoi(token)
      62   [ +  +  +  - ]:       72539 : 
      63                 :           0 : /* Read an unsigned integer field (anything written as ":fldname %u") */
      64   [ +  +  +  + ]:       72539 : #define READ_UINT_FIELD(fldname) \
      65                 :         606 :         token = pg_strtok(&length);         /* skip :fldname */ \
      66   [ +  +  +  + ]:       71933 :         token = pg_strtok(&length);         /* get field value */ \
      67                 :          56 :         local_node->fldname = atoui(token)
      68   [ +  +  +  + ]:       71877 : 
      69                 :        1039 : /* Read a signed integer field (anything written using INT64_FORMAT) */
      70   [ +  +  +  + ]:       70838 : #define READ_INT64_FIELD(fldname) \
      71                 :         511 :         token = pg_strtok(&length); /* skip :fldname */ \
      72   [ +  +  +  + ]:       70327 :         token = pg_strtok(&length); /* get field value */ \
      73                 :          69 :         local_node->fldname = strtoi64(token, NULL, 10)
      74   [ +  +  -  + ]:       70258 : 
      75                 :           0 : /* Read an unsigned integer field (anything written using UINT64_FORMAT) */
      76   [ +  +  +  + ]:       70258 : #define READ_UINT64_FIELD(fldname) \
      77                 :          54 :         token = pg_strtok(&length);         /* skip :fldname */ \
      78   [ +  +  +  + ]:       70204 :         token = pg_strtok(&length);         /* get field value */ \
      79                 :         549 :         local_node->fldname = strtou64(token, NULL, 10)
      80   [ +  +  +  + ]:       69655 : 
      81                 :        1357 : /* Read a long integer field (anything written as ":fldname %ld") */
      82   [ +  +  +  + ]:       68298 : #define READ_LONG_FIELD(fldname) \
      83                 :         555 :         token = pg_strtok(&length);         /* skip :fldname */ \
      84   [ +  +  +  + ]:       67743 :         token = pg_strtok(&length);         /* get field value */ \
      85                 :         378 :         local_node->fldname = atol(token)
      86   [ +  +  +  + ]:       67365 : 
      87                 :          23 : /* Read an OID field (don't hard-wire assumption that OID is same as uint) */
      88   [ +  +  +  + ]:       67342 : #define READ_OID_FIELD(fldname) \
      89                 :           6 :         token = pg_strtok(&length);         /* skip :fldname */ \
      90   [ +  +  +  + ]:       67336 :         token = pg_strtok(&length);         /* get field value */ \
      91                 :         199 :         local_node->fldname = atooid(token)
      92   [ +  +  +  + ]:       67137 : 
      93                 :           3 : /* Read a char field (ie, one ascii character) */
      94   [ +  +  +  + ]:       67134 : #define READ_CHAR_FIELD(fldname) \
      95                 :         207 :         token = pg_strtok(&length);         /* skip :fldname */ \
      96   [ +  +  +  + ]:       66927 :         token = pg_strtok(&length);         /* get field value */ \
      97                 :          34 :         /* avoid overhead of calling debackslash() for one char */ \
      98   [ +  +  +  + ]:       66893 :         local_node->fldname = (length == 0) ? '\0' : (token[0] == '\\' ? token[1] : token[0])
      99                 :         566 : 
     100   [ +  +  +  + ]:       66327 : /* Read an enumerated-type field that was written as an integer code */
     101                 :         213 : #define READ_ENUM_FIELD(fldname, enumtype) \
     102   [ +  +  +  + ]:       66114 :         token = pg_strtok(&length);         /* skip :fldname */ \
     103                 :         155 :         token = pg_strtok(&length);         /* get field value */ \
     104   [ +  +  +  + ]:       65959 :         local_node->fldname = (enumtype) atoi(token)
     105                 :          15 : 
     106   [ +  +  +  + ]:       65944 : /* Read a float field */
     107                 :          20 : #define READ_FLOAT_FIELD(fldname) \
     108   [ +  +  +  + ]:       65924 :         token = pg_strtok(&length);         /* skip :fldname */ \
     109                 :         346 :         token = pg_strtok(&length);         /* get field value */ \
     110   [ +  +  +  + ]:       65578 :         local_node->fldname = atof(token)
     111                 :         198 : 
     112   [ +  +  +  + ]:       65380 : /* Read a boolean field */
     113                 :          69 : #define READ_BOOL_FIELD(fldname) \
     114   [ +  +  +  + ]:       65311 :         token = pg_strtok(&length);         /* skip :fldname */ \
     115                 :          69 :         token = pg_strtok(&length);         /* get field value */ \
     116   [ +  +  +  + ]:       65242 :         local_node->fldname = strtobool(token)
     117                 :          15 : 
     118   [ +  +  +  + ]:       65227 : /* Read a character-string field */
     119                 :         160 : #define READ_STRING_FIELD(fldname) \
     120   [ +  +  +  + ]:       65067 :         token = pg_strtok(&length);         /* skip :fldname */ \
     121                 :           1 :         token = pg_strtok(&length);         /* get field value */ \
     122   [ +  +  +  + ]:       65066 :         local_node->fldname = nullable_string(token, length)
     123                 :          26 : 
     124   [ +  +  +  + ]:       65040 : /* Read a parse location field (and possibly throw away the value) */
     125                 :        1590 : #ifdef DEBUG_NODE_TESTS_ENABLED
     126   [ +  +  +  + ]:       63450 : #define READ_LOCATION_FIELD(fldname) \
     127                 :         213 :         token = pg_strtok(&length);         /* skip :fldname */ \
     128   [ +  +  +  + ]:       63237 :         token = pg_strtok(&length);         /* get field value */ \
     129                 :          32 :         local_node->fldname = restore_location_fields ? atoi(token) : -1
     130   [ +  +  +  - ]:       63205 : #else
     131                 :           0 : #define READ_LOCATION_FIELD(fldname) \
     132   [ +  +  +  - ]:       63205 :         token = pg_strtok(&length);         /* skip :fldname */ \
     133                 :           0 :         token = pg_strtok(&length);         /* get field value */ \
     134   [ +  +  +  + ]:       63205 :         (void) token;                           /* in case not used elsewhere */ \
     135                 :           6 :         local_node->fldname = -1     /* set field to "unknown" */
     136   [ +  +  +  - ]:       63199 : #endif
     137                 :           0 : 
     138   [ +  +  +  + ]:       63199 : /* Read a Node field */
     139                 :       17934 : #define READ_NODE_FIELD(fldname) \
     140   [ +  +  +  + ]:       45265 :         token = pg_strtok(&length);         /* skip :fldname */ \
     141                 :        5003 :         (void) token;                           /* in case not used elsewhere */ \
     142   [ +  +  +  + ]:       40262 :         local_node->fldname = nodeRead(NULL, 0)
     143                 :         819 : 
     144   [ +  +  +  + ]:       39443 : /* Read a bitmapset field */
     145                 :        4194 : #define READ_BITMAPSET_FIELD(fldname) \
     146   [ +  +  +  + ]:       35249 :         token = pg_strtok(&length);         /* skip :fldname */ \
     147                 :           8 :         (void) token;                           /* in case not used elsewhere */ \
     148   [ +  +  -  + ]:       35241 :         local_node->fldname = _readBitmapset()
     149                 :        4204 : 
     150   [ +  +  +  - ]:       31037 : /* Read an attribute number array */
     151                 :           0 : #define READ_ATTRNUMBER_ARRAY(fldname, len) \
     152   [ +  +  -  + ]:       31037 :         token = pg_strtok(&length);         /* skip :fldname */ \
     153                 :           0 :         local_node->fldname = readAttrNumberCols(len)
     154   [ +  +  +  - ]:       31037 : 
     155                 :           0 : /* Read an oid array */
     156   [ +  +  +  - ]:       31037 : #define READ_OID_ARRAY(fldname, len) \
     157                 :           0 :         token = pg_strtok(&length);         /* skip :fldname */ \
     158   [ +  +  -  + ]:       31037 :         local_node->fldname = readOidCols(len)
     159                 :           0 : 
     160   [ +  +  +  - ]:       31037 : /* Read an int array */
     161                 :           0 : #define READ_INT_ARRAY(fldname, len) \
     162   [ +  +  +  - ]:       31037 :         token = pg_strtok(&length);         /* skip :fldname */ \
     163                 :           0 :         local_node->fldname = readIntCols(len)
     164   [ +  +  +  - ]:       31037 : 
     165                 :           0 : /* Read a bool array */
     166   [ +  +  +  - ]:       31037 : #define READ_BOOL_ARRAY(fldname, len) \
     167                 :           0 :         token = pg_strtok(&length);         /* skip :fldname */ \
     168   [ +  +  -  + ]:       31037 :         local_node->fldname = readBoolCols(len)
     169                 :           0 : 
     170   [ +  +  +  - ]:       31037 : /* Routine exit */
     171                 :           0 : #define READ_DONE() \
     172   [ +  +  +  - ]:       31037 :         return local_node
     173                 :           0 : 
     174   [ +  +  -  + ]:       31037 : 
     175                 :           0 : /*
     176   [ +  +  +  - ]:       31037 :  * NOTE: use atoi() to read values written with %d, or atoui() to read
     177                 :           0 :  * values written with %u in outfuncs.c.  An exception is OID values,
     178   [ +  +  +  - ]:       31037 :  * for which use atooid().  (As of 7.1, outfuncs.c writes OIDs as %u,
     179                 :           0 :  * but this will probably change in the future.)
     180   [ +  +  +  - ]:       31037 :  */
     181                 :           0 : #define atoui(x)  ((unsigned int) strtoul((x), NULL, 10))
     182   [ +  +  +  - ]:       31037 : 
     183                 :           0 : #define strtobool(x)  ((*(x) == 't') ? true : false)
     184   [ +  +  +  - ]:       31037 : 
     185                 :           0 : static char *
     186   [ +  +  +  - ]:       69434 : nullable_string(const char *token, int length)
     187                 :           0 : {
     188   [ +  +  +  - ]:       31037 :         /* outToken emits <> for NULL, and pg_strtok makes that an empty string */
     189         [ +  + ]:       38397 :         if (length == 0)
     190   [ +  +  +  - ]:       43094 :                 return NULL;
     191                 :           0 :         /* outToken emits "" for empty string */
     192   [ +  +  +  -  :       57377 :         if (length == 2 && token[0] == '"' && token[1] == '"')
          +  +  -  +  #  
                      # ]
     193                 :           0 :                 return pstrdup("");
     194   [ +  +  +  - ]:       31037 :         /* otherwise, we must remove protective backslashes added by outToken */
     195                 :       26340 :         return debackslash(token, length);
     196   [ +  +  +  - ]:       69434 : }
     197                 :           0 : 
     198   [ +  +  +  - ]:       31037 : 
     199                 :           0 : /*
     200   [ +  +  +  - ]:       31037 :  * _readBitmapset
     201                 :           0 :  *
     202   [ +  +  +  - ]:       31037 :  * Note: this code is used in contexts where we know that a Bitmapset
     203                 :           0 :  * is expected.  There is equivalent code in nodeRead() that can read a
     204   [ +  +  +  - ]:       31037 :  * Bitmapset when we come across one in other contexts.
     205                 :           0 :  */
     206   [ +  +  -  + ]:       31037 : static Bitmapset *
     207                 :       81819 : _readBitmapset(void)
     208   [ +  +  +  - ]:       31037 : {
     209                 :       81819 :         Bitmapset  *result = NULL;
     210   [ +  +  +  + ]:       31037 : 
     211                 :       87879 :         READ_TEMP_LOCALS();
     212   [ +  +  -  + ]:       24977 : 
     213                 :       90025 :         token = pg_strtok(&length);
     214   [ +  -  -  +  :       98590 :         if (token == NULL)
                   #  # ]
     215   [ #  #  #  # ]:           0 :                 elog(ERROR, "incomplete Bitmapset structure");
     216   [ +  -  +  +  :       98590 :         if (length != 1 || token[0] != '(')
                   +  - ]
     217   [ #  #  #  # ]:           0 :                 elog(ERROR, "unrecognized token: \"%.*s\"", length, token);
     218   [ +  +  +  + ]:       16771 : 
     219                 :       90025 :         token = pg_strtok(&length);
     220   [ +  -  +  +  :       90384 :         if (token == NULL)
                   +  + ]
     221   [ #  #  #  # ]:        5257 :                 elog(ERROR, "incomplete Bitmapset structure");
     222   [ +  -  +  +  :       85127 :         if (length != 1 || token[0] != 'b')
                   +  + ]
     223   [ #  #  #  # ]:         431 :                 elog(ERROR, "unrecognized token: \"%.*s\"", length, token);
     224   [ +  +  -  + ]:        2877 : 
     225                 :      106910 :         for (;;)
     226   [ +  +  +  - ]:        2871 :         {
     227                 :      106904 :                 int                     val;
     228   [ +  +  +  + ]:      109775 :                 char       *endptr;
     229                 :         558 : 
     230   [ +  +  +  + ]:      109217 :                 token = pg_strtok(&length);
     231         [ +  - ]:      106913 :                 if (token == NULL)
     232   [ #  #  #  #  :        2304 :                         elog(ERROR, "unterminated Bitmapset structure");
             +  +  +  + ]
     233   [ +  +  +  + ]:      106941 :                 if (length == 1 && token[0] == ')')
     234   [ +  +  +  + ]:       84086 :                         break;
     235                 :       25090 :                 val = (int) strtol(token, &endptr, 10);
     236   [ +  -  +  +  :       27347 :                 if (endptr != token + length)
                   +  - ]
     237   [ #  #  #  # ]:           0 :                         elog(ERROR, "unrecognized integer: \"%.*s\"", length, token);
     238   [ +  +  +  - ]:       27347 :                 result = bms_add_member(result, val);
     239      [ +  -  + ]:      106904 :         }
     240   [ +  +  +  - ]:        2262 : 
     241                 :      163638 :         return result;
     242   [ +  +  +  + ]:       84081 : }
     243                 :           3 : 
     244   [ +  +  +  + ]:        2259 : /*
     245                 :           6 :  * We export this function for use by extensions that define extensible nodes.
     246   [ +  +  +  + ]:        2253 :  * That's somewhat historical, though, because calling nodeRead() will work.
     247                 :          48 :  */
     248   [ +  +  +  - ]:        2205 : Bitmapset *
     249                 :           0 : readBitmapset(void)
     250   [ +  +  +  - ]:        2205 : {
     251                 :           0 :         return _readBitmapset();
     252   [ +  +  +  - ]:        2205 : }
     253                 :           0 : 
     254   [ -  +  #  # ]:        2205 : #include "readfuncs.funcs.c"
     255                 :           0 : 
     256   [ +  +  +  - ]:        2205 : 
     257                 :           0 : /*
     258   [ +  +  -  + ]:        2205 :  * Support functions for nodes with custom_read_write attribute or
     259                 :           0 :  * special_read_write attribute
     260   [ +  +  +  - ]:        2205 :  */
     261                 :           0 : 
     262   [ -  +  #  # ]:        2205 : static Const *
     263                 :       29560 : _readConst(void)
     264   [ +  +  -  + ]:        2205 : {
     265                 :       29560 :         READ_LOCALS(Const);
     266   [ +  +  +  - ]:        2205 : 
     267                 :       29560 :         READ_OID_FIELD(consttype);
     268   [ +  +  +  - ]:       31765 :         READ_INT_FIELD(consttypmod);
     269                 :       29560 :         READ_OID_FIELD(constcollid);
     270   [ +  +  +  - ]:       31765 :         READ_INT_FIELD(constlen);
     271                 :       29560 :         READ_BOOL_FIELD(constbyval);
     272   [ +  +  +  - ]:       31765 :         READ_BOOL_FIELD(constisnull);
     273         [ -  + ]:       29560 :         READ_LOCATION_FIELD(location);
     274   [ -  +  #  # ]:        2205 : 
     275                 :       29560 :         token = pg_strtok(&length); /* skip :constvalue */
     276   [ -  +  #  #  :       31765 :         if (local_node->constisnull)
                   +  + ]
     277                 :        1333 :                 token = pg_strtok(&length); /* skip "<>" */
     278   [ +  +  +  - ]:        2205 :         else
     279                 :       28227 :                 local_node->constvalue = readDatum(local_node->constbyval);
     280   [ +  +  +  - ]:        2205 : 
     281                 :       59120 :         READ_DONE();
     282   [ +  +  +  - ]:       31765 : }
     283                 :           0 : 
     284   [ +  +  +  - ]:        2205 : static BoolExpr *
     285                 :        1561 : _readBoolExpr(void)
     286   [ +  +  +  - ]:        2205 : {
     287                 :        1561 :         READ_LOCALS(BoolExpr);
     288   [ +  +  +  - ]:        2205 : 
     289                 :           0 :         /* do-it-yourself enum representation */
     290   [ +  +  +  - ]:        3766 :         token = pg_strtok(&length); /* skip :boolop */
     291                 :        1561 :         token = pg_strtok(&length); /* get field value */
     292   [ +  +  +  -  :        3766 :         if (length == 3 && strncmp(token, "and", 3) == 0)
             +  +  +  + ]
     293                 :        1228 :                 local_node->boolop = AND_EXPR;
     294   [ +  +  -  +  :        2538 :         else if (length == 2 && strncmp(token, "or", 2) == 0)
             +  +  -  + ]
     295                 :         210 :                 local_node->boolop = OR_EXPR;
     296   [ +  +  +  -  :        2328 :         else if (length == 3 && strncmp(token, "not", 3) == 0)
                   +  - ]
     297                 :         123 :                 local_node->boolop = NOT_EXPR;
     298   [ +  +  +  - ]:        2205 :         else
     299   [ #  #  #  # ]:           0 :                 elog(ERROR, "unrecognized boolop \"%.*s\"", length, token);
     300   [ +  +  -  + ]:        2205 : 
     301                 :        1718 :         READ_NODE_FIELD(args);
     302   [ +  +  -  +  :        3609 :         READ_LOCATION_FIELD(location);
                   -  + ]
     303                 :           0 : 
     304   [ +  +  +  - ]:        5170 :         READ_DONE();
     305                 :        1561 : }
     306   [ -  +  #  # ]:        2048 : 
     307                 :           0 : static A_Const *
     308   [ +  +  +  - ]:        2048 : _readA_Const(void)
     309                 :           0 : {
     310   [ +  +  +  - ]:        2048 :         READ_LOCALS(A_Const);
     311                 :           0 : 
     312   [ -  +  #  # ]:        2048 :         /* We expect either NULL or :val here */
     313                 :           0 :         token = pg_strtok(&length);
     314   [ -  +  #  #  :        2048 :         if (length == 4 && strncmp(token, "NULL", 4) == 0)
             #  #  #  # ]
     315                 :           0 :                 local_node->isnull = true;
     316   [ +  +  +  - ]:        2048 :         else
     317                 :           0 :         {
     318   [ +  +  +  - ]:        2048 :                 union ValUnion *tmp = nodeRead(NULL, 0);
     319                 :           0 : 
     320   [ +  +  +  - ]:        2048 :                 /* To forestall valgrind complaints, copy only the valid data */
     321   [ #  #  #  #  :           0 :                 switch (nodeTag(tmp))
                   #  # ]
     322   [ +  +  +  - ]:        2048 :                 {
     323                 :           0 :                         case T_Integer:
     324   [ +  +  +  - ]:        2048 :                                 memcpy(&local_node->val, tmp, sizeof(Integer));
     325                 :           0 :                                 break;
     326   [ +  +  +  - ]:        2048 :                         case T_Float:
     327                 :           0 :                                 memcpy(&local_node->val, tmp, sizeof(Float));
     328   [ -  +  #  # ]:        2048 :                                 break;
     329                 :           0 :                         case T_Boolean:
     330   [ +  +  +  - ]:        2048 :                                 memcpy(&local_node->val, tmp, sizeof(Boolean));
     331                 :           0 :                                 break;
     332   [ +  +  +  - ]:        2048 :                         case T_String:
     333                 :           0 :                                 memcpy(&local_node->val, tmp, sizeof(String));
     334   [ -  +  #  # ]:        2048 :                                 break;
     335                 :           0 :                         case T_BitString:
     336   [ +  +  +  - ]:        2048 :                                 memcpy(&local_node->val, tmp, sizeof(BitString));
     337                 :           0 :                                 break;
     338   [ +  +  +  - ]:        2048 :                         default:
     339   [ #  #  #  # ]:           0 :                                 elog(ERROR, "unrecognized node type: %d",
     340   [ +  +  +  - ]:        2048 :                                          (int) nodeTag(tmp));
     341                 :           0 :                                 break;
     342   [ +  +  +  - ]:        2048 :                 }
     343                 :           0 :         }
     344   [ -  +  #  # ]:        2048 : 
     345         [ #  # ]:           0 :         READ_LOCATION_FIELD(location);
     346   [ -  +  #  # ]:        2048 : 
     347                 :           0 :         READ_DONE();
     348   [ -  +  #  # ]:        2048 : }
     349                 :           0 : 
     350   [ +  +  +  - ]:        2048 : static RangeTblEntry *
     351                 :        8206 : _readRangeTblEntry(void)
     352   [ -  +  #  # ]:        2048 : {
     353                 :        8206 :         READ_LOCALS(RangeTblEntry);
     354   [ +  +  +  - ]:        2048 : 
     355                 :        8206 :         READ_NODE_FIELD(alias);
     356   [ +  +  +  - ]:       10254 :         READ_NODE_FIELD(eref);
     357                 :        8206 :         READ_ENUM_FIELD(rtekind, RTEKind);
     358   [ +  +  +  - ]:        2048 : 
     359   [ +  +  +  +  :        8206 :         switch (local_node->rtekind)
          +  -  +  +  +  
                   +  - ]
     360   [ -  +  #  # ]:        2048 :         {
     361                 :           0 :                 case RTE_RELATION:
     362   [ -  +  #  # ]:        7653 :                         READ_OID_FIELD(relid);
     363                 :        5605 :                         READ_BOOL_FIELD(inh);
     364   [ -  +  #  #  :        7653 :                         READ_CHAR_FIELD(relkind);
             +  -  -  + ]
     365                 :        5605 :                         READ_INT_FIELD(rellockmode);
     366   [ +  +  +  - ]:        7653 :                         READ_UINT_FIELD(perminfoindex);
     367                 :        5605 :                         READ_NODE_FIELD(tablesample);
     368   [ -  +  #  # ]:        7653 :                         break;
     369                 :           0 :                 case RTE_SUBQUERY:
     370   [ +  +  +  - ]:        2764 :                         READ_NODE_FIELD(subquery);
     371                 :         716 :                         READ_BOOL_FIELD(security_barrier);
     372   [ -  +  #  # ]:        2048 :                         /* we re-use these RELATION fields, too: */
     373                 :         716 :                         READ_OID_FIELD(relid);
     374   [ +  +  +  - ]:        2764 :                         READ_BOOL_FIELD(inh);
     375   [ +  +  -  + ]:         716 :                         READ_CHAR_FIELD(relkind);
     376   [ +  +  +  - ]:        2764 :                         READ_INT_FIELD(rellockmode);
     377                 :         716 :                         READ_UINT_FIELD(perminfoindex);
     378   [ +  +  +  - ]:        2764 :                         break;
     379                 :           0 :                 case RTE_JOIN:
     380   [ -  +  #  # ]:        3062 :                         READ_ENUM_FIELD(jointype, JoinType);
     381                 :        1014 :                         READ_INT_FIELD(joinmergedcols);
     382   [ +  +  +  - ]:        3062 :                         READ_NODE_FIELD(joinaliasvars);
     383                 :        1014 :                         READ_NODE_FIELD(joinleftcols);
     384   [ +  +  +  - ]:        3062 :                         READ_NODE_FIELD(joinrightcols);
     385                 :        1014 :                         READ_NODE_FIELD(join_using_alias);
     386   [ +  +  +  - ]:        3062 :                         break;
     387                 :           0 :                 case RTE_FUNCTION:
     388   [ +  +  +  - ]:        2450 :                         READ_NODE_FIELD(functions);
     389                 :         402 :                         READ_BOOL_FIELD(funcordinality);
     390   [ -  +  #  # ]:        2450 :                         break;
     391                 :           0 :                 case RTE_TABLEFUNC:
     392   [ +  +  +  - ]:        2087 :                         READ_NODE_FIELD(tablefunc);
     393                 :           0 :                         /* The RTE must have a copy of the column type info, if any */
     394   [ +  +  +  -  :        2087 :                         if (local_node->tablefunc)
                   -  + ]
     395                 :           0 :                         {
     396   [ +  +  +  - ]:        2087 :                                 TableFunc  *tf = local_node->tablefunc;
     397                 :           0 : 
     398   [ +  +  +  - ]:        2087 :                                 local_node->coltypes = tf->coltypes;
     399                 :          39 :                                 local_node->coltypmods = tf->coltypmods;
     400   [ -  +  #  # ]:        2087 :                                 local_node->colcollations = tf->colcollations;
     401                 :          39 :                         }
     402   [ -  +  #  # ]:        2087 :                         break;
     403                 :           0 :                 case RTE_VALUES:
     404   [ -  +  #  # ]:        2231 :                         READ_NODE_FIELD(values_lists);
     405                 :         183 :                         READ_NODE_FIELD(coltypes);
     406   [ +  +  +  - ]:        2231 :                         READ_NODE_FIELD(coltypmods);
     407                 :         183 :                         READ_NODE_FIELD(colcollations);
     408   [ -  +  #  # ]:        2231 :                         break;
     409                 :           0 :                 case RTE_CTE:
     410   [ +  +  +  - ]:        2110 :                         READ_STRING_FIELD(ctename);
     411                 :          62 :                         READ_UINT_FIELD(ctelevelsup);
     412   [ +  +  +  - ]:        2110 :                         READ_BOOL_FIELD(self_reference);
     413                 :          62 :                         READ_NODE_FIELD(coltypes);
     414   [ +  +  +  - ]:        2110 :                         READ_NODE_FIELD(coltypmods);
     415                 :          62 :                         READ_NODE_FIELD(colcollations);
     416   [ +  +  +  - ]:        2110 :                         break;
     417                 :           0 :                 case RTE_NAMEDTUPLESTORE:
     418   [ -  +  #  # ]:        2048 :                         READ_STRING_FIELD(enrname);
     419                 :           0 :                         READ_FLOAT_FIELD(enrtuples);
     420   [ +  +  +  - ]:        2048 :                         READ_NODE_FIELD(coltypes);
     421                 :           0 :                         READ_NODE_FIELD(coltypmods);
     422   [ +  +  +  - ]:        2048 :                         READ_NODE_FIELD(colcollations);
     423                 :           0 :                         /* we re-use these RELATION fields, too: */
     424   [ +  +  +  - ]:        2048 :                         READ_OID_FIELD(relid);
     425                 :           0 :                         break;
     426   [ +  +  +  - ]:        2048 :                 case RTE_RESULT:
     427                 :           0 :                         /* no extra fields */
     428   [ +  +  +  - ]:        2048 :                         break;
     429                 :           0 :                 case RTE_GROUP:
     430   [ +  +  +  - ]:        2214 :                         READ_NODE_FIELD(groupexprs);
     431                 :         166 :                         break;
     432   [ +  +  +  - ]:        2048 :                 default:
     433   [ #  #  #  # ]:           0 :                         elog(ERROR, "unrecognized RTE kind: %d",
     434   [ -  +  #  # ]:        2048 :                                  (int) local_node->rtekind);
     435                 :           0 :                         break;
     436   [ -  +  #  # ]:        2048 :         }
     437                 :           0 : 
     438   [ +  +  +  - ]:       10254 :         READ_BOOL_FIELD(lateral);
     439                 :        8206 :         READ_BOOL_FIELD(inFromCl);
     440   [ +  +  +  - ]:       10254 :         READ_NODE_FIELD(securityQuals);
     441                 :           0 : 
     442   [ +  +  +  - ]:       18460 :         READ_DONE();
     443                 :        8206 : }
     444   [ -  +  #  # ]:        2048 : 
     445                 :           0 : static A_Expr *
     446   [ -  +  #  # ]:        2048 : _readA_Expr(void)
     447                 :           0 : {
     448   [ +  +  +  - ]:        2048 :         READ_LOCALS(A_Expr);
     449                 :           0 : 
     450   [ -  +  #  # ]:        2048 :         token = pg_strtok(&length);
     451                 :           0 : 
     452   [ +  +  +  -  :        2048 :         if (length == 3 && strncmp(token, "ANY", 3) == 0)
             #  #  #  # ]
     453                 :           0 :         {
     454   [ +  +  +  - ]:        2048 :                 local_node->kind = AEXPR_OP_ANY;
     455                 :           0 :                 READ_NODE_FIELD(name);
     456   [ +  +  +  + ]:        2048 :         }
     457   [ #  #  #  # ]:          10 :         else if (length == 3 && strncmp(token, "ALL", 3) == 0)
     458   [ +  +  +  - ]:        2038 :         {
     459                 :           0 :                 local_node->kind = AEXPR_OP_ALL;
     460   [ +  +  +  - ]:        2038 :                 READ_NODE_FIELD(name);
     461                 :           0 :         }
     462   [ +  +  +  -  :        2038 :         else if (length == 8 && strncmp(token, "DISTINCT", 8) == 0)
             #  #  #  # ]
     463                 :           0 :         {
     464   [ -  +  #  # ]:        2038 :                 local_node->kind = AEXPR_DISTINCT;
     465                 :           0 :                 READ_NODE_FIELD(name);
     466   [ +  +  +  - ]:        2038 :         }
     467   [ #  #  #  # ]:           0 :         else if (length == 12 && strncmp(token, "NOT_DISTINCT", 12) == 0)
     468   [ +  +  +  - ]:        2038 :         {
     469                 :           0 :                 local_node->kind = AEXPR_NOT_DISTINCT;
     470   [ +  +  +  - ]:        2038 :                 READ_NODE_FIELD(name);
     471                 :           0 :         }
     472   [ +  +  +  -  :        2038 :         else if (length == 6 && strncmp(token, "NULLIF", 6) == 0)
             #  #  #  # ]
     473                 :           0 :         {
     474   [ +  +  +  - ]:        2038 :                 local_node->kind = AEXPR_NULLIF;
     475                 :           0 :                 READ_NODE_FIELD(name);
     476   [ +  +  +  - ]:        2038 :         }
     477   [ #  #  #  # ]:           0 :         else if (length == 2 && strncmp(token, "IN", 2) == 0)
     478   [ -  +  #  # ]:        2038 :         {
     479                 :           0 :                 local_node->kind = AEXPR_IN;
     480   [ -  +  #  # ]:        2038 :                 READ_NODE_FIELD(name);
     481                 :           0 :         }
     482   [ +  +  +  -  :        2038 :         else if (length == 4 && strncmp(token, "LIKE", 4) == 0)
             #  #  #  # ]
     483                 :           0 :         {
     484   [ +  +  +  - ]:        2038 :                 local_node->kind = AEXPR_LIKE;
     485                 :           0 :                 READ_NODE_FIELD(name);
     486   [ +  +  +  - ]:        2038 :         }
     487   [ #  #  #  # ]:           0 :         else if (length == 5 && strncmp(token, "ILIKE", 5) == 0)
     488   [ +  +  +  - ]:        2038 :         {
     489                 :           0 :                 local_node->kind = AEXPR_ILIKE;
     490   [ +  +  +  - ]:        2038 :                 READ_NODE_FIELD(name);
     491                 :           0 :         }
     492   [ +  +  +  -  :        2038 :         else if (length == 7 && strncmp(token, "SIMILAR", 7) == 0)
             #  #  #  # ]
     493                 :           0 :         {
     494   [ +  +  +  - ]:        2038 :                 local_node->kind = AEXPR_SIMILAR;
     495                 :           0 :                 READ_NODE_FIELD(name);
     496   [ -  +  #  # ]:        2038 :         }
     497   [ #  #  #  # ]:           0 :         else if (length == 7 && strncmp(token, "BETWEEN", 7) == 0)
     498   [ +  +  +  - ]:        2038 :         {
     499                 :           0 :                 local_node->kind = AEXPR_BETWEEN;
     500   [ +  +  +  - ]:        2038 :                 READ_NODE_FIELD(name);
     501                 :           0 :         }
     502   [ +  +  +  -  :        2038 :         else if (length == 11 && strncmp(token, "NOT_BETWEEN", 11) == 0)
             #  #  #  # ]
     503                 :           0 :         {
     504   [ +  +  +  - ]:        2038 :                 local_node->kind = AEXPR_NOT_BETWEEN;
     505                 :           0 :                 READ_NODE_FIELD(name);
     506   [ +  +  +  - ]:        2038 :         }
     507   [ #  #  #  # ]:           0 :         else if (length == 11 && strncmp(token, "BETWEEN_SYM", 11) == 0)
     508   [ +  +  +  - ]:        2038 :         {
     509                 :           0 :                 local_node->kind = AEXPR_BETWEEN_SYM;
     510   [ +  +  +  - ]:        2038 :                 READ_NODE_FIELD(name);
     511                 :           0 :         }
     512   [ +  +  +  -  :        2038 :         else if (length == 15 && strncmp(token, "NOT_BETWEEN_SYM", 15) == 0)
             #  #  #  # ]
     513                 :           0 :         {
     514   [ -  +  #  # ]:        2038 :                 local_node->kind = AEXPR_NOT_BETWEEN_SYM;
     515                 :           0 :                 READ_NODE_FIELD(name);
     516   [ +  +  +  - ]:        2038 :         }
     517         [ #  # ]:           0 :         else if (length == 5 && strncmp(token, ":name", 5) == 0)
     518   [ +  +  +  - ]:        2038 :         {
     519                 :           0 :                 local_node->kind = AEXPR_OP;
     520   [ +  +  +  - ]:        2038 :                 local_node->name = nodeRead(NULL, 0);
     521                 :           0 :         }
     522   [ +  +  +  - ]:        2038 :         else
     523   [ #  #  #  # ]:           0 :                 elog(ERROR, "unrecognized A_Expr kind: \"%.*s\"", length, token);
     524   [ -  +  #  # ]:        2038 : 
     525                 :           0 :         READ_NODE_FIELD(lexpr);
     526   [ -  +  #  # ]:        2038 :         READ_NODE_FIELD(rexpr);
     527         [ #  # ]:           0 :         READ_LOCATION_FIELD(rexpr_list_start);
     528   [ -  +  #  #  :        2038 :         READ_LOCATION_FIELD(rexpr_list_end);
                   #  # ]
     529         [ #  # ]:           0 :         READ_LOCATION_FIELD(location);
     530   [ -  +  #  # ]:        2038 : 
     531                 :           0 :         READ_DONE();
     532   [ +  +  +  - ]:        2038 : }
     533                 :           0 : 
     534   [ -  +  #  # ]:        2038 : static ExtensibleNode *
     535                 :           0 : _readExtensibleNode(void)
     536   [ -  +  #  # ]:        2038 : {
     537                 :           0 :         const ExtensibleNodeMethods *methods;
     538   [ +  +  +  - ]:        2038 :         ExtensibleNode *local_node;
     539                 :           0 :         const char *extnodename;
     540   [ -  +  #  # ]:        2038 : 
     541                 :           0 :         READ_TEMP_LOCALS();
     542   [ -  +  #  # ]:        2038 : 
     543                 :           0 :         token = pg_strtok(&length); /* skip :extnodename */
     544   [ +  +  +  - ]:        2038 :         token = pg_strtok(&length); /* get extnodename */
     545                 :           0 : 
     546   [ +  +  +  - ]:        2038 :         extnodename = nullable_string(token, length);
     547         [ #  # ]:           0 :         if (!extnodename)
     548   [ +  +  +  -  :        2038 :                 elog(ERROR, "extnodename has to be supplied");
             #  #  #  # ]
     549                 :           0 :         methods = GetExtensibleNodeMethods(extnodename, false);
     550   [ +  +  +  - ]:        2038 : 
     551                 :           0 :         local_node = (ExtensibleNode *) newNode(methods->node_size,
     552   [ +  +  +  - ]:        2038 :                                                                                         T_ExtensibleNode);
     553                 :           0 :         local_node->extnodename = extnodename;
     554   [ +  +  -  + ]:        2038 : 
     555                 :         436 :         /* deserialize the private fields */
     556   [ +  +  +  + ]:        1602 :         methods->nodeRead(local_node);
     557                 :          22 : 
     558   [ +  +  -  + ]:        1580 :         READ_DONE();
     559                 :           3 : }
     560   [ -  +  #  # ]:        1577 : 
     561                 :           0 : 
     562   [ +  +  +  + ]:        1577 : /*
     563                 :          63 :  * parseNodeString
     564   [ -  +  #  # ]:        1514 :  *
     565                 :           0 :  * Given a character string representing a node tree, parseNodeString creates
     566   [ +  +  +  - ]:        1514 :  * the internal node structure.
     567                 :           0 :  *
     568   [ +  +  +  - ]:        1514 :  * The string to be read must already have been loaded into pg_strtok().
     569                 :           0 :  */
     570   [ +  +  +  - ]:        1514 : Node *
     571                 :      194998 : parseNodeString(void)
     572   [ +  +  +  + ]:        1514 : {
     573                 :      195602 :         READ_TEMP_LOCALS();
     574   [ -  +  #  # ]:         910 : 
     575                 :           0 :         /* Guard against stack overflow due to overly complex expressions */
     576   [ +  +  +  + ]:      195908 :         check_stack_depth();
     577                 :          66 : 
     578   [ +  +  +  + ]:      195842 :         token = pg_strtok(&length);
     579                 :          39 : 
     580   [ +  +  -  + ]:         805 : #define MATCH(tokname, namelen) \
     581                 :          45 :         (length == namelen && memcmp(token, tokname, namelen) == 0)
     582   [ +  +  -  + ]:         760 : 
     583                 :          45 : #include "readfuncs.switch.c"
     584   [ +  +  +  - ]:         715 : 
     585   [ #  #  #  # ]:           0 :         elog(ERROR, "badly formatted node string \"%.32s\"...", token);
     586   [ +  +  +  + ]:         715 :         return NULL;                            /* keep compiler quiet */
     587                 :      194998 : }
     588   [ +  +  +  - ]:         699 : 
     589                 :           0 : 
     590   [ +  +  -  + ]:         699 : /*
     591                 :           4 :  * readDatum
     592   [ -  +  #  # ]:         695 :  *
     593                 :           0 :  * Given a string representation of a constant, recreate the appropriate
     594   [ +  +  +  - ]:         695 :  * Datum.  The string representation embeds length info, but not byValue,
     595                 :           0 :  * so we must be told that.
     596   [ +  +  +  - ]:         695 :  */
     597                 :           0 : Datum
     598   [ -  +  #  # ]:       28922 : readDatum(bool typbyval)
     599                 :           0 : {
     600   [ +  +  +  - ]:       28922 :         Size            length;
     601                 :       28227 :         int                     tokenLength;
     602   [ -  +  #  # ]:       28922 :         const char *token;
     603                 :       28227 :         Datum           res;
     604   [ -  +  #  # ]:       28922 :         char       *s;
     605                 :           0 : 
     606   [ +  +  +  + ]:         695 :         /*
     607                 :           7 :          * read the actual length of the value
     608   [ +  +  -  + ]:         688 :          */
     609                 :       28234 :         token = pg_strtok(&tokenLength);
     610   [ +  +  -  + ]:       28908 :         length = atoui(token);
     611                 :           4 : 
     612   [ +  +  -  + ]:       28904 :         token = pg_strtok(&tokenLength);    /* read the '[' */
     613         [ +  - ]:       28321 :         if (token == NULL || token[0] != '[')
     614   [ -  +  #  #  :         583 :                 elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %zu",
          #  #  #  #  #  
                      # ]
     615                 :           0 :                          token ? token : "[NULL]", length);
     616   [ +  +  -  + ]:         583 : 
     617         [ +  + ]:       28229 :         if (typbyval)
     618   [ +  +  +  + ]:         581 :         {
     619         [ +  - ]:       20917 :                 if (length > (Size) sizeof(Datum))
     620   [ -  +  #  #  :         504 :                         elog(ERROR, "byval datum but length = %zu", length);
             #  #  #  # ]
     621                 :       20840 :                 res = (Datum) 0;
     622   [ -  +  #  # ]:       21344 :                 s = (char *) (&res);
     623         [ +  + ]:      187560 :                 for (Size i = 0; i < (Size) sizeof(Datum); i++)
     624   [ +  +  -  + ]:         504 :                 {
     625                 :      166995 :                         token = pg_strtok(&tokenLength);
     626   [ -  +  #  # ]:      166949 :                         s[i] = (char) atoi(token);
     627                 :      166720 :                 }
     628   [ +  +  -  + ]:       21069 :         }
     629         [ -  + ]:        7388 :         else if (length <= 0)
     630   [ -  +  #  # ]:         228 :                 res = (Datum) 0;
     631                 :           0 :         else
     632   [ -  +  #  # ]:         228 :         {
     633                 :        7387 :                 s = (char *) palloc(length);
     634   [ +  +  -  +  :      442188 :                 for (Size i = 0; i < length; i++)
                   +  + ]
     635                 :          94 :                 {
     636   [ -  +  #  # ]:      434707 :                         token = pg_strtok(&tokenLength);
     637                 :      434573 :                         s[i] = (char) atoi(token);
     638   [ -  +  #  # ]:      434707 :                 }
     639                 :        7387 :                 res = PointerGetDatum(s);
     640   [ -  +  #  # ]:         134 :         }
     641                 :           0 : 
     642   [ -  +  #  # ]:       28361 :         token = pg_strtok(&tokenLength);    /* read the ']' */
     643         [ +  - ]:       28227 :         if (token == NULL || token[0] != ']')
     644   [ +  +  -  +  :         134 :                 elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %zu",
          #  #  #  #  #  
                      # ]
     645                 :          21 :                          token ? token : "[NULL]", length);
     646   [ +  +  -  + ]:         113 : 
     647                 :       56520 :         return res;
     648   [ +  +  -  + ]:       28274 : }
     649                 :          37 : 
     650   [ +  -  -  + ]:          10 : /*
     651                 :          10 :  * common implementation for scalar-array-reading functions
     652   [ #  #  #  # ]:           0 :  *
     653                 :           0 :  * The data format is either "<>" for a NULL pointer (in which case numCols
     654   [ #  #  #  # ]:           0 :  * is ignored) or "(item item item)" where the number of items must equal
     655                 :           0 :  * numCols.  The convfunc must be okay with stopping at whitespace or a
     656   [ #  #  #  # ]:           0 :  * right parenthesis, since pg_strtok won't null-terminate the token.
     657                 :           0 :  */
     658         [ #  # ]:           0 : #define READ_SCALAR_ARRAY(fnname, datatype, convfunc) \
     659                 :           0 : datatype * \
     660                 :             : fnname(int numCols) \
     661                 :             : { \
     662                 :             :         datatype   *vals; \
     663                 :             :         READ_TEMP_LOCALS(); \
     664                 :             :         token = pg_strtok(&length); \
     665                 :             :         if (token == NULL) \
     666                 :             :                 elog(ERROR, "incomplete scalar array"); \
     667                 :             :         if (length == 0) \
     668                 :             :                 return NULL;                    /* it was "<>", so return NULL pointer */ \
     669                 :             :         if (length != 1 || token[0] != '(') \
     670                 :             :                 elog(ERROR, "unrecognized token: \"%.*s\"", length, token); \
     671                 :             :         vals = (datatype *) palloc(numCols * sizeof(datatype)); \
     672                 :             :         for (int i = 0; i < numCols; i++) \
     673                 :             :         { \
     674                 :             :                 token = pg_strtok(&length); \
     675                 :             :                 if (token == NULL || token[0] == ')') \
     676                 :             :                         elog(ERROR, "incomplete scalar array"); \
     677                 :             :                 vals[i] = convfunc(token); \
     678                 :             :         } \
     679                 :             :         token = pg_strtok(&length); \
     680                 :             :         if (token == NULL || length != 1 || token[0] != ')') \
     681                 :             :                 elog(ERROR, "incomplete scalar array"); \
     682                 :             :         return vals; \
     683                 :             : }
     684                 :             : 
     685                 :             : /*
     686                 :             :  * Note: these functions are exported in nodes.h for possible use by
     687                 :             :  * extensions, so don't mess too much with their names or API.
     688                 :             :  */
     689   [ +  -  #  #  :         572 : READ_SCALAR_ARRAY(readAttrNumberCols, int16, atoi)
          #  #  +  +  +  
          -  #  #  #  #  
          +  +  +  -  #  
          #  #  #  +  -  
             #  #  #  # ]
     690   [ +  -  #  #  :        1426 : READ_SCALAR_ARRAY(readOidCols, Oid, atooid)
          #  #  +  +  +  
          -  #  #  #  #  
          +  +  +  -  #  
          #  #  #  +  -  
             #  #  #  # ]
     691                 :             : /* outfuncs.c has writeIndexCols, but we don't yet need that here */
     692                 :             : /* READ_SCALAR_ARRAY(readIndexCols, Index, atoui) */
     693   [ +  -  #  #  :         774 : READ_SCALAR_ARRAY(readIntCols, int, atoi)
          #  #  +  -  +  
          -  #  #  #  #  
          +  +  +  -  #  
          #  #  #  +  -  
             #  #  #  # ]
     694   [ +  -  #  #  :         180 : READ_SCALAR_ARRAY(readBoolCols, bool, strtobool)
          #  #  +  -  +  
          -  #  #  #  #  
          +  +  +  -  #  
          #  #  #  +  -  
             #  #  #  # ]
        

Generated by: LCOV version 2.3.2-1