LCOV - differential code coverage report
Current view: top level - src/interfaces/ecpg/preproc - parser.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 92.0 % 88 81 7 81
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 3 3 3
Baseline: 16@8cea358b128 Branches: 66.0 % 53 35 18 35
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 92.0 % 88 81 7 81
Function coverage date bins:
(240..) days: 100.0 % 3 3 3
Branch coverage date bins:
(240..) days: 66.0 % 53 35 18 35

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * parser.c
                                  4                 :                :  *      Main entry point/driver for PostgreSQL grammar
                                  5                 :                :  *
                                  6                 :                :  * This should match src/backend/parser/parser.c, except that we do not
                                  7                 :                :  * need to bother with re-entrant interfaces.
                                  8                 :                :  *
                                  9                 :                :  * Note: ECPG doesn't report error location like the backend does.
                                 10                 :                :  * This file will need work if we ever want it to.
                                 11                 :                :  *
                                 12                 :                :  *
                                 13                 :                :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
                                 14                 :                :  * Portions Copyright (c) 1994, Regents of the University of California
                                 15                 :                :  *
                                 16                 :                :  * IDENTIFICATION
                                 17                 :                :  *    src/interfaces/ecpg/preproc/parser.c
                                 18                 :                :  *
                                 19                 :                :  *-------------------------------------------------------------------------
                                 20                 :                :  */
                                 21                 :                : 
                                 22                 :                : #include "postgres_fe.h"
                                 23                 :                : 
                                 24                 :                : #include "preproc_extern.h"
                                 25                 :                : #include "preproc.h"
                                 26                 :                : 
                                 27                 :                : 
                                 28                 :                : static bool have_lookahead;     /* is lookahead info valid? */
                                 29                 :                : static int  lookahead_token;    /* one-token lookahead */
                                 30                 :                : static YYSTYPE lookahead_yylval;    /* yylval for lookahead token */
                                 31                 :                : static YYLTYPE lookahead_yylloc;    /* yylloc for lookahead token */
                                 32                 :                : static char *lookahead_yytext;  /* start current token */
                                 33                 :                : 
                                 34                 :                : static bool check_uescapechar(unsigned char escape);
                                 35                 :                : static bool ecpg_isspace(char ch);
                                 36                 :                : 
                                 37                 :                : 
                                 38                 :                : /*
                                 39                 :                :  * Intermediate filter between parser and base lexer (base_yylex in scan.l).
                                 40                 :                :  *
                                 41                 :                :  * This filter is needed because in some cases the standard SQL grammar
                                 42                 :                :  * requires more than one token lookahead.  We reduce these cases to one-token
                                 43                 :                :  * lookahead by replacing tokens here, in order to keep the grammar LALR(1).
                                 44                 :                :  *
                                 45                 :                :  * Using a filter is simpler than trying to recognize multiword tokens
                                 46                 :                :  * directly in scan.l, because we'd have to allow for comments between the
                                 47                 :                :  * words.  Furthermore it's not clear how to do that without re-introducing
                                 48                 :                :  * scanner backtrack, which would cost more performance than this filter
                                 49                 :                :  * layer does.
                                 50                 :                :  *
                                 51                 :                :  * We also use this filter to convert UIDENT and USCONST sequences into
                                 52                 :                :  * plain IDENT and SCONST tokens.  While that could be handled by additional
                                 53                 :                :  * productions in the main grammar, it's more efficient to do it like this.
                                 54                 :                :  */
                                 55                 :                : int
 6015 tgl@sss.pgh.pa.us          56                 :CBC       35431 : filtered_base_yylex(void)
                                 57                 :                : {
                                 58                 :                :     int         cur_token;
                                 59                 :                :     int         next_token;
                                 60                 :                :     YYSTYPE     cur_yylval;
                                 61                 :                :     YYLTYPE     cur_yylloc;
                                 62                 :                :     char       *cur_yytext;
                                 63                 :                : 
                                 64                 :                :     /* Get next token --- we might already have it */
                                 65         [ +  + ]:          35431 :     if (have_lookahead)
                                 66                 :                :     {
                                 67                 :             57 :         cur_token = lookahead_token;
                                 68                 :             57 :         base_yylval = lookahead_yylval;
                                 69                 :             57 :         base_yylloc = lookahead_yylloc;
 2681                            70                 :             57 :         base_yytext = lookahead_yytext;
 6015                            71                 :             57 :         have_lookahead = false;
                                 72                 :                :     }
                                 73                 :                :     else
                                 74                 :          35374 :         cur_token = base_yylex();
                                 75                 :                : 
                                 76                 :                :     /*
                                 77                 :                :      * If this token isn't one that requires lookahead, just return it.
                                 78                 :                :      */
                                 79         [ +  + ]:          35431 :     switch (cur_token)
                                 80                 :                :     {
  382 alvherre@alvh.no-ip.       81                 :             58 :         case FORMAT:
                                 82                 :                :         case NOT:
                                 83                 :                :         case NULLS_P:
                                 84                 :                :         case WITH:
                                 85                 :                :         case WITHOUT:
                                 86                 :                :         case UIDENT:
                                 87                 :                :         case USCONST:
 3337 tgl@sss.pgh.pa.us          88                 :             58 :             break;
                                 89                 :          35373 :         default:
                                 90                 :          35373 :             return cur_token;
                                 91                 :                :     }
                                 92                 :                : 
                                 93                 :                :     /* Save and restore lexer output variables around the call */
                                 94                 :             58 :     cur_yylval = base_yylval;
                                 95                 :             58 :     cur_yylloc = base_yylloc;
 2681                            96                 :             58 :     cur_yytext = base_yytext;
                                 97                 :                : 
                                 98                 :                :     /* Get next token, saving outputs into lookahead variables */
 3337                            99                 :             58 :     next_token = base_yylex();
                                100                 :                : 
                                101                 :             58 :     lookahead_token = next_token;
                                102                 :             58 :     lookahead_yylval = base_yylval;
                                103                 :             58 :     lookahead_yylloc = base_yylloc;
 2681                           104                 :             58 :     lookahead_yytext = base_yytext;
                                105                 :                : 
 3337                           106                 :             58 :     base_yylval = cur_yylval;
                                107                 :             58 :     base_yylloc = cur_yylloc;
 2681                           108                 :             58 :     base_yytext = cur_yytext;
                                109                 :                : 
 3337                           110                 :             58 :     have_lookahead = true;
                                111                 :                : 
                                112                 :                :     /* Replace cur_token if needed, based on lookahead */
                                113   [ +  +  +  +  :             58 :     switch (cur_token)
                                           +  +  - ]
                                114                 :                :     {
  382 alvherre@alvh.no-ip.      115         [ +  - ]:              5 :         case FORMAT:
                                116                 :                :             /* Replace FORMAT by FORMAT_LA if it's followed by JSON */
                                117                 :                :             switch (next_token)
                                118                 :                :             {
                                119                 :              5 :                 case JSON:
                                120                 :              5 :                     cur_token = FORMAT_LA;
                                121                 :              5 :                     break;
                                122                 :                :             }
                                123                 :              5 :             break;
                                124                 :                : 
 3322 tgl@sss.pgh.pa.us         125         [ -  + ]:             36 :         case NOT:
                                126                 :                :             /* Replace NOT by NOT_LA if it's followed by BETWEEN, IN, etc */
                                127                 :                :             switch (next_token)
                                128                 :                :             {
 3322 tgl@sss.pgh.pa.us         129                 :UBC           0 :                 case BETWEEN:
                                130                 :                :                 case IN_P:
                                131                 :                :                 case LIKE:
                                132                 :                :                 case ILIKE:
                                133                 :                :                 case SIMILAR:
                                134                 :              0 :                     cur_token = NOT_LA;
                                135                 :              0 :                     break;
                                136                 :                :             }
 3322 tgl@sss.pgh.pa.us         137                 :CBC          36 :             break;
                                138                 :                : 
 3337                           139         [ +  - ]:              2 :         case NULLS_P:
                                140                 :                :             /* Replace NULLS_P by NULLS_LA if it's followed by FIRST or LAST */
                                141                 :                :             switch (next_token)
                                142                 :                :             {
 6015                           143                 :              2 :                 case FIRST_P:
                                144                 :                :                 case LAST_P:
 3337                           145                 :              2 :                     cur_token = NULLS_LA;
 6015                           146                 :              2 :                     break;
                                147                 :                :             }
                                148                 :              2 :             break;
                                149                 :                : 
                                150         [ +  + ]:              8 :         case WITH:
                                151                 :                :             /* Replace WITH by WITH_LA if it's followed by TIME or ORDINALITY */
                                152                 :                :             switch (next_token)
                                153                 :                :             {
 5647 peter_e@gmx.net           154                 :              1 :                 case TIME:
                                155                 :                :                 case ORDINALITY:
 3337 tgl@sss.pgh.pa.us         156                 :              1 :                     cur_token = WITH_LA;
 6015                           157                 :              1 :                     break;
                                158                 :                :             }
                                159                 :              8 :             break;
                                160                 :                : 
  382 alvherre@alvh.no-ip.      161         [ +  + ]:              4 :         case WITHOUT:
                                162                 :                :             /* Replace WITHOUT by WITHOUT_LA if it's followed by TIME */
                                163                 :                :             switch (next_token)
                                164                 :                :             {
  376                           165                 :              1 :                 case TIME:
  382                           166                 :              1 :                     cur_token = WITHOUT_LA;
                                167                 :              1 :                     break;
                                168                 :                :             }
                                169                 :              4 :             break;
 1553 tgl@sss.pgh.pa.us         170                 :              3 :         case UIDENT:
                                171                 :                :         case USCONST:
                                172                 :                :             /* Look ahead for UESCAPE */
                                173         [ +  + ]:              3 :             if (next_token == UESCAPE)
                                174                 :                :             {
                                175                 :                :                 /* Yup, so get third token, which had better be SCONST */
                                176                 :                :                 const char *escstr;
                                177                 :                : 
                                178                 :                :                 /*
                                179                 :                :                  * Again save and restore lexer output variables around the
                                180                 :                :                  * call
                                181                 :                :                  */
                                182                 :              1 :                 cur_yylval = base_yylval;
                                183                 :              1 :                 cur_yylloc = base_yylloc;
                                184                 :              1 :                 cur_yytext = base_yytext;
                                185                 :                : 
                                186                 :                :                 /* Get third token */
                                187                 :              1 :                 next_token = base_yylex();
                                188                 :                : 
                                189         [ -  + ]:              1 :                 if (next_token != SCONST)
 1553 tgl@sss.pgh.pa.us         190                 :UBC           0 :                     mmerror(PARSE_ERROR, ET_ERROR, "UESCAPE must be followed by a simple string literal");
                                191                 :                : 
                                192                 :                :                 /*
                                193                 :                :                  * Save and check escape string, which the scanner returns
                                194                 :                :                  * with quotes
                                195                 :                :                  */
 1553 tgl@sss.pgh.pa.us         196                 :CBC           1 :                 escstr = base_yylval.str;
                                197   [ +  -  -  + ]:              1 :                 if (strlen(escstr) != 3 || !check_uescapechar(escstr[1]))
 1553 tgl@sss.pgh.pa.us         198                 :UBC           0 :                     mmerror(PARSE_ERROR, ET_ERROR, "invalid Unicode escape character");
                                199                 :                : 
 1553 tgl@sss.pgh.pa.us         200                 :CBC           1 :                 base_yylval = cur_yylval;
                                201                 :              1 :                 base_yylloc = cur_yylloc;
                                202                 :              1 :                 base_yytext = cur_yytext;
                                203                 :                : 
                                204                 :                :                 /* Combine 3 tokens into 1 */
                                205                 :              1 :                 base_yylval.str = psprintf("%s UESCAPE %s", base_yylval.str, escstr);
                                206                 :                : 
                                207                 :                :                 /* Clear have_lookahead, thereby consuming all three tokens */
                                208                 :              1 :                 have_lookahead = false;
                                209                 :                :             }
                                210                 :                : 
                                211         [ +  + ]:              3 :             if (cur_token == UIDENT)
                                212                 :              1 :                 cur_token = IDENT;
                                213         [ +  - ]:              2 :             else if (cur_token == USCONST)
                                214                 :              2 :                 cur_token = SCONST;
                                215                 :              3 :             break;
                                216                 :                :     }
                                217                 :                : 
 6015                           218                 :             58 :     return cur_token;
                                219                 :                : }
                                220                 :                : 
                                221                 :                : /*
                                222                 :                :  * check_uescapechar() and ecpg_isspace() should match their equivalents
                                223                 :                :  * in pgc.l.
                                224                 :                :  */
                                225                 :                : 
                                226                 :                : /* is 'escape' acceptable as Unicode escape character (UESCAPE syntax) ? */
                                227                 :                : static bool
 1553                           228                 :              1 : check_uescapechar(unsigned char escape)
                                229                 :                : {
                                230         [ +  - ]:              1 :     if (isxdigit(escape)
                                231         [ +  - ]:              1 :         || escape == '+'
                                232         [ +  - ]:              1 :         || escape == '\''
                                233         [ +  - ]:              1 :         || escape == '"'
                                234         [ -  + ]:              1 :         || ecpg_isspace(escape))
 1553 tgl@sss.pgh.pa.us         235                 :UBC           0 :         return false;
                                236                 :                :     else
 1553 tgl@sss.pgh.pa.us         237                 :CBC           1 :         return true;
                                238                 :                : }
                                239                 :                : 
                                240                 :                : /*
                                241                 :                :  * ecpg_isspace() --- return true if flex scanner considers char whitespace
                                242                 :                :  */
                                243                 :                : static bool
                                244                 :              1 : ecpg_isspace(char ch)
                                245                 :                : {
                                246   [ +  -  +  - ]:              1 :     if (ch == ' ' ||
                                247         [ +  - ]:              1 :         ch == '\t' ||
                                248         [ +  - ]:              1 :         ch == '\n' ||
                                249         [ -  + ]:              1 :         ch == '\r' ||
                                250                 :                :         ch == '\f')
 1553 tgl@sss.pgh.pa.us         251                 :UBC           0 :         return true;
 1553 tgl@sss.pgh.pa.us         252                 :CBC           1 :     return false;
                                253                 :                : }
        

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