Обсуждение: More long-string woes

Поиск
Список
Период
Сортировка

More long-string woes

От
Joseph Barillari
Дата:
My apologies in advance if this is redundant -- I've managed to get
the backend to cough up an error message which may provide some clue
as to why some of the other errors happened:


cal=> drop function foo();
ERROR:  pg_func_ownercheck: function 'foo()' does not exist
cal=> \i tf3
CREATE
cal=> select foo();
NOTICE:  [bnlah bnlah <repeats for ~1024 chars, snipped>foo
-----  1
(1 row)

cal=> \i tf3
CREATE
cal=> select foo();
NOTICE:  [bnlah bnlah <repeats for ~1024 chars, snipped>
NOTICE:  Error occurred while executing PL/pgSQL function foo
NOTICE:  while casting return value to functions return type
ERROR:  AllocSetFree: cannot find block containing chunk 0x8247780
cal=>

Pl/pgsql hackers -- does this indicate some problems with my
installation? I recompiled using gcc3, and the errors persist. Here's
the function I used to produce them:


CREATE OR REPLACE FUNCTION foo()   RETURNS INTEGER   AS '
DECLAREquerystr TEXT;

BEGIN

querystr := ''bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah
bnlahbnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah
bnlahbnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah
bnlahbnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah
bnlahbnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah
bnlahbnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah
bnlahbnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah
bnlahbnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah
bnlahbnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah
bnlahbnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah
bnlahbnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah
bnlahbnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah bnlah
'';

raise notice ''[%]'', querystr;

return 1;
end;
'
language 'plpgsql';

Re: More long-string woes

От
Tom Lane
Дата:
Joseph Barillari <jbarilla@princeton.edu> writes:
> [ problems with long literals in plpgsql ]

I'm amazed no one has noticed this before.  plpgsql_dstring_append
is broken: it assumes it never needs to more than double the size
of the string.

Too tired to commit a fix tonight, but that's where the problem
lies...
        regards, tom lane


Re: More long-string woes

От
Tom Lane
Дата:
Tom Lane <tgl@sss.pgh.pa.us> writes:
> Joseph Barillari <jbarilla@princeton.edu> writes:
>> [ problems with long literals in plpgsql ]

> I'm amazed no one has noticed this before.  plpgsql_dstring_append
> is broken: it assumes it never needs to more than double the size
> of the string.

I've applied the attached patch to current CVS and the 7.2 branch
(it also works against 7.1 sources).  Seems to fix the cases you report.
        regards, tom lane

*** src/pl/plpgsql/src/pl_funcs.c.orig    Thu Nov 15 18:31:09 2001
--- src/pl/plpgsql/src/pl_funcs.c    Sun May  5 13:38:26 2002
***************
*** 64,69 ****
--- 64,70 ---- {     ds->value = palloc(ds->alloc = 512);     ds->used = 0;
+     ds->value[0] = '\0'; }  
***************
*** 86,95 **** plpgsql_dstring_append(PLpgSQL_dstring * ds, char *str) {     int            len = strlen(str); 
!     if (ds->used + len + 1 > ds->alloc)     {
!         ds->alloc *= 2;         ds->value = repalloc(ds->value, ds->alloc);     } 
--- 87,100 ---- plpgsql_dstring_append(PLpgSQL_dstring * ds, char *str) {     int            len = strlen(str);
+     int            needed = ds->used + len + 1; 
!     if (needed > ds->alloc)     {
!         /* might have to double more than once, if len is large */
!         do {
!             ds->alloc *= 2;
!         } while (needed > ds->alloc);         ds->value = repalloc(ds->value, ds->alloc);     }