Re: [BUGS] BUG #1723: array_cat() bug when passed empty array
On Mon, Jun 20, 2005 at 03:44:24PM -0400, Tom Lane wrote: I [Tom Lane] wrote: Actually, I would say the bug is exec_assign_value's. There is nothing at all wrong with a function returning one of its input values; for example the smaller/larger functions all do that. For that matter, you don't need a function at all: regression=# create or replace function copyit(text) returns text as $$ regression$# declare tmp text; regression$# begin regression$# tmp := $1; regression$# tmp := tmp; regression$# return tmp; regression$# end$$ language plpgsql stable; CREATE FUNCTION regression=# select copyit('foo'); ERROR: out of memory DETAIL: Failed on request of size 1065320319. CONTEXT: PL/pgSQL function copyit line 4 at assignment regression=# This makes it perfectly clear that the problem is that exec_assign_value must copy the given value before it frees the old, just in case they're the same. (Hmm, I wonder if we can shortcircuit the whole thing ...) Anyone working on fixing this? I'd have tried but I didn't want to dive into exec_assign_value() and exec_cast_value(). Given that this occurs for almost any assignment of the form x := any expression with x it's hard to avoid without rewritting a lot of basic assignments with tmp:=x; x:=foo(tmp) which is ugly. We can't use memory checking with this and even without memory checking I don't trust that memory isn't getting spamed in some situations. After all it's referencing free'd memory. -- Dave Chapeskie ---(end of broadcast)--- TIP 3: Have you checked our extensive FAQ? http://www.postgresql.org/docs/faq
Re: [BUGS] BUG #1723: array_cat() bug when passed empty array
Dave Chapeskie [EMAIL PROTECTED] writes: On Mon, Jun 20, 2005 at 03:44:24PM -0400, Tom Lane wrote: This makes it perfectly clear that the problem is that exec_assign_value must copy the given value before it frees the old, just in case they're the same. (Hmm, I wonder if we can shortcircuit the whole thing ...) Anyone working on fixing this? I'd have tried but I didn't want to dive into exec_assign_value() and exec_cast_value(). Done some time ago, I think [ digs in CVS log... ] yeah, here it is: 2005-06-20 16:44 tgl * src/pl/plpgsql/src/: pl_exec.c (REL7_3_STABLE), pl_exec.c (REL7_4_STABLE), pl_exec.c (REL7_2_STABLE), pl_exec.c (REL8_0_STABLE), pl_exec.c: plpgsql's exec_assign_value() freed the old value of a variable before copying/converting the new value, which meant that it failed badly on var := var if var is of pass-by-reference type. Fix this and a similar hazard in exec_move_row(); not sure that the latter can manifest before 8.0, but patch it all the way back anyway. Per report from Dave Chapeskie. You can get the patches from our CVS server. http://developer.postgresql.org/cvsweb.cgi/pgsql/src/pl/plpgsql/src/pl_exec.c regards, tom lane ---(end of broadcast)--- TIP 1: if posting/reading through Usenet, please send an appropriate subscribe-nomail command to [EMAIL PROTECTED] so that your message can get through to the mailing list cleanly
Re: [BUGS] BUG #1723: array_cat() bug when passed empty array
I wrote: Actually, I would say the bug is exec_assign_value's. There is nothing at all wrong with a function returning one of its input values; for example the smaller/larger functions all do that. For that matter, you don't need a function at all: regression=# create or replace function copyit(text) returns text as $$ regression$# declare tmp text; regression$# begin regression$# tmp := $1; regression$# tmp := tmp; regression$# return tmp; regression$# end$$ language plpgsql stable; CREATE FUNCTION regression=# select copyit('foo'); ERROR: out of memory DETAIL: Failed on request of size 1065320319. CONTEXT: PL/pgSQL function copyit line 4 at assignment regression=# This makes it perfectly clear that the problem is that exec_assign_value must copy the given value before it frees the old, just in case they're the same. (Hmm, I wonder if we can shortcircuit the whole thing ...) regards, tom lane ---(end of broadcast)--- TIP 9: the planner will ignore your desire to choose an index scan if your joining column's datatypes do not match
Re: [BUGS] BUG #1723: array_cat() bug when passed empty array
Dave Chapeskie [EMAIL PROTECTED] writes: array_cat() has a bug when passed an empty array. The code attempts to optimise/short-circuit this case and returns a pointer to the non-empty argument. This is bad/wrong. Especially when used in a construct like: foo := foo || some_array since after array_cat() returns exec_assign_value() will pfree() 'foo' and then attempt to assign the now invalid result that points to 'foo'. Actually, I would say the bug is exec_assign_value's. There is nothing at all wrong with a function returning one of its input values; for example the smaller/larger functions all do that. Let's see... regression=# create or replace function smal(text,text) returns text as $$ regression$# declare tmp text; regression$# begin regression$# tmp := $1; regression$# tmp := text_smaller(tmp, $2); regression$# return tmp; regression$# end$$ language plpgsql stable; CREATE FUNCTION regression=# select smal('abc', '123'); smal -- 123 (1 row) regression=# select smal('123', 'abc'); ERROR: out of memory DETAIL: Failed on request of size 1065320319. CONTEXT: PL/pgSQL function smal line 4 at assignment regression=# It's very surprising no one noticed this before. Thanks for the report! regards, tom lane ---(end of broadcast)--- TIP 5: Have you checked our extensive FAQ? http://www.postgresql.org/docs/faq