LCOV - code coverage report
Current view: top level - src/backend/replication - repl_gram.y Coverage Total Hit
Test: PostgreSQL 19devel Lines: 74.8 % 115 86
Test Date: 2026-03-03 13:15:30 Functions: - 0 0
Legend: Lines:     hit not hit

            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         3109 :                     *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          775 :                     $$ = (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          602 :                     VariableShowStmt *n = makeNode(VariableShowStmt);
     157          602 :                     n->name = $2;
     158          602 :                     $$ = (Node *) n;
     159              :                 }
     160              : 
     161          608 : 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          189 :                     BaseBackupCmd *cmd = makeNode(BaseBackupCmd);
     173          189 :                     cmd->options = $3;
     174          189 :                     $$ = (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          145 :                     cmd = makeNode(CreateReplicationSlotCmd);
     189          145 :                     cmd->kind = REPLICATION_KIND_PHYSICAL;
     190          145 :                     cmd->slotname = $2;
     191          145 :                     cmd->temporary = $3;
     192          145 :                     cmd->options = $5;
     193          145 :                     $$ = (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          347 :                     cmd = makeNode(CreateReplicationSlotCmd);
     200          347 :                     cmd->kind = REPLICATION_KIND_LOGICAL;
     201          347 :                     cmd->slotname = $2;
     202          347 :                     cmd->temporary = $3;
     203          347 :                     cmd->plugin = $5;
     204          347 :                     cmd->options = $6;
     205          347 :                     $$ = (Node *) cmd;
     206              :                 }
     207              :             ;
     208              : 
     209              : create_slot_options:
     210          490 :             '(' 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          276 :                     cmd = makeNode(DropReplicationSlotCmd);
     263          276 :                     cmd->slotname = $2;
     264          276 :                     cmd->wait = true;
     265          276 :                     $$ = (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          285 :                     cmd = makeNode(StartReplicationCmd);
     290          285 :                     cmd->kind = REPLICATION_KIND_PHYSICAL;
     291          285 :                     cmd->slotname = $2;
     292          285 :                     cmd->startpoint = $4;
     293          285 :                     cmd->timeline = $5;
     294          285 :                     $$ = (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          445 :                     cmd = makeNode(StartReplicationCmd);
     304          445 :                     cmd->kind = REPLICATION_KIND_LOGICAL;
     305          445 :                     cmd->slotname = $3;
     306          445 :                     cmd->startpoint = $5;
     307          445 :                     cmd->options = $6;
     308          445 :                     $$ = (Node *) cmd;
     309              :                 }
     310              :             ;
     311              : /*
     312              :  * TIMELINE_HISTORY %u
     313              :  */
     314              : timeline_history:
     315              :             K_TIMELINE_HISTORY UCONST
     316              :                 {
     317              :                     TimeLineHistoryCmd *cmd;
     318              : 
     319           13 :                     if ($2 <= 0)
     320            0 :                         ereport(ERROR,
     321              :                                 (errcode(ERRCODE_SYNTAX_ERROR),
     322              :                                  errmsg("invalid timeline %u", $2)));
     323              : 
     324           13 :                     cmd = makeNode(TimeLineHistoryCmd);
     325           13 :                     cmd->timeline = $2;
     326              : 
     327           13 :                     $$ = (Node *) cmd;
     328              :                 }
     329              :             ;
     330              : 
     331              : /* UPLOAD_MANIFEST doesn't currently accept any arguments */
     332              : upload_manifest:
     333              :             K_UPLOAD_MANIFEST
     334              :                 {
     335           13 :                     UploadManifestCmd *cmd = makeNode(UploadManifestCmd);
     336              : 
     337           13 :                     $$ = (Node *) cmd;
     338              :                 }
     339              : 
     340              : opt_physical:
     341              :             K_PHYSICAL
     342              :             | /* EMPTY */
     343              :             ;
     344              : 
     345              : opt_temporary:
     346          140 :             K_TEMPORARY                     { $$ = true; }
     347          352 :             | /* EMPTY */                   { $$ = false; }
     348              :             ;
     349              : 
     350              : opt_slot:
     351              :             K_SLOT IDENT
     352          191 :                 { $$ = $2; }
     353              :             | /* EMPTY */
     354           94 :                 { $$ = NULL; }
     355              :             ;
     356              : 
     357              : opt_timeline:
     358              :             K_TIMELINE UCONST
     359              :                 {
     360          284 :                     if ($2 <= 0)
     361            0 :                         ereport(ERROR,
     362              :                                 (errcode(ERRCODE_SYNTAX_ERROR),
     363              :                                  errmsg("invalid timeline %u", $2)));
     364          284 :                     $$ = $2;
     365              :                 }
     366            1 :                 | /* EMPTY */           { $$ = 0; }
     367              :             ;
     368              : 
     369              : 
     370              : plugin_options:
     371          438 :             '(' plugin_opt_list ')'         { $$ = $2; }
     372            7 :             | /* EMPTY */                   { $$ = NIL; }
     373              :         ;
     374              : 
     375              : plugin_opt_list:
     376              :             plugin_opt_elem
     377              :                 {
     378          438 :                     $$ = list_make1($1);
     379              :                 }
     380              :             | plugin_opt_list ',' plugin_opt_elem
     381              :                 {
     382         1290 :                     $$ = lappend($1, $3);
     383              :                 }
     384              :         ;
     385              : 
     386              : plugin_opt_elem:
     387              :             IDENT plugin_opt_arg
     388              :                 {
     389         1728 :                     $$ = makeDefElem($1, $2, -1);
     390              :                 }
     391              :         ;
     392              : 
     393              : plugin_opt_arg:
     394         1728 :             SCONST                          { $$ = (Node *) makeString($1); }
     395            0 :             | /* EMPTY */                   { $$ = NULL; }
     396              :         ;
     397              : 
     398              : generic_option_list:
     399              :             generic_option_list ',' generic_option
     400         1063 :                 { $$ = lappend($1, $3); }
     401              :             | generic_option
     402          686 :                 { $$ = list_make1($1); }
     403              :             ;
     404              : 
     405              : generic_option:
     406              :             ident_or_keyword
     407              :                 {
     408          411 :                     $$ = 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         1151 :                     $$ = makeDefElem($1, (Node *) makeString($2), -1);
     417              :                 }
     418              :             | ident_or_keyword UCONST
     419              :                 {
     420          181 :                     $$ = makeDefElem($1, (Node *) makeInteger($2), -1);
     421              :                 }
     422              :             ;
     423              : 
     424              : ident_or_keyword:
     425         1424 :             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          179 :             | K_WAIT                        { $$ = "wait"; }
     435            0 :             | K_TIMELINE                    { $$ = "timeline"; }
     436            0 :             | K_PHYSICAL                    { $$ = "physical"; }
     437            0 :             | K_LOGICAL                     { $$ = "logical"; }
     438            0 :             | K_SLOT                        { $$ = "slot"; }
     439          143 :             | 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