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

Don't call data type input functions in GUC check hooks

Instead of calling pg_lsn_in() in check_recovery_target_lsn and
timestamptz_in() in check_recovery_target_time, reorganize the
respective code so that we don't raise any errors in the check hooks.
The previous code tried to use PG_TRY/PG_CATCH to handle errors in a
way that is not safe, so now the code contains no ereport() calls and
can operate safely within the GUC error handling system.

Moreover, since the interpretation of the recovery_target_time string
may depend on the time zone, we cannot do the final processing of that
string until all the GUC processing is done.  Instead,
check_recovery_target_time() now does some parsing for syntax
checking, but the actual conversion to a timestamptz value is done
later in the recovery code that uses it.

Reported-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://www.postgresql.org/message-id/flat/20190611061115.njjwkagvxp4qujhp%40alap3.anarazel.de
This commit is contained in:
Peter Eisentraut
2019-06-30 10:15:25 +02:00
parent 666cbae16d
commit 21f428ebde
5 changed files with 85 additions and 74 deletions

View File

@@ -25,10 +25,9 @@
* Formatting and conversion routines.
*---------------------------------------------------------*/
Datum
pg_lsn_in(PG_FUNCTION_ARGS)
XLogRecPtr
pg_lsn_in_internal(const char *str, bool *have_error)
{
char *str = PG_GETARG_CSTRING(0);
int len1,
len2;
uint32 id,
@@ -38,16 +37,16 @@ pg_lsn_in(PG_FUNCTION_ARGS)
/* Sanity check input format. */
len1 = strspn(str, "0123456789abcdefABCDEF");
if (len1 < 1 || len1 > MAXPG_LSNCOMPONENT || str[len1] != '/')
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type %s: \"%s\"",
"pg_lsn", str)));
{
*have_error = true;
return InvalidXLogRecPtr;
}
len2 = strspn(str + len1 + 1, "0123456789abcdefABCDEF");
if (len2 < 1 || len2 > MAXPG_LSNCOMPONENT || str[len1 + 1 + len2] != '\0')
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type %s: \"%s\"",
"pg_lsn", str)));
{
*have_error = true;
return InvalidXLogRecPtr;
}
/* Decode result. */
id = (uint32) strtoul(str, NULL, 16);
@@ -57,6 +56,23 @@ pg_lsn_in(PG_FUNCTION_ARGS)
PG_RETURN_LSN(result);
}
Datum
pg_lsn_in(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
XLogRecPtr result;
bool have_error = false;
result = pg_lsn_in_internal(str, &have_error);
if (have_error)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type %s: \"%s\"",
"pg_lsn", str)));
PG_RETURN_LSN(result);
}
Datum
pg_lsn_out(PG_FUNCTION_ARGS)
{