Re: crash in plancache with subtransactions
Tom Lane <tgl@sss.pgh.pa.us>
From: Tom Lane <tgl@sss.pgh.pa.us>
To: Heikki Linnakangas <heikki.linnakangas@enterprisedb.com>, Alvaro Herrera <alvherre@commandprompt.com>, pgsql-hackers <pgsql-hackers@postgresql.org>
Date: 2010-10-26T20:48:46Z
Lists: pgsql-hackers
Attachments
- simplify-simple-expressions.patch (text/x-patch) patch
I wrote: > Heikki Linnakangas <heikki.linnakangas@enterprisedb.com> writes: >> One simple idea is to keep a flag along with the executor state to >> indicate that the executor state is currently in use. Set it just before >> calling ExecEvalExpr, and reset afterwards. If the flag is already set >> in the beginning of exec_eval_simple_expr, we have recursed, and must >> create a new executor state. > Yeah, the same thought occurred to me in the shower this morning. > I'm concerned about possible memory leakage during repeated recursion, > but maybe that can be dealt with. I spent some time poking at this today, and developed the attached patch, which gets rid of all the weird assumptions associated with "simple expressions" in plpgsql, in favor of just doing another ExecInitExpr per expression in each call of the function. While this is a whole lot cleaner than what we have, I'm afraid that it's unacceptably slow. I'm seeing an overall slowdown of 2X to 3X on function execution with examples like: create or replace function speedtest10(x float8) returns float8 as $$ declare z float8 := x; begin z := z * 2 + 1; z := z * 2 + 1; z := z * 2 + 1; z := z * 2 + 1; z := z * 2 + 1; z := z * 2 + 1; z := z * 2 + 1; z := z * 2 + 1; z := z * 2 + 1; z := z * 2 + 1; return z; end $$ language plpgsql immutable; Now, this is about the worst case for the patch. This function's runtime depends almost entirely on the speed of simple expressions, and because there's no internal looping, we only get to use the result of each ExecInitExpr once per function call. So probably "typical" use cases wouldn't be quite so bad; but still it seems like we can't go this route. We need to be able to use the ExecInitExpr results across successive calls one way or another. I'll look into creating an in-use flag next. regards, tom lane