Skip to content

Commit 4c8044c

Browse files
committed
pg_waldump: Allow hexadecimal values for -t/--timeline option
This makes it easier to specify values taken directly from WAL file names. The option parsing is arranged in the style of option_parse_int() (but we need to parse unsigned int), to allow future refactoring in the same manner. Reviewed-by: Sébastien Lardière <sebastien@lardiere.net> Discussion: https://www.postgresql.org/message-id/flat/8fef346e-2541-76c3-d768-6536ae052993@lardiere.net
1 parent b797def commit 4c8044c

File tree

2 files changed

+35
-5
lines changed

2 files changed

+35
-5
lines changed

doc/src/sgml/ref/pg_waldump.sgml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ PostgreSQL documentation
215215
<para>
216216
Timeline from which to read WAL records. The default is to use the
217217
value in <replaceable>startseg</replaceable>, if that is specified; otherwise, the
218-
default is 1.
218+
default is 1. The value can be specified in decimal or hexadecimal,
219+
for example <literal>17</literal> or <literal>0x11</literal>.
219220
</para>
220221
</listitem>
221222
</varlistentry>

src/bin/pg_waldump/pg_waldump.c

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "postgres.h"
1414

1515
#include <dirent.h>
16+
#include <limits.h>
1617
#include <signal.h>
1718
#include <sys/stat.h>
1819
#include <unistd.h>
@@ -1007,12 +1008,40 @@ main(int argc, char **argv)
10071008
private.startptr = (uint64) xlogid << 32 | xrecoff;
10081009
break;
10091010
case 't':
1010-
if (sscanf(optarg, "%u", &private.timeline) != 1)
1011+
1012+
/*
1013+
* This is like option_parse_int() but needs to handle
1014+
* unsigned 32-bit int. Also, we accept both decimal and
1015+
* hexadecimal specifications here.
1016+
*/
10111017
{
1012-
pg_log_error("invalid timeline specification: \"%s\"", optarg);
1013-
goto bad_argument;
1018+
char *endptr;
1019+
unsigned long val;
1020+
1021+
errno = 0;
1022+
val = strtoul(optarg, &endptr, 0);
1023+
1024+
while (*endptr != '\0' && isspace((unsigned char) *endptr))
1025+
endptr++;
1026+
1027+
if (*endptr != '\0')
1028+
{
1029+
pg_log_error("invalid value \"%s\" for option %s",
1030+
optarg, "-t/--timeline");
1031+
goto bad_argument;
1032+
}
1033+
1034+
if (errno == ERANGE || val < 1 || val > UINT_MAX)
1035+
{
1036+
pg_log_error("%s must be in range %u..%u",
1037+
"-t/--timeline", 1, UINT_MAX);
1038+
goto bad_argument;
1039+
}
1040+
1041+
private.timeline = val;
1042+
1043+
break;
10141044
}
1015-
break;
10161045
case 'w':
10171046
config.filter_by_fpw = true;
10181047
break;

0 commit comments

Comments
 (0)