Tom Lane wrote:
> I am still concerned about whether ExecFunctionReScan works correctly;
> if not, the problems would show up in join and subquery situations.
> I think the parser and planner stages are in pretty good shape now,
> though. (At least as far as the basic functionality goes. Having
> a smarter materialization policy will take work in the planner.)
I have been beating heavily on this function, but so far I can't find an
example which doesn't seem to work correctly. However, I also cannot
find an example which executes this part of the function:
. . .
/* * Here we have a choice whether to drop the tuplestore (and recompute * the function outputs) or just rescan it.
Thisshould depend on * whether the function expression contains parameters and/or is * marked volatile. FIXME soon.
*/
if (node->scan.plan.chgParam != NULL)
{tuplestore_end((Tuplestorestate *) scanstate->tuplestorestate);scanstate->tuplestorestate = NULL;
}
else
. . .
Here's at least part of what I've used to test:
CREATE TABLE foorescan (fooid int, foosubid int, fooname text, primary
key(fooid,foosubid));
-- use PHP to insert 100,000 records --
VACUUM ANALYZE;
CREATE FUNCTION foorescan(int,int) returns setof foorescan as 'SELECT *
FROM foorescan WHERE fooid >= $1 and fooid < $2 ;' LANGUAGE SQL;
select * from foorescan f, (select fooid, foosubid from
foorescan(5000,5010)) as s where f.fooid = s.fooid and f.foosubid =
s.foosubid;
CREATE VIEW vw_foorescan as select * from foorescan f, (select fooid,
foosubid from foorescan(5000,5010)) as s where f.fooid = s.fooid and
f.foosubid = s.foosubid;
--invokes ExecFunctionReScan
select * from foorescan f where f.fooid in (select fooid from
foorescan(5000,5001));
CREATE TABLE barrescan (fooid int primary key);
INSERT INTO barrescan values(5000);
INSERT INTO barrescan values(5001);
INSERT INTO barrescan values(5002);
INSERT INTO barrescan values(5003);
INSERT INTO barrescan values(5004);
INSERT INTO barrescan values(5005);
INSERT INTO barrescan values(5006);
INSERT INTO barrescan values(5007);
INSERT INTO barrescan values(5008);
INSERT INTO barrescan values(5009);
--invokes ExecFunctionReScan
select * from random(), foorescan(5000,5010) f JOIN barrescan b ON
b.fooid = f.fooid WHERE f.foosubid = 9;
select * from foorescan(5000,5000 + (random() * 10)::int) f JOIN
barrescan b ON b.fooid = f.fooid WHERE f.foosubid = 9;
Any ideas on getting (node->scan.plan.chgParam != NULL) to be true?
Joe