Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5f3cec7

Browse files
committed
Avoid crash after function syntax error in a replication worker.
If a syntax error occurred in a SQL-language or PL/pgSQL-language CREATE FUNCTION or DO command executed in a logical replication worker, we'd suffer a null pointer dereference or assertion failure. That seems like a rather contrived case, but nonetheless worth fixing. The cause is that function_parse_error_transpose assumes it must be executing within the context of a Portal, but logical/worker.c doesn't create a Portal since it's not running the standard executor. We can just back off the hard Assert check and make it fail gracefully if there's not an ActivePortal. (I have a feeling that the aggressive check here was my fault originally, probably because I wasn't sure if the case would always hold and wanted to find out. Well, now we know.) The hazard seems to exist in all branches that have logical replication, so back-patch to v10. Maxim Orlov, Anton Melnikov, Masahiko Sawada, Tom Lane Discussion: https://postgr.es/m/[email protected] Discussion: https://postgr.es/m/[email protected]
1 parent 19cefeb commit 5f3cec7

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

src/backend/catalog/pg_proc.c

+15-5
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,6 @@ function_parse_error_transpose(const char *prosrc)
977977
{
978978
int origerrposition;
979979
int newerrposition;
980-
const char *queryText;
981980

982981
/*
983982
* Nothing to do unless we are dealing with a syntax error that has a
@@ -995,11 +994,22 @@ function_parse_error_transpose(const char *prosrc)
995994
}
996995

997996
/* We can get the original query text from the active portal (hack...) */
998-
Assert(ActivePortal && ActivePortal->status == PORTAL_ACTIVE);
999-
queryText = ActivePortal->sourceText;
997+
if (ActivePortal && ActivePortal->status == PORTAL_ACTIVE)
998+
{
999+
const char *queryText = ActivePortal->sourceText;
10001000

1001-
/* Try to locate the prosrc in the original text */
1002-
newerrposition = match_prosrc_to_query(prosrc, queryText, origerrposition);
1001+
/* Try to locate the prosrc in the original text */
1002+
newerrposition = match_prosrc_to_query(prosrc, queryText,
1003+
origerrposition);
1004+
}
1005+
else
1006+
{
1007+
/*
1008+
* Quietly give up if no ActivePortal. This is an unusual situation
1009+
* but it can happen in, e.g., logical replication workers.
1010+
*/
1011+
newerrposition = -1;
1012+
}
10031013

10041014
if (newerrposition > 0)
10051015
{

0 commit comments

Comments
 (0)