diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:15:05 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:15:05 +0000 |
commit | 46651ce6fe013220ed397add242004d764fc0153 (patch) | |
tree | 6e5299f990f88e60174a1d3ae6e48eedd2688b2b /src/backend/replication/repl_gram.y | |
parent | Initial commit. (diff) | |
download | postgresql-14-46651ce6fe013220ed397add242004d764fc0153.tar.xz postgresql-14-46651ce6fe013220ed397add242004d764fc0153.zip |
Adding upstream version 14.5.upstream/14.5upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/backend/replication/repl_gram.y')
-rw-r--r-- | src/backend/replication/repl_gram.y | 414 |
1 files changed, 414 insertions, 0 deletions
diff --git a/src/backend/replication/repl_gram.y b/src/backend/replication/repl_gram.y new file mode 100644 index 0000000..802c0ad --- /dev/null +++ b/src/backend/replication/repl_gram.y @@ -0,0 +1,414 @@ +%{ +/*------------------------------------------------------------------------- + * + * repl_gram.y - Parser for the replication commands + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/replication/repl_gram.y + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "access/xlogdefs.h" +#include "nodes/makefuncs.h" +#include "nodes/replnodes.h" +#include "replication/walsender.h" +#include "replication/walsender_private.h" + + +/* Result of the parsing is returned here */ +Node *replication_parse_result; + + +/* + * Bison doesn't allocate anything that needs to live across parser calls, + * so we can easily have it use palloc instead of malloc. This prevents + * memory leaks if we error out during parsing. Note this only works with + * bison >= 2.0. However, in bison 1.875 the default is to use alloca() + * if possible, so there's not really much problem anyhow, at least if + * you're building with gcc. + */ +#define YYMALLOC palloc +#define YYFREE pfree + +%} + +%expect 0 +%name-prefix="replication_yy" + +%union { + char *str; + bool boolval; + uint32 uintval; + + XLogRecPtr recptr; + Node *node; + List *list; + DefElem *defelt; +} + +/* Non-keyword tokens */ +%token <str> SCONST IDENT +%token <uintval> UCONST +%token <recptr> RECPTR + +/* Keyword tokens. */ +%token K_BASE_BACKUP +%token K_IDENTIFY_SYSTEM +%token K_SHOW +%token K_START_REPLICATION +%token K_CREATE_REPLICATION_SLOT +%token K_DROP_REPLICATION_SLOT +%token K_TIMELINE_HISTORY +%token K_LABEL +%token K_PROGRESS +%token K_FAST +%token K_WAIT +%token K_NOWAIT +%token K_MAX_RATE +%token K_WAL +%token K_TABLESPACE_MAP +%token K_NOVERIFY_CHECKSUMS +%token K_TIMELINE +%token K_PHYSICAL +%token K_LOGICAL +%token K_SLOT +%token K_RESERVE_WAL +%token K_TEMPORARY +%token K_EXPORT_SNAPSHOT +%token K_NOEXPORT_SNAPSHOT +%token K_USE_SNAPSHOT +%token K_MANIFEST +%token K_MANIFEST_CHECKSUMS + +%type <node> command +%type <node> base_backup start_replication start_logical_replication + create_replication_slot drop_replication_slot identify_system + timeline_history show +%type <list> base_backup_opt_list +%type <defelt> base_backup_opt +%type <uintval> opt_timeline +%type <list> plugin_options plugin_opt_list +%type <defelt> plugin_opt_elem +%type <node> plugin_opt_arg +%type <str> opt_slot var_name +%type <boolval> opt_temporary +%type <list> create_slot_opt_list +%type <defelt> create_slot_opt + +%% + +firstcmd: command opt_semicolon + { + replication_parse_result = $1; + } + ; + +opt_semicolon: ';' + | /* EMPTY */ + ; + +command: + identify_system + | base_backup + | start_replication + | start_logical_replication + | create_replication_slot + | drop_replication_slot + | timeline_history + | show + ; + +/* + * IDENTIFY_SYSTEM + */ +identify_system: + K_IDENTIFY_SYSTEM + { + $$ = (Node *) makeNode(IdentifySystemCmd); + } + ; + +/* + * SHOW setting + */ +show: + K_SHOW var_name + { + VariableShowStmt *n = makeNode(VariableShowStmt); + n->name = $2; + $$ = (Node *) n; + } + +var_name: IDENT { $$ = $1; } + | var_name '.' IDENT + { $$ = psprintf("%s.%s", $1, $3); } + ; + +/* + * BASE_BACKUP [LABEL '<label>'] [PROGRESS] [FAST] [WAL] [NOWAIT] + * [MAX_RATE %d] [TABLESPACE_MAP] [NOVERIFY_CHECKSUMS] + * [MANIFEST %s] [MANIFEST_CHECKSUMS %s] + */ +base_backup: + K_BASE_BACKUP base_backup_opt_list + { + BaseBackupCmd *cmd = makeNode(BaseBackupCmd); + cmd->options = $2; + $$ = (Node *) cmd; + } + ; + +base_backup_opt_list: + base_backup_opt_list base_backup_opt + { $$ = lappend($1, $2); } + | /* EMPTY */ + { $$ = NIL; } + ; + +base_backup_opt: + K_LABEL SCONST + { + $$ = makeDefElem("label", + (Node *)makeString($2), -1); + } + | K_PROGRESS + { + $$ = makeDefElem("progress", + (Node *)makeInteger(true), -1); + } + | K_FAST + { + $$ = makeDefElem("fast", + (Node *)makeInteger(true), -1); + } + | K_WAL + { + $$ = makeDefElem("wal", + (Node *)makeInteger(true), -1); + } + | K_NOWAIT + { + $$ = makeDefElem("nowait", + (Node *)makeInteger(true), -1); + } + | K_MAX_RATE UCONST + { + $$ = makeDefElem("max_rate", + (Node *)makeInteger($2), -1); + } + | K_TABLESPACE_MAP + { + $$ = makeDefElem("tablespace_map", + (Node *)makeInteger(true), -1); + } + | K_NOVERIFY_CHECKSUMS + { + $$ = makeDefElem("noverify_checksums", + (Node *)makeInteger(true), -1); + } + | K_MANIFEST SCONST + { + $$ = makeDefElem("manifest", + (Node *)makeString($2), -1); + } + | K_MANIFEST_CHECKSUMS SCONST + { + $$ = makeDefElem("manifest_checksums", + (Node *)makeString($2), -1); + } + ; + +create_replication_slot: + /* CREATE_REPLICATION_SLOT slot TEMPORARY PHYSICAL RESERVE_WAL */ + K_CREATE_REPLICATION_SLOT IDENT opt_temporary K_PHYSICAL create_slot_opt_list + { + CreateReplicationSlotCmd *cmd; + cmd = makeNode(CreateReplicationSlotCmd); + cmd->kind = REPLICATION_KIND_PHYSICAL; + cmd->slotname = $2; + cmd->temporary = $3; + cmd->options = $5; + $$ = (Node *) cmd; + } + /* CREATE_REPLICATION_SLOT slot TEMPORARY LOGICAL plugin */ + | K_CREATE_REPLICATION_SLOT IDENT opt_temporary K_LOGICAL IDENT create_slot_opt_list + { + CreateReplicationSlotCmd *cmd; + cmd = makeNode(CreateReplicationSlotCmd); + cmd->kind = REPLICATION_KIND_LOGICAL; + cmd->slotname = $2; + cmd->temporary = $3; + cmd->plugin = $5; + cmd->options = $6; + $$ = (Node *) cmd; + } + ; + +create_slot_opt_list: + create_slot_opt_list create_slot_opt + { $$ = lappend($1, $2); } + | /* EMPTY */ + { $$ = NIL; } + ; + +create_slot_opt: + K_EXPORT_SNAPSHOT + { + $$ = makeDefElem("export_snapshot", + (Node *)makeInteger(true), -1); + } + | K_NOEXPORT_SNAPSHOT + { + $$ = makeDefElem("export_snapshot", + (Node *)makeInteger(false), -1); + } + | K_USE_SNAPSHOT + { + $$ = makeDefElem("use_snapshot", + (Node *)makeInteger(true), -1); + } + | K_RESERVE_WAL + { + $$ = makeDefElem("reserve_wal", + (Node *)makeInteger(true), -1); + } + ; + +/* DROP_REPLICATION_SLOT slot */ +drop_replication_slot: + K_DROP_REPLICATION_SLOT IDENT + { + DropReplicationSlotCmd *cmd; + cmd = makeNode(DropReplicationSlotCmd); + cmd->slotname = $2; + cmd->wait = false; + $$ = (Node *) cmd; + } + | K_DROP_REPLICATION_SLOT IDENT K_WAIT + { + DropReplicationSlotCmd *cmd; + cmd = makeNode(DropReplicationSlotCmd); + cmd->slotname = $2; + cmd->wait = true; + $$ = (Node *) cmd; + } + ; + +/* + * START_REPLICATION [SLOT slot] [PHYSICAL] %X/%X [TIMELINE %d] + */ +start_replication: + K_START_REPLICATION opt_slot opt_physical RECPTR opt_timeline + { + StartReplicationCmd *cmd; + + cmd = makeNode(StartReplicationCmd); + cmd->kind = REPLICATION_KIND_PHYSICAL; + cmd->slotname = $2; + cmd->startpoint = $4; + cmd->timeline = $5; + $$ = (Node *) cmd; + } + ; + +/* START_REPLICATION SLOT slot LOGICAL %X/%X options */ +start_logical_replication: + K_START_REPLICATION K_SLOT IDENT K_LOGICAL RECPTR plugin_options + { + StartReplicationCmd *cmd; + cmd = makeNode(StartReplicationCmd); + cmd->kind = REPLICATION_KIND_LOGICAL; + cmd->slotname = $3; + cmd->startpoint = $5; + cmd->options = $6; + $$ = (Node *) cmd; + } + ; +/* + * TIMELINE_HISTORY %d + */ +timeline_history: + K_TIMELINE_HISTORY UCONST + { + TimeLineHistoryCmd *cmd; + + if ($2 <= 0) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid timeline %u", $2))); + + cmd = makeNode(TimeLineHistoryCmd); + cmd->timeline = $2; + + $$ = (Node *) cmd; + } + ; + +opt_physical: + K_PHYSICAL + | /* EMPTY */ + ; + +opt_temporary: + K_TEMPORARY { $$ = true; } + | /* EMPTY */ { $$ = false; } + ; + +opt_slot: + K_SLOT IDENT + { $$ = $2; } + | /* EMPTY */ + { $$ = NULL; } + ; + +opt_timeline: + K_TIMELINE UCONST + { + if ($2 <= 0) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid timeline %u", $2))); + $$ = $2; + } + | /* EMPTY */ { $$ = 0; } + ; + + +plugin_options: + '(' plugin_opt_list ')' { $$ = $2; } + | /* EMPTY */ { $$ = NIL; } + ; + +plugin_opt_list: + plugin_opt_elem + { + $$ = list_make1($1); + } + | plugin_opt_list ',' plugin_opt_elem + { + $$ = lappend($1, $3); + } + ; + +plugin_opt_elem: + IDENT plugin_opt_arg + { + $$ = makeDefElem($1, $2, -1); + } + ; + +plugin_opt_arg: + SCONST { $$ = (Node *) makeString($1); } + | /* EMPTY */ { $$ = NULL; } + ; + +%% + +#include "repl_scanner.c" |