LCOV - code coverage report
Current view: top level - src/backend/replication - repl_gram.y (source / functions) Hit Total Coverage
Test: PostgreSQL 12beta2 Lines: 84 97 86.6 %
Date: 2019-06-19 14:06:47 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-2019, 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             : 
      91             : %type <node>  command
      92             : %type <node>  base_backup start_replication start_logical_replication
      93             :                 create_replication_slot drop_replication_slot identify_system
      94             :                 timeline_history show sql_cmd
      95             : %type <list>  base_backup_opt_list
      96             : %type <defelt>    base_backup_opt
      97             : %type <uintval>   opt_timeline
      98             : %type <list>  plugin_options plugin_opt_list
      99             : %type <defelt>    plugin_opt_elem
     100             : %type <node>  plugin_opt_arg
     101             : %type <str>       opt_slot var_name
     102             : %type <boolval>   opt_temporary
     103             : %type <list>  create_slot_opt_list
     104             : %type <defelt>    create_slot_opt
     105             : 
     106             : %%
     107             : 
     108             : firstcmd: command opt_semicolon
     109             :                 {
     110        1608 :                     replication_parse_result = $1;
     111             :                 }
     112             :             ;
     113             : 
     114             : opt_semicolon:  ';'
     115             :                 | /* EMPTY */
     116             :                 ;
     117             : 
     118             : command:
     119             :             identify_system
     120             :             | base_backup
     121             :             | start_replication
     122             :             | start_logical_replication
     123             :             | create_replication_slot
     124             :             | drop_replication_slot
     125             :             | timeline_history
     126             :             | show
     127             :             | sql_cmd
     128             :             ;
     129             : 
     130             : /*
     131             :  * IDENTIFY_SYSTEM
     132             :  */
     133             : identify_system:
     134             :             K_IDENTIFY_SYSTEM
     135             :                 {
     136         334 :                     $$ = (Node *) makeNode(IdentifySystemCmd);
     137             :                 }
     138             :             ;
     139             : 
     140             : /*
     141             :  * SHOW setting
     142             :  */
     143             : show:
     144             :             K_SHOW var_name
     145             :                 {
     146         322 :                     VariableShowStmt *n = makeNode(VariableShowStmt);
     147         322 :                     n->name = $2;
     148         322 :                     $$ = (Node *) n;
     149             :                 }
     150             : 
     151         322 : var_name:   IDENT   { $$ = $1; }
     152             :             | var_name '.' IDENT
     153           0 :                 { $$ = psprintf("%s.%s", $1, $3); }
     154             :         ;
     155             : 
     156             : /*
     157             :  * BASE_BACKUP [LABEL '<label>'] [PROGRESS] [FAST] [WAL] [NOWAIT]
     158             :  * [MAX_RATE %d] [TABLESPACE_MAP] [NOVERIFY_CHECKSUMS]
     159             :  */
     160             : base_backup:
     161             :             K_BASE_BACKUP base_backup_opt_list
     162             :                 {
     163          98 :                     BaseBackupCmd *cmd = makeNode(BaseBackupCmd);
     164          98 :                     cmd->options = $2;
     165          98 :                     $$ = (Node *) cmd;
     166             :                 }
     167             :             ;
     168             : 
     169             : base_backup_opt_list:
     170             :             base_backup_opt_list base_backup_opt
     171         208 :                 { $$ = lappend($1, $2); }
     172             :             | /* EMPTY */
     173          98 :                 { $$ = NIL; }
     174             :             ;
     175             : 
     176             : base_backup_opt:
     177             :             K_LABEL SCONST
     178             :                 {
     179          98 :                   $$ = makeDefElem("label",
     180          98 :                                    (Node *)makeString($2), -1);
     181             :                 }
     182             :             | K_PROGRESS
     183             :                 {
     184           0 :                   $$ = makeDefElem("progress",
     185           0 :                                    (Node *)makeInteger(true), -1);
     186             :                 }
     187             :             | K_FAST
     188             :                 {
     189           0 :                   $$ = makeDefElem("fast",
     190           0 :                                    (Node *)makeInteger(true), -1);
     191             :                 }
     192             :             | K_WAL
     193             :                 {
     194           2 :                   $$ = makeDefElem("wal",
     195           2 :                                    (Node *)makeInteger(true), -1);
     196             :                 }
     197             :             | K_NOWAIT
     198             :                 {
     199          96 :                   $$ = makeDefElem("nowait",
     200          96 :                                    (Node *)makeInteger(true), -1);
     201             :                 }
     202             :             | K_MAX_RATE UCONST
     203             :                 {
     204           0 :                   $$ = makeDefElem("max_rate",
     205           0 :                                    (Node *)makeInteger($2), -1);
     206             :                 }
     207             :             | K_TABLESPACE_MAP
     208             :                 {
     209          10 :                   $$ = makeDefElem("tablespace_map",
     210          10 :                                    (Node *)makeInteger(true), -1);
     211             :                 }
     212             :             | K_NOVERIFY_CHECKSUMS
     213             :                 {
     214           2 :                   $$ = makeDefElem("noverify_checksums",
     215           2 :                                    (Node *)makeInteger(true), -1);
     216             :                 }
     217             :             ;
     218             : 
     219             : create_replication_slot:
     220             :             /* CREATE_REPLICATION_SLOT slot TEMPORARY PHYSICAL RESERVE_WAL */
     221             :             K_CREATE_REPLICATION_SLOT IDENT opt_temporary K_PHYSICAL create_slot_opt_list
     222             :                 {
     223             :                     CreateReplicationSlotCmd *cmd;
     224          86 :                     cmd = makeNode(CreateReplicationSlotCmd);
     225          86 :                     cmd->kind = REPLICATION_KIND_PHYSICAL;
     226          86 :                     cmd->slotname = $2;
     227          86 :                     cmd->temporary = $3;
     228          86 :                     cmd->options = $5;
     229          86 :                     $$ = (Node *) cmd;
     230             :                 }
     231             :             /* CREATE_REPLICATION_SLOT slot TEMPORARY LOGICAL plugin */
     232             :             | K_CREATE_REPLICATION_SLOT IDENT opt_temporary K_LOGICAL IDENT create_slot_opt_list
     233             :                 {
     234             :                     CreateReplicationSlotCmd *cmd;
     235         108 :                     cmd = makeNode(CreateReplicationSlotCmd);
     236         108 :                     cmd->kind = REPLICATION_KIND_LOGICAL;
     237         108 :                     cmd->slotname = $2;
     238         108 :                     cmd->temporary = $3;
     239         108 :                     cmd->plugin = $5;
     240         108 :                     cmd->options = $6;
     241         108 :                     $$ = (Node *) cmd;
     242             :                 }
     243             :             ;
     244             : 
     245             : create_slot_opt_list:
     246             :             create_slot_opt_list create_slot_opt
     247         192 :                 { $$ = lappend($1, $2); }
     248             :             | /* EMPTY */
     249         194 :                 { $$ = NIL; }
     250             :             ;
     251             : 
     252             : create_slot_opt:
     253             :             K_EXPORT_SNAPSHOT
     254             :                 {
     255           0 :                   $$ = makeDefElem("export_snapshot",
     256           0 :                                    (Node *)makeInteger(true), -1);
     257             :                 }
     258             :             | K_NOEXPORT_SNAPSHOT
     259             :                 {
     260          36 :                   $$ = makeDefElem("export_snapshot",
     261          36 :                                    (Node *)makeInteger(false), -1);
     262             :                 }
     263             :             | K_USE_SNAPSHOT
     264             :                 {
     265          72 :                   $$ = makeDefElem("use_snapshot",
     266          72 :                                    (Node *)makeInteger(true), -1);
     267             :                 }
     268             :             | K_RESERVE_WAL
     269             :                 {
     270          84 :                   $$ = makeDefElem("reserve_wal",
     271          84 :                                    (Node *)makeInteger(true), -1);
     272             :                 }
     273             :             ;
     274             : 
     275             : /* DROP_REPLICATION_SLOT slot */
     276             : drop_replication_slot:
     277             :             K_DROP_REPLICATION_SLOT IDENT
     278             :                 {
     279             :                     DropReplicationSlotCmd *cmd;
     280           2 :                     cmd = makeNode(DropReplicationSlotCmd);
     281           2 :                     cmd->slotname = $2;
     282           2 :                     cmd->wait = false;
     283           2 :                     $$ = (Node *) cmd;
     284             :                 }
     285             :             | K_DROP_REPLICATION_SLOT IDENT K_WAIT
     286             :                 {
     287             :                     DropReplicationSlotCmd *cmd;
     288          12 :                     cmd = makeNode(DropReplicationSlotCmd);
     289          12 :                     cmd->slotname = $2;
     290          12 :                     cmd->wait = true;
     291          12 :                     $$ = (Node *) cmd;
     292             :                 }
     293             :             ;
     294             : 
     295             : /*
     296             :  * START_REPLICATION [SLOT slot] [PHYSICAL] %X/%X [TIMELINE %d]
     297             :  */
     298             : start_replication:
     299             :             K_START_REPLICATION opt_slot opt_physical RECPTR opt_timeline
     300             :                 {
     301             :                     StartReplicationCmd *cmd;
     302             : 
     303         182 :                     cmd = makeNode(StartReplicationCmd);
     304         182 :                     cmd->kind = REPLICATION_KIND_PHYSICAL;
     305         182 :                     cmd->slotname = $2;
     306         182 :                     cmd->startpoint = $4;
     307         182 :                     cmd->timeline = $5;
     308         182 :                     $$ = (Node *) cmd;
     309             :                 }
     310             :             ;
     311             : 
     312             : /* START_REPLICATION SLOT slot LOGICAL %X/%X options */
     313             : start_logical_replication:
     314             :             K_START_REPLICATION K_SLOT IDENT K_LOGICAL RECPTR plugin_options
     315             :                 {
     316             :                     StartReplicationCmd *cmd;
     317          46 :                     cmd = makeNode(StartReplicationCmd);
     318          46 :                     cmd->kind = REPLICATION_KIND_LOGICAL;
     319          46 :                     cmd->slotname = $3;
     320          46 :                     cmd->startpoint = $5;
     321          46 :                     cmd->options = $6;
     322          46 :                     $$ = (Node *) cmd;
     323             :                 }
     324             :             ;
     325             : /*
     326             :  * TIMELINE_HISTORY %d
     327             :  */
     328             : timeline_history:
     329             :             K_TIMELINE_HISTORY UCONST
     330             :                 {
     331             :                     TimeLineHistoryCmd *cmd;
     332             : 
     333          10 :                     if ($2 <= 0)
     334           0 :                         ereport(ERROR,
     335             :                                 (errcode(ERRCODE_SYNTAX_ERROR),
     336             :                                  (errmsg("invalid timeline %u", $2))));
     337             : 
     338          10 :                     cmd = makeNode(TimeLineHistoryCmd);
     339          10 :                     cmd->timeline = $2;
     340             : 
     341          10 :                     $$ = (Node *) cmd;
     342             :                 }
     343             :             ;
     344             : 
     345             : opt_physical:
     346             :             K_PHYSICAL
     347             :             | /* EMPTY */
     348             :             ;
     349             : 
     350             : opt_temporary:
     351         152 :             K_TEMPORARY                     { $$ = true; }
     352          42 :             | /* EMPTY */                   { $$ = false; }
     353             :             ;
     354             : 
     355             : opt_slot:
     356             :             K_SLOT IDENT
     357          88 :                 { $$ = $2; }
     358             :             | /* EMPTY */
     359          94 :                 { $$ = NULL; }
     360             :             ;
     361             : 
     362             : opt_timeline:
     363             :             K_TIMELINE UCONST
     364             :                 {
     365         182 :                     if ($2 <= 0)
     366           0 :                         ereport(ERROR,
     367             :                                 (errcode(ERRCODE_SYNTAX_ERROR),
     368             :                                  (errmsg("invalid timeline %u", $2))));
     369         182 :                     $$ = $2;
     370             :                 }
     371           0 :                 | /* EMPTY */           { $$ = 0; }
     372             :             ;
     373             : 
     374             : 
     375             : plugin_options:
     376          42 :             '(' plugin_opt_list ')'         { $$ = $2; }
     377           4 :             | /* EMPTY */                   { $$ = NIL; }
     378             :         ;
     379             : 
     380             : plugin_opt_list:
     381             :             plugin_opt_elem
     382             :                 {
     383          42 :                     $$ = list_make1($1);
     384             :                 }
     385             :             | plugin_opt_list ',' plugin_opt_elem
     386             :                 {
     387          42 :                     $$ = lappend($1, $3);
     388             :                 }
     389             :         ;
     390             : 
     391             : plugin_opt_elem:
     392             :             IDENT plugin_opt_arg
     393             :                 {
     394          84 :                     $$ = makeDefElem($1, $2, -1);
     395             :                 }
     396             :         ;
     397             : 
     398             : plugin_opt_arg:
     399          84 :             SCONST                          { $$ = (Node *) makeString($1); }
     400           0 :             | /* EMPTY */                   { $$ = NULL; }
     401             :         ;
     402             : 
     403             : sql_cmd:
     404         408 :             IDENT                           { $$ = (Node *) make_sqlcmd(); }
     405             :         ;
     406             : %%
     407             : 
     408             : static SQLCmd *
     409         408 : make_sqlcmd(void)
     410             : {
     411         408 :     SQLCmd *cmd = makeNode(SQLCmd);
     412             :     int tok;
     413             : 
     414             :     /* Just move lexer to the end of command. */
     415             :     for (;;)
     416             :     {
     417       21592 :         tok = yylex();
     418       11000 :         if (tok == ';' || tok == 0)
     419             :             break;
     420             :     }
     421         408 :     return cmd;
     422             : }
     423             : 
     424             : #include "repl_scanner.c"

Generated by: LCOV version 1.13