Skip to content

Commit b90e568

Browse files
tglsfdcreshke
authored andcommitted
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/b570c367-ba38-95f3-f62d-5f59b9808226@inbox.ru Discussion: https://postgr.es/m/adf0452f-8c6b-7def-d35e-ab516c80088e@inbox.ru
1 parent a6983fa commit b90e568

1 file changed

Lines changed: 15 additions & 4 deletions

File tree

src/backend/catalog/pg_proc.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,7 +1087,6 @@ function_parse_error_transpose(const char *prosrc)
10871087
{
10881088
int origerrposition;
10891089
int newerrposition;
1090-
const char *queryText;
10911090

10921091
/*
10931092
* Nothing to do unless we are dealing with a syntax error that has a
@@ -1106,10 +1105,22 @@ function_parse_error_transpose(const char *prosrc)
11061105

11071106
/* We can get the original query text from the active portal (hack...) */
11081107
/* Assert(ActivePortal && PortalGetStatus(ActivePortal) == PORTAL_ACTIVE); */
1109-
queryText = ActivePortal->sourceText;
1108+
if (ActivePortal && ActivePortal->status == PORTAL_ACTIVE)
1109+
{
1110+
const char *queryText = ActivePortal->sourceText;
11101111

1111-
/* Try to locate the prosrc in the original text */
1112-
newerrposition = match_prosrc_to_query(prosrc, queryText, origerrposition);
1112+
/* Try to locate the prosrc in the original text */
1113+
newerrposition = match_prosrc_to_query(prosrc, queryText,
1114+
origerrposition);
1115+
}
1116+
else
1117+
{
1118+
/*
1119+
* Quietly give up if no ActivePortal. This is an unusual situation
1120+
* but it can happen in, e.g., logical replication workers.
1121+
*/
1122+
newerrposition = -1;
1123+
}
11131124

11141125
if (newerrposition > 0)
11151126
{

0 commit comments

Comments
 (0)