Skip to content

Commit ae45312

Browse files
committed
Change pg_lsn_in_internal() to use soft error reporting
pg_lsn includes pg_lsn_in_internal() for the purpose of parsing a LSN position for the GUC recovery_target_lsn (21f428e). It relies on a boolean called "have_error" that would be set when the LSN parsing fails, then let its callers handle any errors. d9f7f5d has added support for soft error reporting. This commit removes some boilerplate code and switches the routine to use soft error reporting directly, giving to the callers of pg_lsn_in_internal() the possibility to be fed the error message generated on failure. pg_lsn_in_internal() routine is renamed to pg_lsn_in_safe(), for consistency with other similar routines that are given an escontext. Author: Amul Sul <sulamul@gmail.com> Reviewed-by: Dean Rasheed <dean.a.rasheed@gmail.com> Discussion: https://postgr.es/m/CAAJ_b96No5h5tRuR+KhcC44YcYUCw8WAHuLoqqyyop8_k3+JDQ@mail.gmail.com
1 parent d814d7f commit ae45312

File tree

3 files changed

+22
-24
lines changed

3 files changed

+22
-24
lines changed

src/backend/access/transam/xlogrecovery.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4834,10 +4834,10 @@ check_recovery_target_lsn(char **newval, void **extra, GucSource source)
48344834
{
48354835
XLogRecPtr lsn;
48364836
XLogRecPtr *myextra;
4837-
bool have_error = false;
4837+
ErrorSaveContext escontext = {T_ErrorSaveContext};
48384838

4839-
lsn = pg_lsn_in_internal(*newval, &have_error);
4840-
if (have_error)
4839+
lsn = pg_lsn_in_safe(*newval, (Node *) &escontext);
4840+
if (escontext.error_occurred)
48414841
return false;
48424842

48434843
myextra = (XLogRecPtr *) guc_malloc(LOG, sizeof(XLogRecPtr));

src/backend/utils/adt/pg_lsn.c

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,53 +25,48 @@
2525
* Formatting and conversion routines.
2626
*---------------------------------------------------------*/
2727

28+
/*
29+
* Internal version of pg_lsn_in() with support for soft error reporting.
30+
*/
2831
XLogRecPtr
29-
pg_lsn_in_internal(const char *str, bool *have_error)
32+
pg_lsn_in_safe(const char *str, Node *escontext)
3033
{
3134
int len1,
3235
len2;
3336
uint32 id,
3437
off;
3538
XLogRecPtr result;
3639

37-
Assert(have_error != NULL);
38-
*have_error = false;
39-
4040
/* Sanity check input format. */
4141
len1 = strspn(str, "0123456789abcdefABCDEF");
4242
if (len1 < 1 || len1 > MAXPG_LSNCOMPONENT || str[len1] != '/')
43-
{
44-
*have_error = true;
45-
return InvalidXLogRecPtr;
46-
}
43+
goto syntax_error;
44+
4745
len2 = strspn(str + len1 + 1, "0123456789abcdefABCDEF");
4846
if (len2 < 1 || len2 > MAXPG_LSNCOMPONENT || str[len1 + 1 + len2] != '\0')
49-
{
50-
*have_error = true;
51-
return InvalidXLogRecPtr;
52-
}
47+
goto syntax_error;
5348

5449
/* Decode result. */
5550
id = (uint32) strtoul(str, NULL, 16);
5651
off = (uint32) strtoul(str + len1 + 1, NULL, 16);
5752
result = ((uint64) id << 32) | off;
5853

5954
return result;
55+
56+
syntax_error:
57+
ereturn(escontext, InvalidXLogRecPtr,
58+
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
59+
errmsg("invalid input syntax for type %s: \"%s\"",
60+
"pg_lsn", str)));
6061
}
6162

6263
Datum
6364
pg_lsn_in(PG_FUNCTION_ARGS)
6465
{
6566
char *str = PG_GETARG_CSTRING(0);
6667
XLogRecPtr result;
67-
bool have_error = false;
68-
69-
result = pg_lsn_in_internal(str, &have_error);
70-
if (have_error)
71-
ereturn(fcinfo->context, (Datum) 0,
72-
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
73-
errmsg("invalid input syntax for type %s: \"%s\"",
74-
"pg_lsn", str)));
68+
69+
result = pg_lsn_in_safe(str, fcinfo->context);
7570

7671
PG_RETURN_LSN(result);
7772
}

src/include/utils/pg_lsn.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
#include "access/xlogdefs.h"
1919
#include "fmgr.h"
2020

21+
/* forward declaration to avoid node.h include */
22+
typedef struct Node Node;
23+
2124
static inline XLogRecPtr
2225
DatumGetLSN(Datum X)
2326
{
@@ -33,6 +36,6 @@ LSNGetDatum(XLogRecPtr X)
3336
#define PG_GETARG_LSN(n) DatumGetLSN(PG_GETARG_DATUM(n))
3437
#define PG_RETURN_LSN(x) return LSNGetDatum(x)
3538

36-
extern XLogRecPtr pg_lsn_in_internal(const char *str, bool *have_error);
39+
extern XLogRecPtr pg_lsn_in_safe(const char *str, Node *escontext);
3740

3841
#endif /* PG_LSN_H */

0 commit comments

Comments
 (0)