Re: cursors as table sources - Mailing list pgsql-general
From | Michael Fuhr |
---|---|
Subject | Re: cursors as table sources |
Date | |
Msg-id | 20060112171528.GA870@winnie.fuhr.org Whole thread Raw |
In response to | cursors as table sources ("Peter Filipov" <pfilipov@netissat.bg>) |
List | pgsql-general |
[Please copy the mailing list on replies. I'm forwarding your entire message to the list without comment so others can see it; I'll look at it when I get a chance.] On Thu, Jan 12, 2006 at 04:21:04PM +0200, Peter Filipov wrote: > It is the second case. > > I find cursors as good way to pass a result set from function to function. > Because a function should not be burdened with the knowledge how its caller > obtained the values that he is passing to her as arguments. Here is my > case: > > loop > > css:=ces + '1 second'::interval; > ces:=tperiod_end(cpp,css); > perform cursor_rewind(pp); > > select > css as > stime, > case > when allp.tpri>apr.tpri then > tperiod_condend((tperiod.*)::tperiod,css) > else ces -- handles last 2 'or's > end as > etime, > (tperiod.*)::tperiod as > newcp, > (allp.*)::tperiod_pentry as > aper > from > curs2set(pp,wd) as allp(id int, tpri int, tp int), > aperiod, > tperiod > where > > allp.tp=aperiod.id and > aperiod.id=tperiod.tid and > tperiod.id<>cpp.id and > ( > ( > allp.tpri>apr.tpri and > tperiod_condend((tperiod.*)::tperiod,css)<ces > > ) or > ( > allp.tpri<apr.tpri and > tperiod_stampin((tperiod.*)::tperiod,tperiod_tstampexplode(ces)) > ) or > ( > tperiod_condend((tperiod.*)::tperiod,css)=ces > ) > ) > order by > case > when allp.tpri>apr.tpri then > tperiod_condend((tperiod.*)::tperiod,css) > else ces -- handles last 2 'or's > end asc, > allp.tpri desc > limit 1 > into cmp; > > mp:=found; > if mp then > css:=cmp.stime; > ces:=cmp.etime; > apr:=cmp.aper; > r.st:=css; > r.et:=ces; > r.csid:=apr.id; > r.tpid:=cpp.id; > -- it is important here that we give the current > period, not the next !!! > cpp:=cmp.newcp; > else > r.st:=css; > r.et:=ces; > r.csid:=apr.id; > r.tpid:=cpp.id; > end if; > -- substract the total allowed length and handle current > period if necesarry > cl:=r.et-r.st+sl; > r.et:=r.st+least(cl,tl)-sl; > tl:=tl-least(cl,tl); > -- return the current row > return next r; > -- check wether no more total length exists or there are no > more periods > if not mp then exit; end if; > if tl<sl then exit; end if; > > end loop; > > Few notes. > 1. Cursor rewind is plpgsql and rewinds the cursor to the begining by: > execute 'move backward all from '||cursor_name(c); > I know it is bad idea but I commented few lines in 'spi.c' in order to > make that possible > 2. I think that: select * from table1,(fetch all from cursor1); is good > idea but it is not possible to use it in a function. > If I replace curs2set(pp) with (fetch all from pp) I get errors > 3. Of course 'pp' is function parameter > 4. I think there is at least one advantage in allowing cursors as table > sources: It gives you flexibility. It may bring performance > penalties but those won't be as big as the penalty I get in my > implementation here. It will still stay 'full scan' but will avoid copying > here and there result sets. > > > Regards, > Peter Filipov > > On Wed, 11 Jan 2006 11:24:30 -0700, Michael Fuhr <mike@fuhr.org> wrote: > > >On Wed, Jan 11, 2006 at 04:11:18PM +0200, Peter Filipov wrote: > >>Is the idea to use cursors as table sources good? > >>Do you plan to implement it in the future and if you plan will it be > >>soon? > > > >Do you mean the ability to use a cursor as one of the sources in > >the FROM clause? Something like the following non-working examples? > > > > DECLARE curs CURSOR FOR SELECT * FROM table1; > > SELECT * FROM table2, curs; > > > >or > > > > DECLARE curs CURSOR FOR SELECT * FROM table1; > > SELECT * FROM table2, (FETCH ALL FROM curs) AS s; > > > >As far as I know PostgreSQL doesn't allow anything like that; > >somebody please correct me if I'm mistaken. However, you could > >write a set-returning function that takes a refcursor argument and > >iterates through the cursor, returning each row, and use that > >function in the FROM clause. Whether that's a good idea or not is > >something I haven't given much thought to. Is there a reason you'd > >want to use a cursor instead of, say, a view? > > > >Are you just curious or is there a problem you're trying to solve? > >If I've misunderstood what you're asking then please elaborate. -- Michael Fuhr
pgsql-general by date: