Age Owner TLA Line data Source code
1 : %{
2 : /*-------------------------------------------------------------------------
3 : *
4 : * repl_gram.y - Parser for the replication commands
5 : *
6 : * Portions Copyright (c) 1996-2023, 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_TIMELINE_HISTORY
68 : %token K_WAIT
69 : %token K_TIMELINE
70 : %token K_PHYSICAL
71 : %token K_LOGICAL
72 : %token K_SLOT
73 : %token K_RESERVE_WAL
74 : %token K_TEMPORARY
75 : %token K_TWO_PHASE
76 : %token K_EXPORT_SNAPSHOT
77 : %token K_NOEXPORT_SNAPSHOT
78 : %token K_USE_SNAPSHOT
79 :
80 : %type <node> command
81 : %type <node> base_backup start_replication start_logical_replication
82 : create_replication_slot drop_replication_slot identify_system
83 : read_replication_slot timeline_history show
84 : %type <list> generic_option_list
85 : %type <defelt> generic_option
86 : %type <uintval> opt_timeline
87 : %type <list> plugin_options plugin_opt_list
88 : %type <defelt> plugin_opt_elem
89 : %type <node> plugin_opt_arg
90 : %type <str> opt_slot var_name ident_or_keyword
91 : %type <boolval> opt_temporary
92 : %type <list> create_slot_options create_slot_legacy_opt_list
93 : %type <defelt> create_slot_legacy_opt
94 :
95 : %%
96 :
4468 magnus 97 ECB : firstcmd: command opt_semicolon
98 : {
4468 magnus 99 GIC 2162 : replication_parse_result = $1;
100 : }
101 : ;
102 :
103 : opt_semicolon: ';'
104 : | /* EMPTY */
105 : ;
106 :
107 : command:
108 : identify_system
109 : | base_backup
110 : | start_replication
111 : | start_logical_replication
112 : | create_replication_slot
113 : | drop_replication_slot
114 : | read_replication_slot
115 : | timeline_history
116 : | show
117 : ;
118 :
119 : /*
120 : * IDENTIFY_SYSTEM
121 : */
122 : identify_system:
4468 magnus 123 ECB : K_IDENTIFY_SYSTEM
124 : {
4468 magnus 125 GIC 522 : $$ = (Node *) makeNode(IdentifySystemCmd);
126 : }
127 : ;
128 :
129 : /*
130 : * READ_REPLICATION_SLOT %s
131 : */
132 : read_replication_slot:
531 michael 133 ECB : K_READ_REPLICATION_SLOT var_name
134 : {
531 michael 135 CBC 6 : ReadReplicationSlotCmd *n = makeNode(ReadReplicationSlotCmd);
531 michael 136 GIC 6 : n->slotname = $2;
137 6 : $$ = (Node *) n;
138 : }
139 : ;
140 :
141 : /*
142 : * SHOW setting
143 : */
144 : show:
2266 rhaas 145 ECB : K_SHOW var_name
146 : {
2266 rhaas 147 CBC 449 : VariableShowStmt *n = makeNode(VariableShowStmt);
2266 rhaas 148 GIC 449 : n->name = $2;
149 449 : $$ = (Node *) n;
2266 rhaas 150 ECB : }
151 :
2266 rhaas 152 GBC 455 : var_name: IDENT { $$ = $1; }
153 : | var_name '.' IDENT
2266 rhaas 154 UIC 0 : { $$ = psprintf("%s.%s", $1, $3); }
155 : ;
156 :
157 : /*
158 : * BASE_BACKUP [ ( option [ 'value' ] [, ...] ) ]
159 : */
160 : base_backup:
551 rhaas 161 ECB : K_BASE_BACKUP '(' generic_option_list ')'
162 : {
551 rhaas 163 CBC 142 : BaseBackupCmd *cmd = makeNode(BaseBackupCmd);
551 rhaas 164 GIC 142 : cmd->options = $3;
165 142 : $$ = (Node *) cmd;
166 : }
425 rhaas 167 ECB : | K_BASE_BACKUP
4468 magnus 168 : {
2298 peter_e 169 GIC 1 : BaseBackupCmd *cmd = makeNode(BaseBackupCmd);
4468 magnus 170 1 : $$ = (Node *) cmd;
171 : }
172 : ;
173 :
174 : create_replication_slot:
175 : /* CREATE_REPLICATION_SLOT slot [TEMPORARY] PHYSICAL [options] */
176 : K_CREATE_REPLICATION_SLOT IDENT opt_temporary K_PHYSICAL create_slot_options
3355 rhaas 177 ECB : {
178 : CreateReplicationSlotCmd *cmd;
3355 rhaas 179 CBC 97 : cmd = makeNode(CreateReplicationSlotCmd);
180 97 : cmd->kind = REPLICATION_KIND_PHYSICAL;
181 97 : cmd->slotname = $2;
2313 peter_e 182 97 : cmd->temporary = $3;
2217 peter_e 183 GIC 97 : cmd->options = $5;
3355 rhaas 184 97 : $$ = (Node *) cmd;
185 : }
186 : /* CREATE_REPLICATION_SLOT slot [TEMPORARY] LOGICAL plugin [options] */
187 : | K_CREATE_REPLICATION_SLOT IDENT opt_temporary K_LOGICAL IDENT create_slot_options
3317 rhaas 188 ECB : {
189 : CreateReplicationSlotCmd *cmd;
3317 rhaas 190 CBC 247 : cmd = makeNode(CreateReplicationSlotCmd);
191 247 : cmd->kind = REPLICATION_KIND_LOGICAL;
192 247 : cmd->slotname = $2;
2313 peter_e 193 247 : cmd->temporary = $3;
194 247 : cmd->plugin = $5;
2217 peter_e 195 GIC 247 : cmd->options = $6;
3317 rhaas 196 247 : $$ = (Node *) cmd;
197 : }
198 : ;
3355 rhaas 199 ECB :
551 200 : create_slot_options:
551 rhaas 201 GIC 342 : '(' generic_option_list ')' { $$ = $2; }
202 2 : | create_slot_legacy_opt_list { $$ = $1; }
203 : ;
204 :
551 rhaas 205 ECB : create_slot_legacy_opt_list:
206 : create_slot_legacy_opt_list create_slot_legacy_opt
2217 peter_e 207 CBC 1 : { $$ = lappend($1, $2); }
208 : | /* EMPTY */
2217 peter_e 209 GIC 2 : { $$ = NIL; }
210 : ;
211 :
212 : create_slot_legacy_opt:
2217 peter_e 213 EUB : K_EXPORT_SNAPSHOT
214 : {
551 rhaas 215 UIC 0 : $$ = makeDefElem("snapshot",
331 peter 216 0 : (Node *) makeString("export"), -1);
217 : }
2217 peter_e 218 EUB : | K_NOEXPORT_SNAPSHOT
219 : {
551 rhaas 220 UIC 0 : $$ = makeDefElem("snapshot",
331 peter 221 0 : (Node *) makeString("nothing"), -1);
222 : }
2208 peter_e 223 EUB : | K_USE_SNAPSHOT
224 : {
551 rhaas 225 UIC 0 : $$ = makeDefElem("snapshot",
331 peter 226 0 : (Node *) makeString("use"), -1);
227 : }
2217 peter_e 228 ECB : | K_RESERVE_WAL
229 : {
2217 peter_e 230 GIC 1 : $$ = makeDefElem("reserve_wal",
331 peter 231 1 : (Node *) makeBoolean(true), -1);
232 : }
648 akapila 233 EUB : | K_TWO_PHASE
234 : {
648 akapila 235 UIC 0 : $$ = makeDefElem("two_phase",
331 peter 236 0 : (Node *) makeBoolean(true), -1);
237 : }
238 : ;
239 :
240 : /* DROP_REPLICATION_SLOT slot */
241 : drop_replication_slot:
242 : K_DROP_REPLICATION_SLOT IDENT
3355 rhaas 243 ECB : {
244 : DropReplicationSlotCmd *cmd;
3355 rhaas 245 CBC 3 : cmd = makeNode(DropReplicationSlotCmd);
246 3 : cmd->slotname = $2;
2046 alvherre 247 GIC 3 : cmd->wait = false;
248 3 : $$ = (Node *) cmd;
249 : }
250 : | K_DROP_REPLICATION_SLOT IDENT K_WAIT
2046 alvherre 251 ECB : {
252 : DropReplicationSlotCmd *cmd;
2046 alvherre 253 CBC 189 : cmd = makeNode(DropReplicationSlotCmd);
254 189 : cmd->slotname = $2;
2046 alvherre 255 GIC 189 : cmd->wait = true;
3355 rhaas 256 189 : $$ = (Node *) cmd;
257 : }
258 : ;
259 :
260 : /*
261 : * START_REPLICATION [SLOT slot] [PHYSICAL] %X/%X [TIMELINE %d]
262 : */
263 : start_replication:
264 : K_START_REPLICATION opt_slot opt_physical RECPTR opt_timeline
265 : {
4468 magnus 266 ECB : StartReplicationCmd *cmd;
267 :
4468 magnus 268 CBC 195 : cmd = makeNode(StartReplicationCmd);
3355 rhaas 269 195 : cmd->kind = REPLICATION_KIND_PHYSICAL;
270 195 : cmd->slotname = $2;
271 195 : cmd->startpoint = $4;
3355 rhaas 272 GIC 195 : cmd->timeline = $5;
3769 heikki.linnakangas 273 195 : $$ = (Node *) cmd;
274 : }
275 : ;
276 :
277 : /* START_REPLICATION SLOT slot LOGICAL %X/%X options */
278 : start_logical_replication:
279 : K_START_REPLICATION K_SLOT IDENT K_LOGICAL RECPTR plugin_options
3769 heikki.linnakangas 280 ECB : {
3317 rhaas 281 : StartReplicationCmd *cmd;
3317 rhaas 282 CBC 298 : cmd = makeNode(StartReplicationCmd);
2931 heikki.linnakangas 283 298 : cmd->kind = REPLICATION_KIND_LOGICAL;
3317 rhaas 284 298 : cmd->slotname = $3;
285 298 : cmd->startpoint = $5;
3317 rhaas 286 GIC 298 : cmd->options = $6;
287 298 : $$ = (Node *) cmd;
288 : }
289 : ;
290 : /*
291 : * TIMELINE_HISTORY %d
292 : */
293 : timeline_history:
294 : K_TIMELINE_HISTORY UCONST
295 : {
3769 heikki.linnakangas 296 ECB : TimeLineHistoryCmd *cmd;
3769 heikki.linnakangas 297 EUB :
3769 heikki.linnakangas 298 GIC 13 : if ($2 <= 0)
3769 heikki.linnakangas 299 UIC 0 : ereport(ERROR,
300 : (errcode(ERRCODE_SYNTAX_ERROR),
1165 alvherre 301 ECB : errmsg("invalid timeline %u", $2)));
3769 heikki.linnakangas 302 :
3769 heikki.linnakangas 303 GIC 13 : cmd = makeNode(TimeLineHistoryCmd);
3769 heikki.linnakangas 304 CBC 13 : cmd->timeline = $2;
305 :
4468 magnus 306 GIC 13 : $$ = (Node *) cmd;
307 : }
308 : ;
309 :
310 : opt_physical:
311 : K_PHYSICAL
312 : | /* EMPTY */
313 : ;
3355 rhaas 314 ECB :
2313 peter_e 315 : opt_temporary:
2313 peter_e 316 GIC 92 : K_TEMPORARY { $$ = true; }
317 252 : | /* EMPTY */ { $$ = false; }
318 : ;
319 :
3353 tgl 320 ECB : opt_slot:
321 : K_SLOT IDENT
3353 tgl 322 CBC 122 : { $$ = $2; }
323 : | /* EMPTY */
3353 tgl 324 GIC 73 : { $$ = NULL; }
325 : ;
326 :
327 : opt_timeline:
3317 rhaas 328 ECB : K_TIMELINE UCONST
3317 rhaas 329 EUB : {
3317 rhaas 330 GIC 194 : if ($2 <= 0)
3317 rhaas 331 UIC 0 : ereport(ERROR,
3317 rhaas 332 ECB : (errcode(ERRCODE_SYNTAX_ERROR),
333 : errmsg("invalid timeline %u", $2)));
3317 rhaas 334 CBC 194 : $$ = $2;
335 : }
3317 rhaas 336 GIC 1 : | /* EMPTY */ { $$ = 0; }
337 : ;
338 :
3317 rhaas 339 ECB :
340 : plugin_options:
3317 rhaas 341 GIC 293 : '(' plugin_opt_list ')' { $$ = $2; }
342 5 : | /* EMPTY */ { $$ = NIL; }
343 : ;
344 :
345 : plugin_opt_list:
3317 rhaas 346 ECB : plugin_opt_elem
347 : {
3317 rhaas 348 GIC 293 : $$ = list_make1($1);
349 : }
3317 rhaas 350 ECB : | plugin_opt_list ',' plugin_opt_elem
351 : {
3317 rhaas 352 GIC 618 : $$ = lappend($1, $3);
353 : }
354 : ;
355 :
356 : plugin_opt_elem:
3317 rhaas 357 ECB : IDENT plugin_opt_arg
358 : {
2406 peter_e 359 GIC 911 : $$ = makeDefElem($1, $2, -1);
360 : }
361 : ;
3317 rhaas 362 ECB :
3317 rhaas 363 EUB : plugin_opt_arg:
3317 rhaas 364 GIC 911 : SCONST { $$ = (Node *) makeString($1); }
3317 rhaas 365 UIC 0 : | /* EMPTY */ { $$ = NULL; }
366 : ;
367 :
551 rhaas 368 ECB : generic_option_list:
369 : generic_option_list ',' generic_option
551 rhaas 370 CBC 808 : { $$ = lappend($1, $3); }
371 : | generic_option
551 rhaas 372 GIC 484 : { $$ = list_make1($1); }
373 : ;
374 :
375 : generic_option:
551 rhaas 376 ECB : ident_or_keyword
377 : {
551 rhaas 378 GIC 292 : $$ = makeDefElem($1, NULL, -1);
379 : }
551 rhaas 380 EUB : | ident_or_keyword IDENT
381 : {
551 rhaas 382 UIC 0 : $$ = makeDefElem($1, (Node *) makeString($2), -1);
383 : }
551 rhaas 384 ECB : | ident_or_keyword SCONST
385 : {
551 rhaas 386 GIC 863 : $$ = makeDefElem($1, (Node *) makeString($2), -1);
387 : }
551 rhaas 388 ECB : | ident_or_keyword UCONST
389 : {
551 rhaas 390 GIC 137 : $$ = makeDefElem($1, (Node *) makeInteger($2), -1);
391 : }
392 : ;
551 rhaas 393 ECB :
551 rhaas 394 EUB : ident_or_keyword:
551 rhaas 395 GBC 1060 : IDENT { $$ = $1; }
551 rhaas 396 UBC 0 : | K_BASE_BACKUP { $$ = "base_backup"; }
397 0 : | K_IDENTIFY_SYSTEM { $$ = "identify_system"; }
398 0 : | K_SHOW { $$ = "show"; }
399 0 : | K_START_REPLICATION { $$ = "start_replication"; }
400 0 : | K_CREATE_REPLICATION_SLOT { $$ = "create_replication_slot"; }
551 rhaas 401 LBC 0 : | K_DROP_REPLICATION_SLOT { $$ = "drop_replication_slot"; }
551 rhaas 402 UBC 0 : | K_TIMELINE_HISTORY { $$ = "timeline_history"; }
551 rhaas 403 GBC 135 : | K_WAIT { $$ = "wait"; }
551 rhaas 404 UBC 0 : | K_TIMELINE { $$ = "timeline"; }
405 0 : | K_PHYSICAL { $$ = "physical"; }
551 rhaas 406 LBC 0 : | K_LOGICAL { $$ = "logical"; }
551 rhaas 407 UBC 0 : | K_SLOT { $$ = "slot"; }
551 rhaas 408 CBC 95 : | K_RESERVE_WAL { $$ = "reserve_wal"; }
551 rhaas 409 UBC 0 : | K_TEMPORARY { $$ = "temporary"; }
551 rhaas 410 GBC 2 : | K_TWO_PHASE { $$ = "two_phase"; }
551 rhaas 411 UBC 0 : | K_EXPORT_SNAPSHOT { $$ = "export_snapshot"; }
551 rhaas 412 UIC 0 : | K_NOEXPORT_SNAPSHOT { $$ = "noexport_snapshot"; }
413 0 : | K_USE_SNAPSHOT { $$ = "use_snapshot"; }
414 : ;
415 :
416 : %%
|