Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4cafef5

Browse files
committed
Do not execute fastpath function calls if in transaction ABORT state.
Just like queries, doing nothing is better than possibly getting weird error messages. Also, improve comments.
1 parent b0c1c53 commit 4cafef5

File tree

1 file changed

+46
-14
lines changed

1 file changed

+46
-14
lines changed

src/backend/tcop/fastpath.c

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.43 2000/07/03 23:09:46 wieck Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.44 2000/10/24 20:59:35 tgl Exp $
1212
*
1313
* NOTES
1414
* This cruft is the server side of PQfn.
@@ -271,9 +271,14 @@ update_fp_info(Oid func_id, struct fp_info * fip)
271271
* Note: All ordinary errors result in elog(ERROR,...). However,
272272
* if we lose the frontend connection there is no one to elog to,
273273
* and no use in proceeding...
274+
*
275+
* Note: palloc()s done here and in the called function do not need to be
276+
* cleaned up explicitly. We are called from PostgresMain() in the
277+
* QueryContext memory context, which will be automatically reset when
278+
* control returns to PostgresMain.
274279
*/
275280
int
276-
HandleFunctionRequest()
281+
HandleFunctionRequest(void)
277282
{
278283
Oid fid;
279284
int argsize;
@@ -285,6 +290,32 @@ HandleFunctionRequest()
285290
char *p;
286291
struct fp_info *fip;
287292

293+
/*
294+
* XXX FIXME: This protocol is misdesigned.
295+
*
296+
* We really do not want to elog() before having swallowed all of the
297+
* frontend's fastpath message; otherwise we will lose sync with the input
298+
* datastream. What should happen is we absorb all of the input message
299+
* per protocol syntax, and *then* do error checking (including lookup of
300+
* the given function ID) and elog if appropriate. Unfortunately, because
301+
* we cannot even read the message properly without knowing whether the
302+
* data types are pass-by-ref or pass-by-value, it's not all that easy to
303+
* do :-(. The protocol should require the client to supply what it
304+
* thinks is the typbyval and typlen value for each arg, so that we can
305+
* read the data without having to do any lookups. Then after we've read
306+
* the message, we should do the lookups, verify agreement of the actual
307+
* function arg types with what we received, and finally call the function.
308+
*
309+
* As things stand, not only will we lose sync for an invalid message
310+
* (such as requested function OID doesn't exist), but we may lose sync
311+
* for a perfectly valid message if we are in transaction-aborted state!
312+
* This can happen because our database lookup attempts may fail entirely
313+
* in abort state.
314+
*
315+
* Unfortunately I see no way to fix this without breaking a lot of
316+
* existing clients. Maybe do it as part of next protocol version change.
317+
*/
318+
288319
if (pq_getint(&tmp, 4)) /* function oid */
289320
return EOF;
290321
fid = (Oid) tmp;
@@ -293,23 +324,13 @@ HandleFunctionRequest()
293324

294325
/*
295326
* This is where the one-back caching is done. If you want to save
296-
* more state, make this a loop around an array.
327+
* more state, make this a loop around an array. Given the relatively
328+
* short lifespan of the cache, not clear that there's any win possible.
297329
*/
298330
fip = &last_fp;
299331
if (!valid_fp_info(fid, fip))
300332
update_fp_info(fid, fip);
301333

302-
/*
303-
* XXX FIXME: elog() here means we lose sync with the frontend, since
304-
* we have not swallowed all of its input message. What should happen
305-
* is we absorb all of the input message per protocol syntax, and
306-
* *then* do error checking (including lookup of the given function ID)
307-
* and elog if appropriate. Unfortunately, because we cannot even read
308-
* the message properly without knowing whether the data types are
309-
* pass-by-ref or pass-by-value, it's not all that easy to fix :-(.
310-
* This protocol is misdesigned.
311-
*/
312-
313334
if (fip->flinfo.fn_nargs != nargs || nargs > FUNC_MAX_ARGS)
314335
{
315336
elog(ERROR, "HandleFunctionRequest: actual arguments (%d) != registered arguments (%d)",
@@ -366,6 +387,17 @@ HandleFunctionRequest()
366387
}
367388
}
368389

390+
/*
391+
* Now that we've eaten the input message, check to see if we actually
392+
* want to do the function call or not.
393+
*
394+
* Currently, we report an error if in ABORT state, or return a dummy
395+
* NULL response if fastpath support has been compiled out.
396+
*/
397+
if (IsAbortedTransactionBlockState())
398+
elog(ERROR, "current transaction is aborted, "
399+
"queries ignored until end of transaction block");
400+
369401
#ifdef NO_FASTPATH
370402
/* force a NULL return */
371403
retval = (Datum) 0;

0 commit comments

Comments
 (0)