Skip to content

Commit e5487f6

Browse files
committed
Make walsender options order-independent
While doing this, also move base backup options into a struct instead of increasing the number of parameters to multiple functions for each new option.
1 parent 39e911e commit e5487f6

File tree

5 files changed

+109
-43
lines changed

5 files changed

+109
-43
lines changed

src/backend/replication/basebackup.c

+72-11
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@
3232
#include "utils/memutils.h"
3333
#include "utils/ps_status.h"
3434

35+
typedef struct
36+
{
37+
const char *label;
38+
bool progress;
39+
bool fastcheckpoint;
40+
} basebackup_options;
41+
42+
3543
static int64 sendDir(char *path, int basepathlen, bool sizeonly);
3644
static void sendFile(char *path, int basepathlen, struct stat * statbuf);
3745
static void _tarWriteHeader(char *filename, char *linktarget,
@@ -40,7 +48,8 @@ static void send_int8_string(StringInfoData *buf, int64 intval);
4048
static void SendBackupHeader(List *tablespaces);
4149
static void SendBackupDirectory(char *location, char *spcoid);
4250
static void base_backup_cleanup(int code, Datum arg);
43-
static void perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, bool fastcheckpoint);
51+
static void perform_base_backup(basebackup_options *opt, DIR *tblspcdir);
52+
static void parse_basebackup_options(List *options, basebackup_options *opt);
4453

4554
typedef struct
4655
{
@@ -67,9 +76,9 @@ base_backup_cleanup(int code, Datum arg)
6776
* clobbered by longjmp" from stupider versions of gcc.
6877
*/
6978
static void
70-
perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, bool fastcheckpoint)
79+
perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
7180
{
72-
do_pg_start_backup(backup_label, fastcheckpoint);
81+
do_pg_start_backup(opt->label, opt->fastcheckpoint);
7382

7483
PG_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum) 0);
7584
{
@@ -81,7 +90,7 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo
8190

8291
/* Add a node for the base directory */
8392
ti = palloc0(sizeof(tablespaceinfo));
84-
ti->size = progress ? sendDir(".", 1, true) : -1;
93+
ti->size = opt->progress ? sendDir(".", 1, true) : -1;
8594
tablespaces = lappend(tablespaces, ti);
8695

8796
/* Collect information about all tablespaces */
@@ -107,7 +116,7 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo
107116
ti = palloc(sizeof(tablespaceinfo));
108117
ti->oid = pstrdup(de->d_name);
109118
ti->path = pstrdup(linkpath);
110-
ti->size = progress ? sendDir(linkpath, strlen(linkpath), true) : -1;
119+
ti->size = opt->progress ? sendDir(linkpath, strlen(linkpath), true) : -1;
111120
tablespaces = lappend(tablespaces, ti);
112121
}
113122

@@ -128,18 +137,73 @@ perform_base_backup(const char *backup_label, bool progress, DIR *tblspcdir, boo
128137
do_pg_stop_backup();
129138
}
130139

140+
/*
141+
* Parse the base backup options passed down by the parser
142+
*/
143+
static void
144+
parse_basebackup_options(List *options, basebackup_options *opt)
145+
{
146+
ListCell *lopt;
147+
bool o_label = false;
148+
bool o_progress = false;
149+
bool o_fast = false;
150+
151+
MemSet(opt, 0, sizeof(opt));
152+
foreach(lopt, options)
153+
{
154+
DefElem *defel = (DefElem *) lfirst(lopt);
155+
156+
if (strcmp(defel->defname, "label") == 0)
157+
{
158+
if (o_label)
159+
ereport(ERROR,
160+
(errcode(ERRCODE_SYNTAX_ERROR),
161+
errmsg("duplicate option \"%s\"", defel->defname)));
162+
opt->label = strVal(defel->arg);
163+
o_label = true;
164+
}
165+
else if (strcmp(defel->defname, "progress") == 0)
166+
{
167+
if (o_progress)
168+
ereport(ERROR,
169+
(errcode(ERRCODE_SYNTAX_ERROR),
170+
errmsg("duplicate option \"%s\"", defel->defname)));
171+
opt->progress = true;
172+
o_progress = true;
173+
}
174+
else if (strcmp(defel->defname, "fast") == 0)
175+
{
176+
if (o_fast)
177+
ereport(ERROR,
178+
(errcode(ERRCODE_SYNTAX_ERROR),
179+
errmsg("duplicate option \"%s\"", defel->defname)));
180+
opt->fastcheckpoint = true;
181+
o_fast = true;
182+
}
183+
else
184+
elog(ERROR, "option \"%s\" not recognized",
185+
defel->defname);
186+
}
187+
if (opt->label == NULL)
188+
opt->label = "base backup";
189+
}
190+
191+
131192
/*
132193
* SendBaseBackup() - send a complete base backup.
133194
*
134195
* The function will take care of running pg_start_backup() and
135196
* pg_stop_backup() for the user.
136197
*/
137198
void
138-
SendBaseBackup(const char *backup_label, bool progress, bool fastcheckpoint)
199+
SendBaseBackup(BaseBackupCmd *cmd)
139200
{
140201
DIR *dir;
141202
MemoryContext backup_context;
142203
MemoryContext old_context;
204+
basebackup_options opt;
205+
206+
parse_basebackup_options(cmd->options, &opt);
143207

144208
backup_context = AllocSetContextCreate(CurrentMemoryContext,
145209
"Streaming base backup context",
@@ -150,15 +214,12 @@ SendBaseBackup(const char *backup_label, bool progress, bool fastcheckpoint)
150214

151215
WalSndSetState(WALSNDSTATE_BACKUP);
152216

153-
if (backup_label == NULL)
154-
backup_label = "base backup";
155-
156217
if (update_process_title)
157218
{
158219
char activitymsg[50];
159220

160221
snprintf(activitymsg, sizeof(activitymsg), "sending backup \"%s\"",
161-
backup_label);
222+
opt.label);
162223
set_ps_display(activitymsg, false);
163224
}
164225

@@ -168,7 +229,7 @@ SendBaseBackup(const char *backup_label, bool progress, bool fastcheckpoint)
168229
ereport(ERROR,
169230
(errmsg("unable to open directory pg_tblspc: %m")));
170231

171-
perform_base_backup(backup_label, progress, dir, fastcheckpoint);
232+
perform_base_backup(&opt, dir);
172233

173234
FreeDir(dir);
174235

src/backend/replication/repl_gram.y

+27-18
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
#include "postgres.h"
1717

18+
#include "nodes/makefuncs.h"
19+
#include "nodes/parsenodes.h"
1820
#include "replication/replnodes.h"
1921
#include "replication/walsender.h"
2022

@@ -55,6 +57,8 @@ Node *replication_parse_result;
5557

5658
XLogRecPtr recptr;
5759
Node *node;
60+
List *list;
61+
DefElem *defelt;
5862
}
5963

6064
/* Non-keyword tokens */
@@ -71,9 +75,8 @@ Node *replication_parse_result;
7175

7276
%type <node> command
7377
%type <node> base_backup start_replication identify_system
74-
%type <boolval> opt_progress opt_fast
75-
%type <str> opt_label
76-
78+
%type <list> base_backup_opt_list
79+
%type <defelt> base_backup_opt
7780
%%
7881

7982
firstcmd: command opt_semicolon
@@ -106,28 +109,34 @@ identify_system:
106109
* BASE_BACKUP [LABEL <label>] [PROGRESS] [FAST]
107110
*/
108111
base_backup:
109-
K_BASE_BACKUP opt_label opt_progress opt_fast
112+
K_BASE_BACKUP base_backup_opt_list
110113
{
111114
BaseBackupCmd *cmd = (BaseBackupCmd *) makeNode(BaseBackupCmd);
112-
113-
cmd->label = $2;
114-
cmd->progress = $3;
115-
cmd->fastcheckpoint = $4;
116-
115+
cmd->options = $2;
117116
$$ = (Node *) cmd;
118117
}
119118
;
120119

121-
opt_label: K_LABEL SCONST { $$ = $2; }
122-
| /* EMPTY */ { $$ = NULL; }
123-
;
120+
base_backup_opt_list: base_backup_opt_list base_backup_opt { $$ = lappend($1, $2); }
121+
| /* EMPTY */ { $$ = NIL; }
122+
123+
base_backup_opt:
124+
K_LABEL SCONST
125+
{
126+
$$ = makeDefElem("label",
127+
(Node *)makeString($2));
128+
}
129+
| K_PROGRESS
130+
{
131+
$$ = makeDefElem("progress",
132+
(Node *)makeInteger(TRUE));
133+
}
134+
| K_FAST
135+
{
136+
$$ = makeDefElem("fast",
137+
(Node *)makeInteger(TRUE));
138+
}
124139

125-
opt_progress: K_PROGRESS { $$ = true; }
126-
| /* EMPTY */ { $$ = false; }
127-
;
128-
opt_fast: K_FAST { $$ = true; }
129-
| /* EMPTY */ { $$ = false; }
130-
;
131140

132141
/*
133142
* START_REPLICATION %X/%X

src/backend/replication/walsender.c

+6-10
Original file line numberDiff line numberDiff line change
@@ -399,17 +399,13 @@ HandleReplicationCommand(const char *cmd_string)
399399
break;
400400

401401
case T_BaseBackupCmd:
402-
{
403-
BaseBackupCmd *cmd = (BaseBackupCmd *) cmd_node;
404-
405-
SendBaseBackup(cmd->label, cmd->progress, cmd->fastcheckpoint);
402+
SendBaseBackup((BaseBackupCmd *) cmd_node);
406403

407-
/* Send CommandComplete and ReadyForQuery messages */
408-
EndCommand("SELECT", DestRemote);
409-
ReadyForQuery(DestRemote);
410-
/* ReadyForQuery did pq_flush for us */
411-
break;
412-
}
404+
/* Send CommandComplete and ReadyForQuery messages */
405+
EndCommand("SELECT", DestRemote);
406+
ReadyForQuery(DestRemote);
407+
/* ReadyForQuery did pq_flush for us */
408+
break;
413409

414410
default:
415411
ereport(FATAL,

src/include/replication/basebackup.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#ifndef _BASEBACKUP_H
1313
#define _BASEBACKUP_H
1414

15-
extern void SendBaseBackup(const char *backup_label, bool progress, bool fastcheckpoint);
15+
#include "replication/replnodes.h"
16+
17+
extern void SendBaseBackup(BaseBackupCmd *cmd);
1618

1719
#endif /* _BASEBACKUP_H */

src/include/replication/replnodes.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ typedef struct IdentifySystemCmd
4545
typedef struct BaseBackupCmd
4646
{
4747
NodeTag type;
48-
char *label;
49-
bool progress;
50-
bool fastcheckpoint;
48+
List *options;
5149
} BaseBackupCmd;
5250

5351

0 commit comments

Comments
 (0)