1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-11 20:28:21 +03:00

Common function for percent placeholder replacement

There are a number of places where a shell command is constructed with
percent-placeholders (like %x).  It's cumbersome to have to open-code
this several times.  This factors out this logic into a separate
function.  This also allows us to ensure consistency for and document
some subtle behaviors, such as what to do with unrecognized
placeholders.

The unified handling is now that incorrect and unknown placeholders
are an error, where previously in most cases they were skipped or
ignored.  This affects the following settings:

- archive_cleanup_command
- archive_command
- recovery_end_command
- restore_command
- ssl_passphrase_command

The following settings are part of this refactoring but already had
stricter error handling and should be unchanged in their behavior:

- basebackup_to_shell.command

Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/5238bbed-0b01-83a6-d4b2-7eb0562a054e%40enterprisedb.com
This commit is contained in:
Peter Eisentraut
2023-01-11 07:22:51 +01:00
parent 5f6401f81c
commit c96de2ce17
10 changed files with 199 additions and 247 deletions

View File

@ -12,6 +12,7 @@
#include "access/xact.h"
#include "backup/basebackup_target.h"
#include "common/percentrepl.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/acl.h"
@ -208,59 +209,8 @@ static char *
shell_construct_command(const char *base_command, const char *filename,
const char *target_detail)
{
StringInfoData buf;
const char *c;
initStringInfo(&buf);
for (c = base_command; *c != '\0'; ++c)
{
/* Anything other than '%' is copied verbatim. */
if (*c != '%')
{
appendStringInfoChar(&buf, *c);
continue;
}
/* Any time we see '%' we eat the following character as well. */
++c;
/*
* The following character determines what we insert here, or may
* cause us to throw an error.
*/
if (*c == '%')
{
/* '%%' is replaced by a single '%' */
appendStringInfoChar(&buf, '%');
}
else if (*c == 'f')
{
/* '%f' is replaced by the filename */
appendStringInfoString(&buf, filename);
}
else if (*c == 'd')
{
/* '%d' is replaced by the target detail */
appendStringInfoString(&buf, target_detail);
}
else if (*c == '\0')
{
/* Incomplete escape sequence, expected a character afterward */
ereport(ERROR,
errcode(ERRCODE_SYNTAX_ERROR),
errmsg("shell command ends unexpectedly after escape character \"%%\""));
}
else
{
/* Unknown escape sequence */
ereport(ERROR,
errcode(ERRCODE_SYNTAX_ERROR),
errmsg("shell command contains unexpected escape sequence \"%c\"",
*c));
}
}
return buf.data;
return replace_percent_placeholders(base_command, "basebackup_to_shell.command",
"df", target_detail, filename);
}
/*