From 33d78c9e48d8d096f606c169413ca3d56b9c9b2c Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 30 Jan 2007 18:02:22 +0000 Subject: [PATCH] Add SPI_push/SPI_pop calls so that datatype input and output functions called by plpgsql can themselves use SPI --- possibly indirectly, as in the case of domain_in() invoking plpgsql functions in a domain check constraint. Per bug #2945 from Sergiy Vyshnevetskiy. Somewhat arbitrarily, I've chosen to back-patch this as far as 8.0. Given the lack of prior complaints, it doesn't seem critical for 7.x. --- src/pl/plpgsql/src/pl_exec.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 67bcbf0cc4..8a9c0093c5 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.185 2007/01/28 17:58:13 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.186 2007/01/30 18:02:22 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -4282,12 +4282,27 @@ make_tuple_from_row(PLpgSQL_execstate *estate, static char * convert_value_to_string(Datum value, Oid valtype) { + char *str; Oid typoutput; bool typIsVarlena; getTypeOutputInfo(valtype, &typoutput, &typIsVarlena); - return OidOutputFunctionCall(typoutput, value); + /* + * We do SPI_push to allow the datatype output function to use SPI. + * However we do not mess around with CommandCounterIncrement or advancing + * the snapshot, which means that a stable output function would not see + * updates made so far by our own function. The use-case for such + * scenarios seems too narrow to justify the cycles that would be + * expended. + */ + SPI_push(); + + str = OidOutputFunctionCall(typoutput, value); + + SPI_pop(); + + return str; } /* ---------- @@ -4313,14 +4328,25 @@ exec_cast_value(Datum value, Oid valtype, char *extval; extval = convert_value_to_string(value, valtype); + + /* Allow input function to use SPI ... see notes above */ + SPI_push(); + value = InputFunctionCall(reqinput, extval, reqtypioparam, reqtypmod); + + SPI_pop(); + pfree(extval); } else { + SPI_push(); + value = InputFunctionCall(reqinput, NULL, reqtypioparam, reqtypmod); + + SPI_pop(); } } -- 2.11.0