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

Generated by: LCOV version 1.14