mirror of
https://github.com/postgres/postgres.git
synced 2025-07-02 09:02:37 +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:
@ -20,7 +20,7 @@
|
||||
#endif
|
||||
|
||||
#include "common/archive.h"
|
||||
#include "lib/stringinfo.h"
|
||||
#include "common/percentrepl.h"
|
||||
|
||||
/*
|
||||
* BuildRestoreCommand
|
||||
@ -41,81 +41,20 @@ BuildRestoreCommand(const char *restoreCommand,
|
||||
const char *xlogfname,
|
||||
const char *lastRestartPointFname)
|
||||
{
|
||||
StringInfoData result;
|
||||
const char *sp;
|
||||
char *nativePath = NULL;
|
||||
char *result;
|
||||
|
||||
/*
|
||||
* Build the command to be executed.
|
||||
*/
|
||||
initStringInfo(&result);
|
||||
|
||||
for (sp = restoreCommand; *sp; sp++)
|
||||
if (xlogpath)
|
||||
{
|
||||
if (*sp == '%')
|
||||
{
|
||||
switch (sp[1])
|
||||
{
|
||||
case 'p':
|
||||
{
|
||||
char *nativePath;
|
||||
|
||||
/* %p: relative path of target file */
|
||||
if (xlogpath == NULL)
|
||||
{
|
||||
pfree(result.data);
|
||||
return NULL;
|
||||
}
|
||||
sp++;
|
||||
|
||||
/*
|
||||
* This needs to use a placeholder to not modify the
|
||||
* input with the conversion done via
|
||||
* make_native_path().
|
||||
*/
|
||||
nativePath = pstrdup(xlogpath);
|
||||
make_native_path(nativePath);
|
||||
appendStringInfoString(&result,
|
||||
nativePath);
|
||||
pfree(nativePath);
|
||||
break;
|
||||
}
|
||||
case 'f':
|
||||
/* %f: filename of desired file */
|
||||
if (xlogfname == NULL)
|
||||
{
|
||||
pfree(result.data);
|
||||
return NULL;
|
||||
}
|
||||
sp++;
|
||||
appendStringInfoString(&result, xlogfname);
|
||||
break;
|
||||
case 'r':
|
||||
/* %r: filename of last restartpoint */
|
||||
if (lastRestartPointFname == NULL)
|
||||
{
|
||||
pfree(result.data);
|
||||
return NULL;
|
||||
}
|
||||
sp++;
|
||||
appendStringInfoString(&result,
|
||||
lastRestartPointFname);
|
||||
break;
|
||||
case '%':
|
||||
/* convert %% to a single % */
|
||||
sp++;
|
||||
appendStringInfoChar(&result, *sp);
|
||||
break;
|
||||
default:
|
||||
/* otherwise treat the % as not special */
|
||||
appendStringInfoChar(&result, *sp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
appendStringInfoChar(&result, *sp);
|
||||
}
|
||||
nativePath = pstrdup(xlogpath);
|
||||
make_native_path(nativePath);
|
||||
}
|
||||
|
||||
return result.data;
|
||||
result = replace_percent_placeholders(restoreCommand, "restore_command", "frp",
|
||||
xlogfname, lastRestartPointFname, nativePath);
|
||||
|
||||
if (nativePath)
|
||||
pfree(nativePath);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
Reference in New Issue
Block a user