I wrote: > However, I also wondered how ExecuteCallStmt works at all for pass-by- > reference datatypes, since it immediately destroys the execution context > for each expression. And the answer is that it doesn't, as proven here:
On closer inspection, there are actually three sub-cases involved. It accidentally works for simple constant arguments, because the passed Datum will point at a Const node generated during transformExpr. And it works for fully run-time-evaluated arguments, because those end up in memory belonging to the standalone ExprContext(s), which ExecuteCallStmt never bothers to free at all. (Which is a bug in itself, although possibly one that wouldn't be exposed in practice given that we disallow SRFs here; I don't know if there are any other cases that would expect ExprContext cleanup hooks to get invoked.) Where it doesn't work is for expressions that are const-folded during ExecPrepareExpr, because then the values are in Const nodes that live in the EState's per-query context, and the code is throwing that away too soon. I pushed a fix for all that. The failure in pg_get_functiondef() is still there. While the immediate answer probably is to teach that function to emit correct CREATE PROCEDURE syntax, I continue to think that it's a bad idea to be putting zeroes into pg_proc.prorettype. regards, tom lane