From bf64a37909cd25e2e14c47de922a51d205795d17 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 11 Jun 2006 15:49:28 +0000 Subject: Fix Assert failure when a fastpath function call is attempted inside an already-aborted transaction block. GetSnapshotData throws an Assert if not in a valid transaction; hence we mustn't attempt to set a snapshot for the function until after checking for aborted transaction. This is harmless AFAICT if Asserts aren't enabled (GetSnapshotData will compute a bogus snapshot, but it doesn't matter since HandleFunctionRequest will throw an error shortly anywy). Hence, not a major bug. Along the way, add some ability to log fastpath calls when statement logging is turned on. This could probably stand to be improved further, but not logging anything is clearly undesirable. Backpatched as far as 8.0; bug doesn't exist before that. --- src/backend/tcop/fastpath.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/backend/tcop/fastpath.c') diff --git a/src/backend/tcop/fastpath.c b/src/backend/tcop/fastpath.c index c9fa715600f..3f769d9a9ad 100644 --- a/src/backend/tcop/fastpath.c +++ b/src/backend/tcop/fastpath.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tcop/fastpath.c,v 1.86 2006/04/04 19:35:35 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/tcop/fastpath.c,v 1.87 2006/06/11 15:49:28 tgl Exp $ * * NOTES * This cruft is the server side of PQfn. @@ -26,6 +26,7 @@ #include "miscadmin.h" #include "mb/pg_wchar.h" #include "tcop/fastpath.h" +#include "tcop/tcopprot.h" #include "utils/acl.h" #include "utils/lsyscache.h" #include "utils/syscache.h" @@ -299,14 +300,25 @@ HandleFunctionRequest(StringInfo msgBuf) errmsg("current transaction is aborted, " "commands ignored until end of transaction block"))); + /* + * Now that we know we are in a valid transaction, set snapshot in + * case needed by function itself or one of the datatype I/O routines. + */ + ActiveSnapshot = CopySnapshot(GetTransactionSnapshot()); + /* * Begin parsing the buffer contents. */ if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3) - (void) pq_getmsgstring(msgBuf); /* dummy string */ + (void) pq_getmsgstring(msgBuf); /* dummy string */ fid = (Oid) pq_getmsgint(msgBuf, 4); /* function oid */ + if (log_statement == LOGSTMT_ALL) + ereport(LOG, + (errmsg("fastpath function call: function OID %u", + fid))); + /* * There used to be a lame attempt at caching lookup info here. Now we * just do the lookups on every call. -- cgit v1.2.3