pg_waldump: Allow hexadecimal values for -t/--timeline option
authorPeter Eisentraut
Tue, 21 Mar 2023 07:01:12 +0000 (08:01 +0100)
committerPeter Eisentraut
Tue, 21 Mar 2023 07:05:23 +0000 (08:05 +0100)
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
Discussion: https://www.postgresql.org/message-id/flat/8fef346e-2541-76c3-d768-6536ae052993@lardiere.net

doc/src/sgml/ref/pg_waldump.sgml
src/bin/pg_waldump/pg_waldump.c

index 343f0482a9f6999c29f853634108ea6cac7a6c4e..7685d3d15b98ff8504fc96f75874a8e23f809aee 100644 (file)
@@ -215,7 +215,8 @@ PostgreSQL documentation
        
         Timeline from which to read WAL records. The default is to use the
         value in startseg, if that is specified; otherwise, the
-        default is 1.
+        default is 1.  The value can be specified in decimal or hexadecimal,
+        for example 17 or 0x11.
        
       
      
index 44b5c8726e653d1e8378b8f5d27886e464722c92..8630000ef0b6c23a66d73415cbe7c3df20e4e4dc 100644 (file)
@@ -13,6 +13,7 @@
 #include "postgres.h"
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1007,12 +1008,40 @@ main(int argc, char **argv)
                    private.startptr = (uint64) xlogid << 32 | xrecoff;
                break;
            case 't':
-               if (sscanf(optarg, "%u", &private.timeline) != 1)
+
+               /*
+                * This is like option_parse_int() but needs to handle
+                * unsigned 32-bit int.  Also, we accept both decimal and
+                * hexadecimal specifications here.
+                */
                {
-                   pg_log_error("invalid timeline specification: \"%s\"", optarg);
-                   goto bad_argument;
+                   char       *endptr;
+                   unsigned long val;
+
+                   errno = 0;
+                   val = strtoul(optarg, &endptr, 0);
+
+                   while (*endptr != '\0' && isspace((unsigned char) *endptr))
+                       endptr++;
+
+                   if (*endptr != '\0')
+                   {
+                       pg_log_error("invalid value \"%s\" for option %s",
+                                    optarg, "-t/--timeline");
+                       goto bad_argument;
+                   }
+
+                   if (errno == ERANGE || val < 1 || val > UINT_MAX)
+                   {
+                       pg_log_error("%s must be in range %u..%u",
+                                    "-t/--timeline", 1, UINT_MAX);
+                       goto bad_argument;
+                   }
+
+                   private.timeline = val;
+
+                   break;
                }
-               break;
            case 'w':
                config.filter_by_fpw = true;
                break;