LCOV - code coverage report
Current view: top level - src/backend/replication - repl_gram.y (source / functions) Hit Total Coverage
Test: PostgreSQL 13beta1 Lines: 90 101 89.1 %
Date: 2020-06-03 10:06:28 Functions: 1 1 100.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-2020, 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/replnodes.h"
      21             : #include "replication/walsender.h"
      22             : #include "replication/walsender_private.h"
      23             : 
      24             : 
      25             : /* Result of the parsing is returned here */
      26             : Node *replication_parse_result;
      27             : 
      28             : static SQLCmd *make_sqlcmd(void);
      29             : 
      30             : 
      31             : /*
      32             :  * Bison doesn't allocate anything that needs to live across parser calls,
      33             :  * so we can easily have it use palloc instead of malloc.  This prevents
      34             :  * memory leaks if we error out during parsing.  Note this only works with
      35             :  * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
      36             :  * if possible, so there's not really much problem anyhow, at least if
      37             :  * you're building with gcc.
      38             :  */
      39             : #define YYMALLOC palloc
      40             : #define YYFREE   pfree
      41             : 
      42             : %}
      43             : 
      44             : %expect 0
      45             : %name-prefix="replication_yy"
      46             : 
      47             : %union {
      48             :         char                    *str;
      49             :         bool                    boolval;
      50             :         uint32                  uintval;
      51             : 
      52             :         XLogRecPtr              recptr;
      53             :         Node                    *node;
      54             :         List                    *list;
      55             :         DefElem                 *defelt;
      56             : }
      57             : 
      58             : /* Non-keyword tokens */
      59             : %token <str> SCONST IDENT
      60             : %token <uintval> UCONST
      61             : %token <recptr> RECPTR
      62             : %token T_WORD
      63             : 
      64             : /* Keyword tokens. */
      65             : %token K_BASE_BACKUP
      66             : %token K_IDENTIFY_SYSTEM
      67             : %token K_SHOW
      68             : %token K_START_REPLICATION
      69             : %token K_CREATE_REPLICATION_SLOT
      70             : %token K_DROP_REPLICATION_SLOT
      71             : %token K_TIMELINE_HISTORY
      72             : %token K_LABEL
      73             : %token K_PROGRESS
      74             : %token K_FAST
      75             : %token K_WAIT
      76             : %token K_NOWAIT
      77             : %token K_MAX_RATE
      78             : %token K_WAL
      79             : %token K_TABLESPACE_MAP
      80             : %token K_NOVERIFY_CHECKSUMS
      81             : %token K_TIMELINE
      82             : %token K_PHYSICAL
      83             : %token K_LOGICAL
      84             : %token K_SLOT
      85             : %token K_RESERVE_WAL
      86             : %token K_TEMPORARY
      87             : %token K_EXPORT_SNAPSHOT
      88             : %token K_NOEXPORT_SNAPSHOT
      89             : %token K_USE_SNAPSHOT
      90             : %token K_MANIFEST
      91             : %token K_MANIFEST_CHECKSUMS
      92             : 
      93             : %type <node>  command
      94             : %type <node>  base_backup start_replication start_logical_replication
      95             :                 create_replication_slot drop_replication_slot identify_system
      96             :                 timeline_history show sql_cmd
      97             : %type <list>  base_backup_opt_list
      98             : %type <defelt>    base_backup_opt
      99             : %type <uintval>   opt_timeline
     100             : %type <list>  plugin_options plugin_opt_list
     101             : %type <defelt>    plugin_opt_elem
     102             : %type <node>  plugin_opt_arg
     103             : %type <str>       opt_slot var_name
     104             : %type <boolval>   opt_temporary
     105             : %type <list>  create_slot_opt_list
     106             : %type <defelt>    create_slot_opt
     107             : 
     108             : %%
     109             : 
     110             : firstcmd: command opt_semicolon
     111             :                 {
     112        2234 :                     replication_parse_result = $1;
     113             :                 }
     114             :             ;
     115             : 
     116             : opt_semicolon:  ';'
     117             :                 | /* EMPTY */
     118             :                 ;
     119             : 
     120             : command:
     121             :             identify_system
     122             :             | base_backup
     123             :             | start_replication
     124             :             | start_logical_replication
     125             :             | create_replication_slot
     126             :             | drop_replication_slot
     127             :             | timeline_history
     128             :             | show
     129             :             | sql_cmd
     130             :             ;
     131             : 
     132             : /*
     133             :  * IDENTIFY_SYSTEM
     134             :  */
     135             : identify_system:
     136             :             K_IDENTIFY_SYSTEM
     137             :                 {
     138         452 :                     $$ = (Node *) makeNode(IdentifySystemCmd);
     139             :                 }
     140             :             ;
     141             : 
     142             : /*
     143             :  * SHOW setting
     144             :  */
     145             : show:
     146             :             K_SHOW var_name
     147             :                 {
     148         466 :                     VariableShowStmt *n = makeNode(VariableShowStmt);
     149         466 :                     n->name = $2;
     150         466 :                     $$ = (Node *) n;
     151             :                 }
     152             : 
     153         466 : var_name:   IDENT   { $$ = $1; }
     154             :             | var_name '.' IDENT
     155           0 :                 { $$ = psprintf("%s.%s", $1, $3); }
     156             :         ;
     157             : 
     158             : /*
     159             :  * BASE_BACKUP [LABEL '<label>'] [PROGRESS] [FAST] [WAL] [NOWAIT]
     160             :  * [MAX_RATE %d] [TABLESPACE_MAP] [NOVERIFY_CHECKSUMS]
     161             :  * [MANIFEST %s] [MANIFEST_CHECKSUMS %s]
     162             :  */
     163             : base_backup:
     164             :             K_BASE_BACKUP base_backup_opt_list
     165             :                 {
     166         146 :                     BaseBackupCmd *cmd = makeNode(BaseBackupCmd);
     167         146 :                     cmd->options = $2;
     168         146 :                     $$ = (Node *) cmd;
     169             :                 }
     170             :             ;
     171             : 
     172             : base_backup_opt_list:
     173             :             base_backup_opt_list base_backup_opt
     174         608 :                 { $$ = lappend($1, $2); }
     175             :             | /* EMPTY */
     176         146 :                 { $$ = NIL; }
     177             :             ;
     178             : 
     179             : base_backup_opt:
     180             :             K_LABEL SCONST
     181             :                 {
     182         146 :                   $$ = makeDefElem("label",
     183         146 :                                    (Node *)makeString($2), -1);
     184             :                 }
     185             :             | K_PROGRESS
     186             :                 {
     187         146 :                   $$ = makeDefElem("progress",
     188         146 :                                    (Node *)makeInteger(true), -1);
     189             :                 }
     190             :             | K_FAST
     191             :                 {
     192           0 :                   $$ = makeDefElem("fast",
     193           0 :                                    (Node *)makeInteger(true), -1);
     194             :                 }
     195             :             | K_WAL
     196             :                 {
     197           2 :                   $$ = makeDefElem("wal",
     198           2 :                                    (Node *)makeInteger(true), -1);
     199             :                 }
     200             :             | K_NOWAIT
     201             :                 {
     202         144 :                   $$ = makeDefElem("nowait",
     203         144 :                                    (Node *)makeInteger(true), -1);
     204             :                 }
     205             :             | K_MAX_RATE UCONST
     206             :                 {
     207           0 :                   $$ = makeDefElem("max_rate",
     208           0 :                                    (Node *)makeInteger($2), -1);
     209             :                 }
     210             :             | K_TABLESPACE_MAP
     211             :                 {
     212          10 :                   $$ = makeDefElem("tablespace_map",
     213          10 :                                    (Node *)makeInteger(true), -1);
     214             :                 }
     215             :             | K_NOVERIFY_CHECKSUMS
     216             :                 {
     217           2 :                   $$ = makeDefElem("noverify_checksums",
     218           2 :                                    (Node *)makeInteger(true), -1);
     219             :                 }
     220             :             | K_MANIFEST SCONST
     221             :                 {
     222         144 :                   $$ = makeDefElem("manifest",
     223         144 :                                    (Node *)makeString($2), -1);
     224             :                 }
     225             :             | K_MANIFEST_CHECKSUMS SCONST
     226             :                 {
     227          14 :                   $$ = makeDefElem("manifest_checksums",
     228          14 :                                    (Node *)makeString($2), -1);
     229             :                 }
     230             :             ;
     231             : 
     232             : create_replication_slot:
     233             :             /* CREATE_REPLICATION_SLOT slot TEMPORARY PHYSICAL RESERVE_WAL */
     234             :             K_CREATE_REPLICATION_SLOT IDENT opt_temporary K_PHYSICAL create_slot_opt_list
     235             :                 {
     236             :                     CreateReplicationSlotCmd *cmd;
     237         132 :                     cmd = makeNode(CreateReplicationSlotCmd);
     238         132 :                     cmd->kind = REPLICATION_KIND_PHYSICAL;
     239         132 :                     cmd->slotname = $2;
     240         132 :                     cmd->temporary = $3;
     241         132 :                     cmd->options = $5;
     242         132 :                     $$ = (Node *) cmd;
     243             :                 }
     244             :             /* CREATE_REPLICATION_SLOT slot TEMPORARY LOGICAL plugin */
     245             :             | K_CREATE_REPLICATION_SLOT IDENT opt_temporary K_LOGICAL IDENT create_slot_opt_list
     246             :                 {
     247             :                     CreateReplicationSlotCmd *cmd;
     248         144 :                     cmd = makeNode(CreateReplicationSlotCmd);
     249         144 :                     cmd->kind = REPLICATION_KIND_LOGICAL;
     250         144 :                     cmd->slotname = $2;
     251         144 :                     cmd->temporary = $3;
     252         144 :                     cmd->plugin = $5;
     253         144 :                     cmd->options = $6;
     254         144 :                     $$ = (Node *) cmd;
     255             :                 }
     256             :             ;
     257             : 
     258             : create_slot_opt_list:
     259             :             create_slot_opt_list create_slot_opt
     260         274 :                 { $$ = lappend($1, $2); }
     261             :             | /* EMPTY */
     262         276 :                 { $$ = NIL; }
     263             :             ;
     264             : 
     265             : create_slot_opt:
     266             :             K_EXPORT_SNAPSHOT
     267             :                 {
     268           0 :                   $$ = makeDefElem("export_snapshot",
     269           0 :                                    (Node *)makeInteger(true), -1);
     270             :                 }
     271             :             | K_NOEXPORT_SNAPSHOT
     272             :                 {
     273          42 :                   $$ = makeDefElem("export_snapshot",
     274          42 :                                    (Node *)makeInteger(false), -1);
     275             :                 }
     276             :             | K_USE_SNAPSHOT
     277             :                 {
     278         102 :                   $$ = makeDefElem("use_snapshot",
     279         102 :                                    (Node *)makeInteger(true), -1);
     280             :                 }
     281             :             | K_RESERVE_WAL
     282             :                 {
     283         130 :                   $$ = makeDefElem("reserve_wal",
     284         130 :                                    (Node *)makeInteger(true), -1);
     285             :                 }
     286             :             ;
     287             : 
     288             : /* DROP_REPLICATION_SLOT slot */
     289             : drop_replication_slot:
     290             :             K_DROP_REPLICATION_SLOT IDENT
     291             :                 {
     292             :                     DropReplicationSlotCmd *cmd;
     293           2 :                     cmd = makeNode(DropReplicationSlotCmd);
     294           2 :                     cmd->slotname = $2;
     295           2 :                     cmd->wait = false;
     296           2 :                     $$ = (Node *) cmd;
     297             :                 }
     298             :             | K_DROP_REPLICATION_SLOT IDENT K_WAIT
     299             :                 {
     300             :                     DropReplicationSlotCmd *cmd;
     301          14 :                     cmd = makeNode(DropReplicationSlotCmd);
     302          14 :                     cmd->slotname = $2;
     303          14 :                     cmd->wait = true;
     304          14 :                     $$ = (Node *) cmd;
     305             :                 }
     306             :             ;
     307             : 
     308             : /*
     309             :  * START_REPLICATION [SLOT slot] [PHYSICAL] %X/%X [TIMELINE %d]
     310             :  */
     311             : start_replication:
     312             :             K_START_REPLICATION opt_slot opt_physical RECPTR opt_timeline
     313             :                 {
     314             :                     StartReplicationCmd *cmd;
     315             : 
     316         248 :                     cmd = makeNode(StartReplicationCmd);
     317         248 :                     cmd->kind = REPLICATION_KIND_PHYSICAL;
     318         248 :                     cmd->slotname = $2;
     319         248 :                     cmd->startpoint = $4;
     320         248 :                     cmd->timeline = $5;
     321         248 :                     $$ = (Node *) cmd;
     322             :                 }
     323             :             ;
     324             : 
     325             : /* START_REPLICATION SLOT slot LOGICAL %X/%X options */
     326             : start_logical_replication:
     327             :             K_START_REPLICATION K_SLOT IDENT K_LOGICAL RECPTR plugin_options
     328             :                 {
     329             :                     StartReplicationCmd *cmd;
     330          52 :                     cmd = makeNode(StartReplicationCmd);
     331          52 :                     cmd->kind = REPLICATION_KIND_LOGICAL;
     332          52 :                     cmd->slotname = $3;
     333          52 :                     cmd->startpoint = $5;
     334          52 :                     cmd->options = $6;
     335          52 :                     $$ = (Node *) cmd;
     336             :                 }
     337             :             ;
     338             : /*
     339             :  * TIMELINE_HISTORY %d
     340             :  */
     341             : timeline_history:
     342             :             K_TIMELINE_HISTORY UCONST
     343             :                 {
     344             :                     TimeLineHistoryCmd *cmd;
     345             : 
     346          10 :                     if ($2 <= 0)
     347           0 :                         ereport(ERROR,
     348             :                                 (errcode(ERRCODE_SYNTAX_ERROR),
     349             :                                  errmsg("invalid timeline %u", $2)));
     350             : 
     351          10 :                     cmd = makeNode(TimeLineHistoryCmd);
     352          10 :                     cmd->timeline = $2;
     353             : 
     354          10 :                     $$ = (Node *) cmd;
     355             :                 }
     356             :             ;
     357             : 
     358             : opt_physical:
     359             :             K_PHYSICAL
     360             :             | /* EMPTY */
     361             :             ;
     362             : 
     363             : opt_temporary:
     364         228 :             K_TEMPORARY                     { $$ = true; }
     365          48 :             | /* EMPTY */                   { $$ = false; }
     366             :             ;
     367             : 
     368             : opt_slot:
     369             :             K_SLOT IDENT
     370         150 :                 { $$ = $2; }
     371             :             | /* EMPTY */
     372          98 :                 { $$ = NULL; }
     373             :             ;
     374             : 
     375             : opt_timeline:
     376             :             K_TIMELINE UCONST
     377             :                 {
     378         248 :                     if ($2 <= 0)
     379           0 :                         ereport(ERROR,
     380             :                                 (errcode(ERRCODE_SYNTAX_ERROR),
     381             :                                  errmsg("invalid timeline %u", $2)));
     382         248 :                     $$ = $2;
     383             :                 }
     384           0 :                 | /* EMPTY */           { $$ = 0; }
     385             :             ;
     386             : 
     387             : 
     388             : plugin_options:
     389          46 :             '(' plugin_opt_list ')'         { $$ = $2; }
     390           6 :             | /* EMPTY */                   { $$ = NIL; }
     391             :         ;
     392             : 
     393             : plugin_opt_list:
     394             :             plugin_opt_elem
     395             :                 {
     396          46 :                     $$ = list_make1($1);
     397             :                 }
     398             :             | plugin_opt_list ',' plugin_opt_elem
     399             :                 {
     400          46 :                     $$ = lappend($1, $3);
     401             :                 }
     402             :         ;
     403             : 
     404             : plugin_opt_elem:
     405             :             IDENT plugin_opt_arg
     406             :                 {
     407          92 :                     $$ = makeDefElem($1, $2, -1);
     408             :                 }
     409             :         ;
     410             : 
     411             : plugin_opt_arg:
     412          92 :             SCONST                          { $$ = (Node *) makeString($1); }
     413           0 :             | /* EMPTY */                   { $$ = NULL; }
     414             :         ;
     415             : 
     416             : sql_cmd:
     417         568 :             IDENT                           { $$ = (Node *) make_sqlcmd(); }
     418             :         ;
     419             : %%
     420             : 
     421             : static SQLCmd *
     422         568 : make_sqlcmd(void)
     423             : {
     424         568 :     SQLCmd *cmd = makeNode(SQLCmd);
     425             :     int tok;
     426             : 
     427             :     /* Just move lexer to the end of command. */
     428             :     for (;;)
     429             :     {
     430       15262 :         tok = yylex();
     431       15262 :         if (tok == ';' || tok == 0)
     432             :             break;
     433             :     }
     434         568 :     return cmd;
     435             : }
     436             : 
     437             : #include "repl_scanner.c"

Generated by: LCOV version 1.13