diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2007-01-30 18:02:22 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2007-01-30 18:02:22 +0000 |
commit | 33d78c9e48d8d096f606c169413ca3d56b9c9b2c (patch) | |
tree | 339a28912bd8f479fa884adf9b2bacdbc95ab237 /src | |
parent | ae875d318ec160cc0042e17560254928a5ed863c (diff) | |
download | postgresql-33d78c9e48d8d096f606c169413ca3d56b9c9b2c.tar.gz postgresql-33d78c9e48d8d096f606c169413ca3d56b9c9b2c.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/pl/plpgsql/src/pl_exec.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 67bcbf0cc40..8a9c0093c5b 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(); } } |