LCOV - differential code coverage report
Current view: top level - src/bin/pgbench - exprscan.l (source / functions) Coverage Total Hit UBC CBC
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 95.3 % 149 142 7 142
Current Date: 2025-09-06 07:49:51 +0900 Functions: 100.0 % 6 6 6
Baseline: lcov-20250906-005545-baseline Branches: 70.6 % 34 24 10 24
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(30,360] days: 100.0 % 8 8 8
(360..) days: 95.0 % 141 134 7 134
Function coverage date bins:
(30,360] days: 100.0 % 1 1 1
(360..) days: 100.0 % 5 5 5
Branch coverage date bins:
(30,360] days: 100.0 % 2 2 2
(360..) days: 68.8 % 32 22 10 22

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : %top{
                                  2                 :                : /*-------------------------------------------------------------------------
                                  3                 :                :  *
                                  4                 :                :  * exprscan.l
                                  5                 :                :  *    lexical scanner for pgbench backslash commands
                                  6                 :                :  *
                                  7                 :                :  * This lexer supports two operating modes:
                                  8                 :                :  *
                                  9                 :                :  * In INITIAL state, just parse off whitespace-separated words (this mode
                                 10                 :                :  * is basically equivalent to strtok(), which is what we used to use).
                                 11                 :                :  *
                                 12                 :                :  * In EXPR state, lex for the simple expression syntax of exprparse.y.
                                 13                 :                :  *
                                 14                 :                :  * In either mode, stop upon hitting newline or end of string.
                                 15                 :                :  *
                                 16                 :                :  * Note that this lexer operates within the framework created by psqlscan.l,
                                 17                 :                :  *
                                 18                 :                :  * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
                                 19                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                 20                 :                :  *
                                 21                 :                :  * src/bin/pgbench/exprscan.l
                                 22                 :                :  *
                                 23                 :                :  *-------------------------------------------------------------------------
                                 24                 :                :  */
                                 25                 :                : #include "postgres_fe.h"
                                 26                 :                : 
                                 27                 :                : /*
                                 28                 :                :  * NB: include exprparse.h only AFTER including pgbench.h, because pgbench.h
                                 29                 :                :  * contains definitions needed for YYSTYPE. Likewise, pgbench.h must come after
                                 30                 :                :  * psqlscan_int.h for yyscan_t.
                                 31                 :                :  */
                                 32                 :                : #include "fe_utils/psqlscan_int.h"
                                 33                 :                : #include "pgbench.h"
                                 34                 :                : #include "exprparse.h"
                                 35                 :                : }
                                 36                 :                : 
                                 37                 :                : %{
                                 38                 :                : /* context information for reporting errors in expressions */
                                 39                 :                : static const char *expr_source = NULL;
                                 40                 :                : static int  expr_lineno = 0;
                                 41                 :                : static int  expr_start_offset = 0;
                                 42                 :                : static const char *expr_command = NULL;
                                 43                 :                : 
                                 44                 :                : /* indicates whether last yylex() call read a newline */
                                 45                 :                : static bool last_was_newline = false;
                                 46                 :                : 
                                 47                 :                : /* LCOV_EXCL_START */
                                 48                 :                : 
                                 49                 :                : %}
                                 50                 :                : 
                                 51                 :                : /* Except for the prefix, these options should match psqlscan.l */
                                 52                 :                : %option reentrant
                                 53                 :                : %option bison-bridge
                                 54                 :                : %option 8bit
                                 55                 :                : %option never-interactive
                                 56                 :                : %option nodefault
                                 57                 :                : %option noinput
                                 58                 :                : %option nounput
                                 59                 :                : %option noyywrap
                                 60                 :                : %option warn
                                 61                 :                : %option prefix="expr_yy"
                                 62                 :                : 
                                 63                 :                : /* Character classes */
                                 64                 :                : alpha           [a-zA-Z\200-\377_]
                                 65                 :                : digit           [0-9]
                                 66                 :                : alnum           [A-Za-z\200-\377_0-9]
                                 67                 :                : /* {space} + {nonspace} + {newline} should cover all characters */
                                 68                 :                : space           [ \t\r\f\v]
                                 69                 :                : nonspace        [^ \t\r\f\v\n]
                                 70                 :                : newline         [\n]
                                 71                 :                : 
                                 72                 :                : /* Line continuation marker */
                                 73                 :                : continuation    \\\r?{newline}
                                 74                 :                : 
                                 75                 :                : /* case insensitive keywords */
                                 76                 :                : and             [Aa][Nn][Dd]
                                 77                 :                : or              [Oo][Rr]
                                 78                 :                : not             [Nn][Oo][Tt]
                                 79                 :                : case            [Cc][Aa][Ss][Ee]
                                 80                 :                : when            [Ww][Hh][Ee][Nn]
                                 81                 :                : then            [Tt][Hh][Ee][Nn]
                                 82                 :                : else            [Ee][Ll][Ss][Ee]
                                 83                 :                : end             [Ee][Nn][Dd]
                                 84                 :                : true            [Tt][Rr][Uu][Ee]
                                 85                 :                : false           [Ff][Aa][Ll][Ss][Ee]
                                 86                 :                : null            [Nn][Uu][Ll][Ll]
                                 87                 :                : is              [Ii][Ss]
                                 88                 :                : isnull          [Ii][Ss][Nn][Uu][Ll][Ll]
                                 89                 :                : notnull         [Nn][Oo][Tt][Nn][Uu][Ll][Ll]
                                 90                 :                : 
                                 91                 :                : /* Exclusive states */
                                 92                 :                : %x EXPR
                                 93                 :                : 
                                 94                 :                : %%
                                 95                 :                : 
                                 96                 :                : %{
                                 97                 :                :         /* Declare some local variables inside yylex(), for convenience */
                                 98                 :                :         PsqlScanState cur_state = yyextra;
 3457 tgl@sss.pgh.pa.us          99                 :CBC        5107 : 
                                100                 :                :         /*
                                101                 :                :          * Force flex into the state indicated by start_state.  This has a
                                102                 :                :          * couple of purposes: it lets some of the functions below set a new
                                103                 :                :          * starting state without ugly direct access to flex variables, and it
                                104                 :                :          * allows us to transition from one flex lexer to another so that we
                                105                 :                :          * can lex different parts of the source string using separate lexers.
                                106                 :                :          */
                                107                 :                :         BEGIN(cur_state->start_state);
                                108                 :           5107 : 
                                109                 :                :         /* Reset was-newline flag */
                                110                 :                :         last_was_newline = false;
 3458                           111                 :           5107 : %}
                                112                 :                : 
                                113                 :                :     /* INITIAL state */
                                114                 :                : 
                                115                 :                : {nonspace}+     {
                                116                 :                :                     /* Found a word, emit and return it */
                                117                 :                :                     psqlscan_emit(cur_state, yytext, yyleng);
 3457                           118                 :           1185 :                     return 1;
                                119                 :           1185 :                 }
                                120                 :                : 
                                121                 :                :     /*
                                122                 :                :      * We need this rule to avoid returning "word\" instead of recognizing
                                123                 :                :      * a continuation marker just after a word:
                                124                 :                :      */
                                125                 :                : {nonspace}+{continuation}   {
 2546                           126                 :              1 :                     /* Found "word\\\r?\n", emit and return just "word" */
                                127                 :                :                     int     wordlen = yyleng - 2;
                                128                 :              1 :                     if (yytext[wordlen] == '\r')
                                129         [ -  + ]:              1 :                         wordlen--;
 2546 tgl@sss.pgh.pa.us         130                 :UBC           0 :                     Assert(yytext[wordlen] == '\\');
 2546 tgl@sss.pgh.pa.us         131         [ -  + ]:CBC           1 :                     psqlscan_emit(cur_state, yytext, wordlen);
 3151                           132                 :              1 :                     return 1;
                                133                 :              1 :                 }
                                134                 :                : 
                                135                 :                : {space}+        { /* ignore */ }
 3457                           136                 :            655 : 
 3151                           137                 :            655 : {continuation}  { /* ignore */ }
                                138                 :              1 : 
 3457                           139                 :              1 : {newline}       {
                                140                 :            108 :                     /* report end of command */
                                141                 :                :                     last_was_newline = true;
                                142                 :            108 :                     return 0;
                                143                 :            108 :                 }
                                144                 :                : 
                                145                 :                :     /* EXPR state */
                                146                 :                : 
                                147                 :                : <EXPR>{
                                148                 :             53 : 
                                149                 :                : "+"               { return '+'; }
                                150                 :             53 : "-"               { return '-'; }
                                151                 :             65 : "*"               { return '*'; }
                                152                 :             65 : "/"               { return '/'; }
 2797 teodor@sigaev.ru          153                 :            204 : "%"               { return '%'; } /* C version, also in Pg SQL */
                                154                 :             13 : "="               { return '='; }
                                155                 :              2 : "<>"            { return NE_OP; }
                                156                 :             32 : "!="          { return NE_OP; } /* C version, also in Pg SQL */
                                157                 :              5 : "<="           { return LE_OP; }
                                158                 :              3 : ">="           { return GE_OP; }
                                159                 :              4 : "<<"            { return LS_OP; }
                                160                 :              3 : ">>"            { return RS_OP; }
                                161                 :              7 : "<"                { return '<'; }
                                162                 :              1 : ">"                { return '>'; }
                                163                 :             10 : "|"               { return '|'; }
                                164                 :              6 : "&"               { return '&'; }
                                165                 :              2 : "#"               { return '#'; }
                                166                 :              1 : "~"               { return '~'; }
                                167                 :              1 : 
 3457 tgl@sss.pgh.pa.us         168                 :              2 : "("               { return '('; }
                                169                 :            451 : ")"               { return ')'; }
                                170                 :            453 : ","               { return ','; }
 3814                           171                 :            453 : 
 2797 teodor@sigaev.ru          172                 :            343 : {and}           { return AND_OP; }
                                173                 :             44 : {or}            { return OR_OP; }
                                174                 :              5 : {not}           { return NOT_OP; }
                                175                 :              5 : {is}            { return IS_OP; }
                                176                 :             15 : {isnull}        { return ISNULL_OP; }
                                177                 :              8 : {notnull}       { return NOTNULL_OP; }
                                178                 :              1 : 
                                179                 :              1 : {case}          { return CASE_KW; }
                                180                 :             15 : {when}          { return WHEN_KW; }
                                181                 :             16 : {then}          { return THEN_KW; }
                                182                 :             16 : {else}          { return ELSE_KW; }
                                183                 :             17 : {end}           { return END_KW; }
                                184                 :             11 : 
 3471 tgl@sss.pgh.pa.us         185                 :             15 : :{alnum}+       {
 3457                           186                 :            272 :                     yylval->str = pg_strdup(yytext + 1);
 3814                           187                 :            272 :                     return VARIABLE;
                                188                 :            272 :                 }
                                189                 :                : 
                                190                 :                : {null}          { return NULL_CONST; }
 2797 teodor@sigaev.ru          191                 :             12 : {true}          {
                                192                 :                :                     yylval->bval = true;
                                193                 :             21 :                     return BOOLEAN_CONST;
                                194                 :             21 :                 }
                                195                 :                : {false}         {
                                196                 :                :                     yylval->bval = false;
                                197                 :             13 :                     return BOOLEAN_CONST;
                                198                 :             13 :                 }
                                199                 :                : "9223372036854775808" {
                                200                 :                :                     /*
 2536 andres@anarazel.de        201                 :              1 :                      * Special handling for PG_INT64_MIN, which can't
                                202                 :                :                      * accurately be represented here, as the minus sign is
                                203                 :                :                      * lexed separately and INT64_MIN can't be represented as
                                204                 :                :                      * a positive integer.
                                205                 :                :                      */
                                206                 :                :                     return MAXINT_PLUS_ONE_CONST;
                                207                 :              1 :                 }
                                208                 :                : {digit}+        {
                                209                 :                :                     if (!strtoint64(yytext, true, &yylval->ival))
                                210         [ +  + ]:            797 :                         expr_yyerror_more(yyscanner, "bigint constant overflow",
                                211                 :              1 :                                           strdup(yytext));
 3448 tgl@sss.pgh.pa.us         212                 :              1 :                     return INTEGER_CONST;
 3814                           213                 :            796 :                 }
                                214                 :                : {digit}+(\.{digit}*)?([eE][-+]?{digit}+)?   {
                                215                 :                :                     if (!strtodouble(yytext, true, &yylval->dval))
 2536 andres@anarazel.de        216         [ +  + ]:             61 :                         expr_yyerror_more(yyscanner, "double constant overflow",
                                217                 :              1 :                                           strdup(yytext));
 3448 tgl@sss.pgh.pa.us         218                 :              1 :                     return DOUBLE_CONST;
                                219                 :             60 :                 }
                                220                 :                : \.{digit}+([eE][-+]?{digit}+)?  {
                                221                 :                :                     if (!strtodouble(yytext, true, &yylval->dval))
 2536 andres@anarazel.de        222         [ +  + ]:              2 :                         expr_yyerror_more(yyscanner, "double constant overflow",
                                223                 :              1 :                                           strdup(yytext));
 3448 tgl@sss.pgh.pa.us         224                 :              1 :                     return DOUBLE_CONST;
 3449 rhaas@postgresql.org      225                 :              1 :                 }
                                226                 :                : {alpha}{alnum}* {
                                227                 :                :                     yylval->str = pg_strdup(yytext);
 3476                           228                 :            399 :                     return FUNCTION;
                                229                 :            399 :                 }
                                230                 :                : 
                                231                 :                : {space}+        { /* ignore */ }
 3151 tgl@sss.pgh.pa.us         232                 :           1656 : 
                                233                 :           1656 : {continuation}  { /* ignore */ }
                                234                 :             17 : 
 3457                           235                 :             17 : {newline}       {
                                236                 :            368 :                     /* report end of command */
                                237                 :                :                     last_was_newline = true;
                                238                 :            368 :                     return 0;
                                239                 :            368 :                 }
                                240                 :                : 
                                241                 :                : .               {
                                242                 :              1 :                     /*
                                243                 :                :                      * must strdup yytext so that expr_yyerror_more doesn't
                                244                 :                :                      * change it while finding end of line
                                245                 :                :                      */
                                246                 :                :                     expr_yyerror_more(yyscanner, "unexpected character",
                                247                 :              1 :                                       pg_strdup(yytext));
                                248                 :              1 :                     /* NOTREACHED, syntax_error calls exit() */
                                249                 :                :                     return 0;
                                250                 :                :                 }
                                251                 :                : 
                                252                 :                : }
                                253                 :                : 
                                254                 :             57 : <<EOF>>         {
                                255                 :                :                     if (cur_state->buffer_stack == NULL)
                                256         [ +  - ]:             57 :                         return 0;           /* end of input reached */
                                257                 :             57 : 
                                258                 :                :                     /*
                                259                 :                :                      * We were expanding a variable, so pop the inclusion
                                260                 :                :                      * stack and keep lexing
                                261                 :                :                      */
                                262                 :                :                     psqlscan_pop_buffer_stack(cur_state);
 3457 tgl@sss.pgh.pa.us         263                 :UBC           0 :                     psqlscan_select_top_buffer(cur_state);
                                264                 :              0 :                 }
                                265                 :                : 
 3841 rhaas@postgresql.org      266                 :              0 : %%
                                267                 :              0 : 
                                268                 :                : /* LCOV_EXCL_STOP */
                                269                 :                : 
                                270                 :                : void
                                271                 :                : expr_yyerror_more(yyscan_t yyscanner, const char *message, const char *more)
 3841 rhaas@postgresql.org      272                 :CBC          19 : {
                                273                 :                :     PsqlScanState state = yyget_extra(yyscanner);
  191 tgl@sss.pgh.pa.us         274                 :             19 :     int         lineno;
                                275                 :                :     int         error_detection_offset;
                                276                 :                :     YYSTYPE     lval;
                                277                 :                :     char       *full_line;
                                278                 :                : 
                                279                 :                :     psql_scan_get_location(state, &lineno, &error_detection_offset);
                                280                 :             19 :     error_detection_offset--;
                                281                 :             19 : 
                                282                 :                :     /*
                                283                 :                :      * While parsing an expression, we may not have collected the whole line
                                284                 :                :      * yet from the input source.  Lex till EOL so we can report whole line.
                                285                 :                :      * (If we're at EOF, it's okay to call yylex() an extra time.)
                                286                 :                :      */
                                287                 :                :     if (!last_was_newline)
 3457                           288         [ +  + ]:             19 :     {
                                289                 :                :         while (yylex(&lval, yyscanner))
                                290         [ +  + ]:             25 :              /* skip */ ;
                                291                 :                :     }
                                292                 :                : 
                                293                 :                :     /* Extract the line, trimming trailing newline if any */
                                294                 :                :     full_line = expr_scanner_get_substring(state,
                                295                 :             19 :                                            expr_start_offset,
                                296                 :                :                                            true);
                                297                 :                : 
                                298                 :                :     syntax_error(expr_source, expr_lineno, full_line, expr_command,
                                299                 :             19 :                  message, more, error_detection_offset - expr_start_offset);
                                300                 :                : }
                                301                 :                : 
                                302                 :                : /*
                                303                 :                :  * (The first argument is enforced by Bison to match the first argument of
                                304                 :                :  * yyparse(), but it is not used here.)
                                305                 :                :  */
                                306                 :                : void
                                307                 :                : expr_yyerror(PgBenchExpr **expr_parse_result_p, yyscan_t yyscanner, const char *message)
 3476 rhaas@postgresql.org      308                 :              6 : {
                                309                 :                :     expr_yyerror_more(yyscanner, message, NULL);
 3841                           310                 :              6 : }
                                311                 :                : 
                                312                 :                : /*
                                313                 :                :  * Collect a space-separated word from a backslash command and return it
                                314                 :                :  * in word_buf, along with its starting string offset in *offset.
                                315                 :                :  * Returns true if successful, false if at end of command.
                                316                 :                :  */
                                317                 :                : bool
                                318                 :                : expr_lex_one_word(PsqlScanState state, PQExpBuffer word_buf, int *offset)
                                319                 :           1318 : {
                                320                 :                :     int         lexresult;
                                321                 :                :     YYSTYPE     lval;
                                322                 :                : 
                                323                 :                :     /* Must be scanning already */
                                324                 :                :     Assert(state->scanbufhandle != NULL);
 3458 tgl@sss.pgh.pa.us         325         [ -  + ]:           1318 : 
                                326                 :                :     /* Set current output target */
                                327                 :                :     state->output_buf = word_buf;
 3457                           328                 :           1318 :     resetPQExpBuffer(word_buf);
                                329                 :           1318 : 
                                330                 :                :     /* Set input source */
                                331                 :                :     if (state->buffer_stack != NULL)
                                332         [ -  + ]:           1318 :         yy_switch_to_buffer(state->buffer_stack->buf, state->scanner);
 3457 tgl@sss.pgh.pa.us         333                 :UBC           0 :     else
                                334                 :                :         yy_switch_to_buffer(state->scanbufhandle, state->scanner);
 3810 rhaas@postgresql.org      335                 :CBC        1318 : 
                                336                 :                :     /* Set start state */
                                337                 :                :     state->start_state = INITIAL;
 3457 tgl@sss.pgh.pa.us         338                 :           1318 : 
                                339                 :                :     /* And lex. */
                                340                 :                :     lexresult = yylex(&lval, state->scanner);
 3476 rhaas@postgresql.org      341                 :           1318 : 
                                342                 :                :     /* Save start offset of word, if any. */
                                343                 :                :     if (lexresult)
  191 tgl@sss.pgh.pa.us         344         [ +  + ]:           1318 :     {
                                345                 :                :         int         lineno;
                                346                 :                :         int         end_offset;
                                347                 :                : 
                                348                 :                :         psql_scan_get_location(state, &lineno, &end_offset);
                                349                 :           1186 :         *offset = end_offset - word_buf->len;
                                350                 :           1186 :     }
                                351                 :                :     else
                                352                 :                :         *offset = -1;
 3841 rhaas@postgresql.org      353                 :            132 : 
                                354                 :                :     /*
                                355                 :                :      * In case the caller returns to using the regular SQL lexer, reselect the
                                356                 :                :      * appropriate initial state.
                                357                 :                :      */
                                358                 :                :     psql_scan_reselect_sql_lexer(state);
 3457 tgl@sss.pgh.pa.us         359                 :           1318 : 
                                360                 :                :     return (bool) lexresult;
 3841 rhaas@postgresql.org      361                 :           1318 : }
                                362                 :                : 
                                363                 :                : /*
                                364                 :                :  * Prepare to lex an expression via expr_yyparse().
                                365                 :                :  *
                                366                 :                :  * Returns the yyscan_t that is to be passed to expr_yyparse().
                                367                 :                :  * (This is just state->scanner, but callers don't need to know that.)
                                368                 :                :  */
                                369                 :                : yyscan_t
                                370                 :                : expr_scanner_init(PsqlScanState state,
 3457 tgl@sss.pgh.pa.us         371                 :            399 :                   const char *source, int lineno, int start_offset,
                                372                 :                :                   const char *command)
                                373                 :                : {
                                374                 :                :     /* Save error context info */
                                375                 :                :     expr_source = source;
                                376                 :            399 :     expr_lineno = lineno;
                                377                 :            399 :     expr_start_offset = start_offset;
                                378                 :            399 :     expr_command = command;
                                379                 :            399 : 
                                380                 :                :     /* Must be scanning already */
                                381                 :                :     Assert(state->scanbufhandle != NULL);
                                382         [ -  + ]:            399 : 
                                383                 :                :     /* Set current output target */
                                384                 :                :     state->output_buf = NULL;
                                385                 :            399 : 
                                386                 :                :     /* Set input source */
                                387                 :                :     if (state->buffer_stack != NULL)
                                388         [ -  + ]:            399 :         yy_switch_to_buffer(state->buffer_stack->buf, state->scanner);
 3457 tgl@sss.pgh.pa.us         389                 :UBC           0 :     else
                                390                 :                :         yy_switch_to_buffer(state->scanbufhandle, state->scanner);
 3457 tgl@sss.pgh.pa.us         391                 :CBC         399 : 
                                392                 :                :     /* Set start state */
                                393                 :                :     state->start_state = EXPR;
                                394                 :            399 : 
                                395                 :                :     return state->scanner;
                                396                 :            399 : }
                                397                 :                : 
                                398                 :                : /*
                                399                 :                :  * Finish lexing an expression.
                                400                 :                :  */
                                401                 :                : void
                                402                 :                : expr_scanner_finish(yyscan_t yyscanner)
 3841 rhaas@postgresql.org      403                 :            380 : {
                                404                 :                :     PsqlScanState state = yyget_extra(yyscanner);
 3457 tgl@sss.pgh.pa.us         405                 :            380 : 
                                406                 :                :     /*
                                407                 :                :      * Reselect appropriate initial state for SQL lexer.
                                408                 :                :      */
                                409                 :                :     psql_scan_reselect_sql_lexer(state);
                                410                 :            380 : }
                                411                 :            380 : 
                                412                 :                : /*
                                413                 :                :  * Get a malloc'd copy of the lexer input string from start_offset
                                414                 :                :  * to end of current lexer token.  If chomp is true, drop any trailing
                                415                 :                :  * newline(s).
                                416                 :                :  *
                                417                 :                :  * We rely on the knowledge that flex modifies the scan buffer by storing
                                418                 :                :  * a NUL at the end of the current token (yytext).  Note that this might
                                419                 :                :  * not work quite right if we were parsing a sub-buffer, but since pgbench
                                420                 :                :  * never invokes that functionality, it doesn't matter.  Also, this will
                                421                 :                :  * give the wrong answer (the whole remainder of the input) if called
                                422                 :                :  * before any yylex() call has been done.
                                423                 :                :  */
                                424                 :                : char *
                                425                 :                : expr_scanner_get_substring(PsqlScanState state,
  191                           426                 :            530 :                            int start_offset,
                                427                 :                :                            bool chomp)
                                428                 :                : {
                                429                 :                :     char       *result;
                                430                 :                :     const char *scanptr = state->scanbuf + start_offset;
                                431                 :            530 :     size_t      slen = strlen(scanptr);
 2924                           432                 :            530 : 
                                433                 :                :     if (chomp)
                                434         [ +  - ]:            530 :     {
                                435                 :                :         while (slen > 0 &&
                                436         [ +  - ]:           1006 :                (scanptr[slen - 1] == '\n' || scanptr[slen - 1] == '\r'))
                                437   [ +  +  -  + ]:           1006 :             slen--;
                                438                 :            476 :     }
                                439                 :                : 
                                440                 :                :     result = (char *) pg_malloc(slen + 1);
                                441                 :            530 :     memcpy(result, scanptr, slen);
 3457                           442                 :            530 :     result[slen] = '\0';
                                443                 :            530 : 
                                444                 :                :     return result;
                                445                 :            530 : }
                                446                 :                : /* END: function "expr_scanner_get_substring" */
        

Generated by: LCOV version 2.4-beta