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

Generated by: LCOV version 1.14