LCOV - code coverage report
Current view: top level - src/backend/replication - repl_gram.y Coverage Total Hit
Test: PostgreSQL 20devel Lines: 74.8 % 115 86
Test Date: 2026-07-03 19:57:34 Functions: - 0 0
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 25.0 % 8 2

             Branch data     Line data    Source code
       1                 :             : %{
       2                 :             : /*-------------------------------------------------------------------------
       3                 :             :  *
       4                 :             :  * repl_gram.y              - Parser for the replication commands
       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/replication/repl_gram.y
      12                 :             :  *
      13                 :             :  *-------------------------------------------------------------------------
      14                 :             :  */
      15                 :             : 
      16                 :             : #include "postgres.h"
      17                 :             : 
      18                 :             : #include "access/xlogdefs.h"
      19                 :             : #include "nodes/makefuncs.h"
      20                 :             : #include "nodes/parsenodes.h"
      21                 :             : #include "nodes/replnodes.h"
      22                 :             : #include "replication/walsender.h"
      23                 :             : #include "replication/walsender_private.h"
      24                 :             : 
      25                 :             : #include "repl_gram.h"
      26                 :             : 
      27                 :             : 
      28                 :             : /*
      29                 :             :  * Bison doesn't allocate anything that needs to live across parser calls,
      30                 :             :  * so we can easily have it use palloc instead of malloc.  This prevents
      31                 :             :  * memory leaks if we error out during parsing.
      32                 :             :  */
      33                 :             : #define YYMALLOC palloc
      34                 :             : #define YYFREE   pfree
      35                 :             : 
      36                 :             : %}
      37                 :             : 
      38                 :             : %parse-param {Node **replication_parse_result_p}
      39                 :             : %parse-param {yyscan_t yyscanner}
      40                 :             : %lex-param   {yyscan_t yyscanner}
      41                 :             : %pure-parser
      42                 :             : %expect 0
      43                 :             : %name-prefix="replication_yy"
      44                 :             : 
      45                 :             : %union
      46                 :             : {
      47                 :             :     char       *str;
      48                 :             :     bool        boolval;
      49                 :             :     uint32      uintval;
      50                 :             :     XLogRecPtr  recptr;
      51                 :             :     Node       *node;
      52                 :             :     List       *list;
      53                 :             :     DefElem    *defelt;
      54                 :             : }
      55                 :             : 
      56                 :             : /* Non-keyword tokens */
      57                 :             : %token <str> SCONST IDENT
      58                 :             : %token <uintval> UCONST
      59                 :             : %token <recptr> RECPTR
      60                 :             : 
      61                 :             : /* Keyword tokens. */
      62                 :             : %token K_BASE_BACKUP
      63                 :             : %token K_IDENTIFY_SYSTEM
      64                 :             : %token K_READ_REPLICATION_SLOT
      65                 :             : %token K_SHOW
      66                 :             : %token K_START_REPLICATION
      67                 :             : %token K_CREATE_REPLICATION_SLOT
      68                 :             : %token K_DROP_REPLICATION_SLOT
      69                 :             : %token K_ALTER_REPLICATION_SLOT
      70                 :             : %token K_TIMELINE_HISTORY
      71                 :             : %token K_WAIT
      72                 :             : %token K_TIMELINE
      73                 :             : %token K_PHYSICAL
      74                 :             : %token K_LOGICAL
      75                 :             : %token K_SLOT
      76                 :             : %token K_RESERVE_WAL
      77                 :             : %token K_TEMPORARY
      78                 :             : %token K_TWO_PHASE
      79                 :             : %token K_EXPORT_SNAPSHOT
      80                 :             : %token K_NOEXPORT_SNAPSHOT
      81                 :             : %token K_USE_SNAPSHOT
      82                 :             : %token K_UPLOAD_MANIFEST
      83                 :             : 
      84                 :             : %type <node>  command
      85                 :             : %type <node>  base_backup start_replication start_logical_replication
      86                 :             :                 create_replication_slot drop_replication_slot
      87                 :             :                 alter_replication_slot identify_system read_replication_slot
      88                 :             :                 timeline_history show upload_manifest
      89                 :             : %type <list>  generic_option_list
      90                 :             : %type <defelt>    generic_option
      91                 :             : %type <uintval>   opt_timeline
      92                 :             : %type <list>  plugin_options plugin_opt_list
      93                 :             : %type <defelt>    plugin_opt_elem
      94                 :             : %type <node>  plugin_opt_arg
      95                 :             : %type <str>       opt_slot var_name ident_or_keyword
      96                 :             : %type <boolval>   opt_temporary
      97                 :             : %type <list>  create_slot_options create_slot_legacy_opt_list
      98                 :             : %type <defelt>    create_slot_legacy_opt
      99                 :             : 
     100                 :             : %%
     101                 :             : 
     102                 :             : firstcmd: command opt_semicolon
     103                 :             :                 {
     104                 :        3231 :                     *replication_parse_result_p = $1;
     105                 :             : 
     106                 :             :                     (void) yynerrs; /* suppress compiler warning */
     107                 :             :                 }
     108                 :             :             ;
     109                 :             : 
     110                 :             : opt_semicolon:  ';'
     111                 :             :                 | /* EMPTY */
     112                 :             :                 ;
     113                 :             : 
     114                 :             : command:
     115                 :             :             identify_system
     116                 :             :             | base_backup
     117                 :             :             | start_replication
     118                 :             :             | start_logical_replication
     119                 :             :             | create_replication_slot
     120                 :             :             | drop_replication_slot
     121                 :             :             | alter_replication_slot
     122                 :             :             | read_replication_slot
     123                 :             :             | timeline_history
     124                 :             :             | show
     125                 :             :             | upload_manifest
     126                 :             :             ;
     127                 :             : 
     128                 :             : /*
     129                 :             :  * IDENTIFY_SYSTEM
     130                 :             :  */
     131                 :             : identify_system:
     132                 :             :             K_IDENTIFY_SYSTEM
     133                 :             :                 {
     134                 :         800 :                     $$ = (Node *) makeNode(IdentifySystemCmd);
     135                 :             :                 }
     136                 :             :             ;
     137                 :             : 
     138                 :             : /*
     139                 :             :  * READ_REPLICATION_SLOT %s
     140                 :             :  */
     141                 :             : read_replication_slot:
     142                 :             :             K_READ_REPLICATION_SLOT var_name
     143                 :             :                 {
     144                 :           6 :                     ReadReplicationSlotCmd *n = makeNode(ReadReplicationSlotCmd);
     145                 :           6 :                     n->slotname = $2;
     146                 :           6 :                     $$ = (Node *) n;
     147                 :             :                 }
     148                 :             :             ;
     149                 :             : 
     150                 :             : /*
     151                 :             :  * SHOW setting
     152                 :             :  */
     153                 :             : show:
     154                 :             :             K_SHOW var_name
     155                 :             :                 {
     156                 :         626 :                     VariableShowStmt *n = makeNode(VariableShowStmt);
     157                 :         626 :                     n->name = $2;
     158                 :         626 :                     $$ = (Node *) n;
     159                 :             :                 }
     160                 :             : 
     161                 :         632 : var_name:   IDENT   { $$ = $1; }
     162                 :             :             | var_name '.' IDENT
     163                 :           0 :                 { $$ = psprintf("%s.%s", $1, $3); }
     164                 :             :         ;
     165                 :             : 
     166                 :             : /*
     167                 :             :  * BASE_BACKUP [ ( option [ 'value' ] [, ...] ) ]
     168                 :             :  */
     169                 :             : base_backup:
     170                 :             :             K_BASE_BACKUP '(' generic_option_list ')'
     171                 :             :                 {
     172                 :         196 :                     BaseBackupCmd *cmd = makeNode(BaseBackupCmd);
     173                 :         196 :                     cmd->options = $3;
     174                 :         196 :                     $$ = (Node *) cmd;
     175                 :             :                 }
     176                 :             :             | K_BASE_BACKUP
     177                 :             :                 {
     178                 :           1 :                     BaseBackupCmd *cmd = makeNode(BaseBackupCmd);
     179                 :           1 :                     $$ = (Node *) cmd;
     180                 :             :                 }
     181                 :             :             ;
     182                 :             : 
     183                 :             : create_replication_slot:
     184                 :             :             /* CREATE_REPLICATION_SLOT slot [TEMPORARY] PHYSICAL [options] */
     185                 :             :             K_CREATE_REPLICATION_SLOT IDENT opt_temporary K_PHYSICAL create_slot_options
     186                 :             :                 {
     187                 :             :                     CreateReplicationSlotCmd *cmd;
     188                 :         153 :                     cmd = makeNode(CreateReplicationSlotCmd);
     189                 :         153 :                     cmd->kind = REPLICATION_KIND_PHYSICAL;
     190                 :         153 :                     cmd->slotname = $2;
     191                 :         153 :                     cmd->temporary = $3;
     192                 :         153 :                     cmd->options = $5;
     193                 :         153 :                     $$ = (Node *) cmd;
     194                 :             :                 }
     195                 :             :             /* CREATE_REPLICATION_SLOT slot [TEMPORARY] LOGICAL plugin [options] */
     196                 :             :             | K_CREATE_REPLICATION_SLOT IDENT opt_temporary K_LOGICAL IDENT create_slot_options
     197                 :             :                 {
     198                 :             :                     CreateReplicationSlotCmd *cmd;
     199                 :         364 :                     cmd = makeNode(CreateReplicationSlotCmd);
     200                 :         364 :                     cmd->kind = REPLICATION_KIND_LOGICAL;
     201                 :         364 :                     cmd->slotname = $2;
     202                 :         364 :                     cmd->temporary = $3;
     203                 :         364 :                     cmd->plugin = $5;
     204                 :         364 :                     cmd->options = $6;
     205                 :         364 :                     $$ = (Node *) cmd;
     206                 :             :                 }
     207                 :             :             ;
     208                 :             : 
     209                 :             : create_slot_options:
     210                 :         515 :             '(' generic_option_list ')'         { $$ = $2; }
     211                 :           2 :             | create_slot_legacy_opt_list       { $$ = $1; }
     212                 :             :             ;
     213                 :             : 
     214                 :             : create_slot_legacy_opt_list:
     215                 :             :             create_slot_legacy_opt_list create_slot_legacy_opt
     216                 :           1 :                 { $$ = lappend($1, $2); }
     217                 :             :             | /* EMPTY */
     218                 :           2 :                 { $$ = NIL; }
     219                 :             :             ;
     220                 :             : 
     221                 :             : create_slot_legacy_opt:
     222                 :             :             K_EXPORT_SNAPSHOT
     223                 :             :                 {
     224                 :           0 :                   $$ = makeDefElem("snapshot",
     225                 :           0 :                                    (Node *) makeString("export"), -1);
     226                 :             :                 }
     227                 :             :             | K_NOEXPORT_SNAPSHOT
     228                 :             :                 {
     229                 :           0 :                   $$ = makeDefElem("snapshot",
     230                 :           0 :                                    (Node *) makeString("nothing"), -1);
     231                 :             :                 }
     232                 :             :             | K_USE_SNAPSHOT
     233                 :             :                 {
     234                 :           0 :                   $$ = makeDefElem("snapshot",
     235                 :           0 :                                    (Node *) makeString("use"), -1);
     236                 :             :                 }
     237                 :             :             | K_RESERVE_WAL
     238                 :             :                 {
     239                 :           1 :                   $$ = makeDefElem("reserve_wal",
     240                 :           1 :                                    (Node *) makeBoolean(true), -1);
     241                 :             :                 }
     242                 :             :             | K_TWO_PHASE
     243                 :             :                 {
     244                 :           0 :                   $$ = makeDefElem("two_phase",
     245                 :           0 :                                    (Node *) makeBoolean(true), -1);
     246                 :             :                 }
     247                 :             :             ;
     248                 :             : 
     249                 :             : /* DROP_REPLICATION_SLOT slot */
     250                 :             : drop_replication_slot:
     251                 :             :             K_DROP_REPLICATION_SLOT IDENT
     252                 :             :                 {
     253                 :             :                     DropReplicationSlotCmd *cmd;
     254                 :           5 :                     cmd = makeNode(DropReplicationSlotCmd);
     255                 :           5 :                     cmd->slotname = $2;
     256                 :           5 :                     cmd->wait = false;
     257                 :           5 :                     $$ = (Node *) cmd;
     258                 :             :                 }
     259                 :             :             | K_DROP_REPLICATION_SLOT IDENT K_WAIT
     260                 :             :                 {
     261                 :             :                     DropReplicationSlotCmd *cmd;
     262                 :         288 :                     cmd = makeNode(DropReplicationSlotCmd);
     263                 :         288 :                     cmd->slotname = $2;
     264                 :         288 :                     cmd->wait = true;
     265                 :         288 :                     $$ = (Node *) cmd;
     266                 :             :                 }
     267                 :             :             ;
     268                 :             : 
     269                 :             : /* ALTER_REPLICATION_SLOT slot (options) */
     270                 :             : alter_replication_slot:
     271                 :             :             K_ALTER_REPLICATION_SLOT IDENT '(' generic_option_list ')'
     272                 :             :                 {
     273                 :             :                     AlterReplicationSlotCmd *cmd;
     274                 :           7 :                     cmd = makeNode(AlterReplicationSlotCmd);
     275                 :           7 :                     cmd->slotname = $2;
     276                 :           7 :                     cmd->options = $4;
     277                 :           7 :                     $$ = (Node *) cmd;
     278                 :             :                 }
     279                 :             :             ;
     280                 :             : 
     281                 :             : /*
     282                 :             :  * START_REPLICATION [SLOT slot] [PHYSICAL] %X/%08X [TIMELINE %u]
     283                 :             :  */
     284                 :             : start_replication:
     285                 :             :             K_START_REPLICATION opt_slot opt_physical RECPTR opt_timeline
     286                 :             :                 {
     287                 :             :                     StartReplicationCmd *cmd;
     288                 :             : 
     289                 :         302 :                     cmd = makeNode(StartReplicationCmd);
     290                 :         302 :                     cmd->kind = REPLICATION_KIND_PHYSICAL;
     291                 :         302 :                     cmd->slotname = $2;
     292                 :         302 :                     cmd->startpoint = $4;
     293                 :         302 :                     cmd->timeline = $5;
     294                 :         302 :                     $$ = (Node *) cmd;
     295                 :             :                 }
     296                 :             :             ;
     297                 :             : 
     298                 :             : /* START_REPLICATION SLOT slot LOGICAL %X/%08X options */
     299                 :             : start_logical_replication:
     300                 :             :             K_START_REPLICATION K_SLOT IDENT K_LOGICAL RECPTR plugin_options
     301                 :             :                 {
     302                 :             :                     StartReplicationCmd *cmd;
     303                 :         455 :                     cmd = makeNode(StartReplicationCmd);
     304                 :         455 :                     cmd->kind = REPLICATION_KIND_LOGICAL;
     305                 :         455 :                     cmd->slotname = $3;
     306                 :         455 :                     cmd->startpoint = $5;
     307                 :         455 :                     cmd->options = $6;
     308                 :         455 :                     $$ = (Node *) cmd;
     309                 :             :                 }
     310                 :             :             ;
     311                 :             : /*
     312                 :             :  * TIMELINE_HISTORY %u
     313                 :             :  */
     314                 :             : timeline_history:
     315                 :             :             K_TIMELINE_HISTORY UCONST
     316                 :             :                 {
     317                 :             :                     TimeLineHistoryCmd *cmd;
     318                 :             : 
     319         [ -  + ]:          16 :                     if ($2 <= 0)
     320         [ #  # ]:           0 :                         ereport(ERROR,
     321                 :             :                                 (errcode(ERRCODE_SYNTAX_ERROR),
     322                 :             :                                  errmsg("invalid timeline %u", $2)));
     323                 :             : 
     324                 :          16 :                     cmd = makeNode(TimeLineHistoryCmd);
     325                 :          16 :                     cmd->timeline = $2;
     326                 :             : 
     327                 :          16 :                     $$ = (Node *) cmd;
     328                 :             :                 }
     329                 :             :             ;
     330                 :             : 
     331                 :             : /* UPLOAD_MANIFEST doesn't currently accept any arguments */
     332                 :             : upload_manifest:
     333                 :             :             K_UPLOAD_MANIFEST
     334                 :             :                 {
     335                 :          12 :                     UploadManifestCmd *cmd = makeNode(UploadManifestCmd);
     336                 :             : 
     337                 :          12 :                     $$ = (Node *) cmd;
     338                 :             :                 }
     339                 :             : 
     340                 :             : opt_physical:
     341                 :             :             K_PHYSICAL
     342                 :             :             | /* EMPTY */
     343                 :             :             ;
     344                 :             : 
     345                 :             : opt_temporary:
     346                 :         147 :             K_TEMPORARY                     { $$ = true; }
     347                 :         370 :             | /* EMPTY */                   { $$ = false; }
     348                 :             :             ;
     349                 :             : 
     350                 :             : opt_slot:
     351                 :             :             K_SLOT IDENT
     352                 :         203 :                 { $$ = $2; }
     353                 :             :             | /* EMPTY */
     354                 :          99 :                 { $$ = NULL; }
     355                 :             :             ;
     356                 :             : 
     357                 :             : opt_timeline:
     358                 :             :             K_TIMELINE UCONST
     359                 :             :                 {
     360         [ -  + ]:         301 :                     if ($2 <= 0)
     361         [ #  # ]:           0 :                         ereport(ERROR,
     362                 :             :                                 (errcode(ERRCODE_SYNTAX_ERROR),
     363                 :             :                                  errmsg("invalid timeline %u", $2)));
     364                 :         301 :                     $$ = $2;
     365                 :             :                 }
     366                 :           1 :                 | /* EMPTY */           { $$ = 0; }
     367                 :             :             ;
     368                 :             : 
     369                 :             : 
     370                 :             : plugin_options:
     371                 :         447 :             '(' plugin_opt_list ')'         { $$ = $2; }
     372                 :           8 :             | /* EMPTY */                   { $$ = NIL; }
     373                 :             :         ;
     374                 :             : 
     375                 :             : plugin_opt_list:
     376                 :             :             plugin_opt_elem
     377                 :             :                 {
     378                 :         447 :                     $$ = list_make1($1);
     379                 :             :                 }
     380                 :             :             | plugin_opt_list ',' plugin_opt_elem
     381                 :             :                 {
     382                 :        1317 :                     $$ = lappend($1, $3);
     383                 :             :                 }
     384                 :             :         ;
     385                 :             : 
     386                 :             : plugin_opt_elem:
     387                 :             :             IDENT plugin_opt_arg
     388                 :             :                 {
     389                 :        1764 :                     $$ = makeDefElem($1, $2, -1);
     390                 :             :                 }
     391                 :             :         ;
     392                 :             : 
     393                 :             : plugin_opt_arg:
     394                 :        1764 :             SCONST                          { $$ = (Node *) makeString($1); }
     395                 :           0 :             | /* EMPTY */                   { $$ = NULL; }
     396                 :             :         ;
     397                 :             : 
     398                 :             : generic_option_list:
     399                 :             :             generic_option_list ',' generic_option
     400                 :        1100 :                 { $$ = lappend($1, $3); }
     401                 :             :             | generic_option
     402                 :         718 :                 { $$ = list_make1($1); }
     403                 :             :             ;
     404                 :             : 
     405                 :             : generic_option:
     406                 :             :             ident_or_keyword
     407                 :             :                 {
     408                 :         427 :                     $$ = makeDefElem($1, NULL, -1);
     409                 :             :                 }
     410                 :             :             | ident_or_keyword IDENT
     411                 :             :                 {
     412                 :           6 :                     $$ = makeDefElem($1, (Node *) makeString($2), -1);
     413                 :             :                 }
     414                 :             :             | ident_or_keyword SCONST
     415                 :             :                 {
     416                 :        1196 :                     $$ = makeDefElem($1, (Node *) makeString($2), -1);
     417                 :             :                 }
     418                 :             :             | ident_or_keyword UCONST
     419                 :             :                 {
     420                 :         189 :                     $$ = makeDefElem($1, (Node *) makeInteger($2), -1);
     421                 :             :                 }
     422                 :             :             ;
     423                 :             : 
     424                 :             : ident_or_keyword:
     425                 :        1477 :             IDENT                           { $$ = $1; }
     426                 :           0 :             | K_BASE_BACKUP                 { $$ = "base_backup"; }
     427                 :           0 :             | K_IDENTIFY_SYSTEM             { $$ = "identify_system"; }
     428                 :           0 :             | K_SHOW                        { $$ = "show"; }
     429                 :           0 :             | K_START_REPLICATION           { $$ = "start_replication"; }
     430                 :           0 :             | K_CREATE_REPLICATION_SLOT { $$ = "create_replication_slot"; }
     431                 :           0 :             | K_DROP_REPLICATION_SLOT       { $$ = "drop_replication_slot"; }
     432                 :           0 :             | K_ALTER_REPLICATION_SLOT      { $$ = "alter_replication_slot"; }
     433                 :           0 :             | K_TIMELINE_HISTORY            { $$ = "timeline_history"; }
     434                 :         187 :             | K_WAIT                        { $$ = "wait"; }
     435                 :           0 :             | K_TIMELINE                    { $$ = "timeline"; }
     436                 :           0 :             | K_PHYSICAL                    { $$ = "physical"; }
     437                 :           0 :             | K_LOGICAL                     { $$ = "logical"; }
     438                 :           0 :             | K_SLOT                        { $$ = "slot"; }
     439                 :         151 :             | K_RESERVE_WAL                 { $$ = "reserve_wal"; }
     440                 :           0 :             | K_TEMPORARY                   { $$ = "temporary"; }
     441                 :           3 :             | K_TWO_PHASE                   { $$ = "two_phase"; }
     442                 :           0 :             | K_EXPORT_SNAPSHOT             { $$ = "export_snapshot"; }
     443                 :           0 :             | K_NOEXPORT_SNAPSHOT           { $$ = "noexport_snapshot"; }
     444                 :           0 :             | K_USE_SNAPSHOT                { $$ = "use_snapshot"; }
     445                 :           0 :             | K_UPLOAD_MANIFEST             { $$ = "upload_manifest"; }
     446                 :             :         ;
     447                 :             : 
     448                 :             : %%
        

Generated by: LCOV version 2.0-1