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:
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user