Re: [GENERAL] Many Pl/PgSQL parameters -> AllocSetAlloc(128)?

From: Joe Conway <mail(at)joeconway(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: reuven(at)lerner(dot)co(dot)il, "Patches (PostgreSQL)" <pgsql-patches(at)postgresql(dot)org>
Subject: Re: [GENERAL] Many Pl/PgSQL parameters -> AllocSetAlloc(128)?
Date: 2003-06-24 23:22:31
Message-ID: 3EF8DD37.5000806@joeconway.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general pgsql-hackers pgsql-patches

(moving to patches)

Tom Lane wrote:
> Joe Conway <mail(at)joeconway(dot)com> writes:
>>Actually, adding a "pfree(oneres);" to the end of that for loop plugs
>>the memory leak and allows me to see the error message:
>
> On second look, you can't pfree oneres at the bottom of
> gen_cross_product() because it's part of the returned data structure
> --- note the assignment
> *iter++ = oneres;

Yup, I see that now ;-)

> I think the bug here is that gen_cross_product should be ignoring
> argument positions that have nsupers == 0; those should always be
> assigned the same type as the input, since the regular type resolution
> algorithm is responsible for dealing with 'em.
>
> It might work to get rid of the "wild card" case (line 1115), which'd
> reduce the number of outputs to product(nsupers+1). I doubt we really
> want any wild cards in there anymore.
>

The above didn't work, but if I understand correctly what that function
is intended to do, it seemed very broken. Basically this code:

nanswers = 1;
for (i = 0; i < nargs; i++)
{
nanswers *= (arginh[i].nsupers + 2);
cur[i] = 0;
}

for 24 arguments means 2^24 answers, even when there are no superclasses.

In that case (no arguments with superclasses), we ought to get:

nanswers = 1
iter should be sized at 1(all arginh[i].self)
+ 1(all wildcard)
+ 1 (null terminator)

The attached patch fixes this issue, but I'm still not entirely sure I
understand what the function was supposed to be doing, so please check
over my logic. Here's how I tested (after `make installcheck`)

CREATE OR REPLACE FUNCTION inhtest (d, integer, stud_emp, integer)
returns text as 'select ''OK''::text' language 'sql';
CREATE OR REPLACE FUNCTION get_d() returns d as 'select * from d limit
1' language 'sql';
CREATE OR REPLACE FUNCTION get_stud_emp() returns stud_emp as 'select *
from stud_emp limit 1' language 'sql';
select inhtest(get_d(), 'a'::text, get_stud_emp(), 1);

During testing, I had an elog(NOTICE,...) in there, and got the
following (reformatted) results:

arg num = 3 2 1 0
iter[j]
NOTICE: j = 0 23 1764386 25 1881220
NOTICE: j = 1 23 1764391 25 1881220
NOTICE: j = 2 23 1764381 25 1881220
NOTICE: j = 3 23 1764386 25 1881225
NOTICE: j = 4 23 1764391 25 1881225
NOTICE: j = 5 23 1764381 25 1881225
NOTICE: j = 6 23 1764386 25 1881215
NOTICE: j = 7 23 1764391 25 1881215
NOTICE: j = 8 23 1764381 25 1881215

Seems correct to me.

Passes all regression tests.

Joe

Attachment Content-Type Size
parse_func_fix.patch text/plain 2.3 KB

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Dennis Gearon 2003-06-25 00:34:38 Re: server layout
Previous Message Bruce Momjian 2003-06-24 23:20:24 Re: Thousands of semops for every i/o

Browse pgsql-hackers by date

  From Date Subject
Next Message The Hermit Hacker 2003-06-25 00:24:43 Re: Two weeks to feature freeze
Previous Message Guillaume LELARGE 2003-06-24 22:40:28 Re: capturing and storing query statement with rules

Browse pgsql-patches by date

  From Date Subject
Next Message Bruce Momjian 2003-06-24 23:25:54 Re: Nested transactions: deferred triggers
Previous Message Bruce Momjian 2003-06-24 23:20:24 Re: Thousands of semops for every i/o