Thread: context in plpgsql functions
I've been using PostgreSQL 7.3.2. What, if any, way is there to share a context (global rowtype variable) between plpgsql functions ? Can row types be passed as parameters ? (I seem to have had trouble doing that) e.g. A transaction that looks like: BEGIN; select FindContext(5432); select SomeRandomFunction('111'); COMMIT; The functions would look somthing like: CREATE or replace FUNCTION FindContext(int4) RETURNS int4 AS ' DECLARE w_key alias for $1; w_context context%ROWTYPE; BEGIN SELECT INTO w_context * FROM contecxt WHERE key = w_key; -- I want to access w_context in a different method RETURN 1; END; ' LANGUAGE 'plpgsql'; CREATE or replace FUNCTION SomeRandomFunction(int4) RETURNS int4 AS ' DECLARE w_stuff alias for $1; w_context context%ROWTYPE; -- ?????????????? BEGIN update sometable set key = w_context.key where yadda = w_stuff; RETURN 1; END; ' LANGUAGE 'plpgsql';
On Friday 16 May 2003 20:46, Gianni Mariani wrote: > I've been using PostgreSQL 7.3.2. > > What, if any, way is there to share a context (global rowtype variable) > between plpgsql functions ? If you mean something like Oracle's PL/SQL packages, which can contain package global variables, then unfortunately not. Ian Barwick barwick@gmx.net
--- Ian Barwick <barwick@gmx.net> wrote: > On Friday 16 May 2003 20:46, Gianni Mariani wrote: > > I've been using PostgreSQL 7.3.2. > > > > What, if any, way is there to share a context > (global rowtype variable) > > between plpgsql functions ? > > If you mean something like Oracle's PL/SQL packages, > which can > contain package global variables, then unfortunately > not. I believe the usual workaround is to insert the values in a table which has been created for that purpose. __________________________________ Do you Yahoo!? The New Yahoo! Search - Faster. Easier. Bingo. http://search.yahoo.com
You can do this with plpython. There is a brief write up about it at http://www.varlena.com/GeneralBits/23.html There is one trick to it :-) --elein On Friday 16 May 2003 11:46, Gianni Mariani wrote: > I've been using PostgreSQL 7.3.2. > > What, if any, way is there to share a context (global rowtype variable) > between plpgsql functions ? > > Can row types be passed as parameters ? (I seem to have had trouble > doing that) > > e.g. > > A transaction that looks like: > > BEGIN; > select FindContext(5432); > select SomeRandomFunction('111'); > COMMIT; > > > The functions would look somthing like: > > CREATE or replace FUNCTION FindContext(int4) RETURNS int4 AS > ' > DECLARE > w_key alias for $1; > w_context context%ROWTYPE; > BEGIN > > SELECT INTO w_context * FROM contecxt WHERE key = w_key; > > -- I want to access w_context in a different method > > RETURN 1; > > END; > ' > LANGUAGE 'plpgsql'; > > > CREATE or replace FUNCTION SomeRandomFunction(int4) RETURNS int4 AS > ' > DECLARE > w_stuff alias for $1; > w_context context%ROWTYPE; -- ?????????????? > BEGIN > > update sometable set key = w_context.key where yadda = w_stuff; > > RETURN 1; > > END; > ' > LANGUAGE 'plpgsql'; > > > > > ---------------------------(end of broadcast)--------------------------- > TIP 2: you can get off all lists at once with the unregister command > (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) > > -- ============================================================= elein@varlena.com Database Consulting www.varlena.com PostgreSQL General Bits http:/www.varlena.com/GeneralBits/ "Left foot, right foot, left foot, breathe. Right foot, left foot, right foot, breathe." --Father Tom
Jeff Eckermann wrote: >--- Ian Barwick <barwick@gmx.net> wrote: > > >>On Friday 16 May 2003 20:46, Gianni Mariani wrote: >> >> >>>I've been using PostgreSQL 7.3.2. >>> >>>What, if any, way is there to share a context >>> >>> >>(global rowtype variable) >> >> >>>between plpgsql functions ? >>> >>> >>If you mean something like Oracle's PL/SQL packages, >>which can >>contain package global variables, then unfortunately >>not. >> >> > >I believe the usual workaround is to insert the values >in a table which has been created for that purpose. > > Yes - I was thinking of that - I was also thinking you could use a cursor to do the job of pointing to the record in the table you care about. However, when I try to do a MOVE cursor inside a plpgsql function i get : EXECUTE ''MOVE BACKWARD 1 IN "ContextCursor"'' psql:kkk4:145: ERROR: unexpected error -5 in EXECUTE of query 'MOVE BACKWARD 1 IN "ContextCursor"' or a PERFORM MOVE BACKWARD 1 IN "ContextCursor"; psql:kkk4:145: ERROR: parser: parse error at or near "BACKWARD" at character 14 or MOVE BACKWARD 1 IN "ContextCursor"; psql:kkk4:145: ERROR: SPI_prepare() failed on "MOVE BACKWARD 1 IN "ContextCursor"" .... yet that same statement works fine elsewhere ... Ideas on how to move a cursor inside a plpgsql function ? TIA
Gianni Mariani wrote: > Jeff Eckermann wrote: > >> --- Ian Barwick <barwick@gmx.net> wrote: >> >> >>> On Friday 16 May 2003 20:46, Gianni Mariani wrote: >>> >>> >>>> I've been using PostgreSQL 7.3.2. >>>> >>>> What, if any, way is there to share a context >>>> >>> >>> (global rowtype variable) >>> >>> >>>> between plpgsql functions ? >>>> >>> >>> If you mean something like Oracle's PL/SQL packages, >>> which can >>> contain package global variables, then unfortunately >>> not. >>> >> >> >> I believe the usual workaround is to insert the values >> in a table which has been created for that purpose. >> >> > Yes - I was thinking of that - I was also thinking you could use a > cursor to do the job of pointing to the record in the table you care > about. > > However, when I try to do a MOVE cursor inside a plpgsql function i get : > > EXECUTE ''MOVE BACKWARD 1 IN "ContextCursor"'' > > psql:kkk4:145: ERROR: unexpected error -5 in EXECUTE of query > 'MOVE BACKWARD 1 IN "ContextCursor"' > > or a > PERFORM MOVE BACKWARD 1 IN "ContextCursor"; > > psql:kkk4:145: ERROR: parser: parse error at or near "BACKWARD" at > character 14 > > or > > MOVE BACKWARD 1 IN "ContextCursor"; > > psql:kkk4:145: ERROR: SPI_prepare() failed on "MOVE BACKWARD 1 IN > "ContextCursor"" > > > .... yet that same statement works fine elsewhere ... > > Ideas on how to move a cursor inside a plpgsql function ? OK - this one works. CREATE FUNCTION MoveBack() RETURNS unknown AS ' MOVE BACKWARD 1 FROM "ContextCursor"; select ''A''; ' LANGUAGE SQL; ... then in the plpgsql function do this: PERFORM MoveBack(); It seems like there is a few issues with cursors and plpgsql functions. Does anyone want some test cases ? So it seems like it is possible to create a somewhat simple context handler using cursors. It's also good that with cursors by default there is a scope by default in a transaction (the 7.4 doc seems to suggest that you can declare cursors that live beyond a transaction). Having said all that, it would be good if you could define a "class" of plpgsql functions that could share contextual information implicitly.
You can do this in a C function or a plpython function by saving out the information into context in C or into the SD[] dictionary in plpython. This is the subject of my talk at OSCON :-) elein On Saturday 17 May 2003 08:50, Gianni Mariani wrote: > Gianni Mariani wrote: > > > Jeff Eckermann wrote: > > > >> --- Ian Barwick <barwick@gmx.net> wrote: > >> > >> > >>> On Friday 16 May 2003 20:46, Gianni Mariani wrote: > >>> > >>> > >>>> I've been using PostgreSQL 7.3.2. > >>>> > >>>> What, if any, way is there to share a context > >>>> > >>> > >>> (global rowtype variable) > >>> > >>> > >>>> between plpgsql functions ? > >>>> > >>> > >>> If you mean something like Oracle's PL/SQL packages, > >>> which can > >>> contain package global variables, then unfortunately > >>> not. > >>> > >> > >> > >> I believe the usual workaround is to insert the values > >> in a table which has been created for that purpose. > >> > >> > > Yes - I was thinking of that - I was also thinking you could use a > > cursor to do the job of pointing to the record in the table you care > > about. > > > > However, when I try to do a MOVE cursor inside a plpgsql function i get : > > > > EXECUTE ''MOVE BACKWARD 1 IN "ContextCursor"'' > > > > psql:kkk4:145: ERROR: unexpected error -5 in EXECUTE of query > > 'MOVE BACKWARD 1 IN "ContextCursor"' > > > > or a > > PERFORM MOVE BACKWARD 1 IN "ContextCursor"; > > > > psql:kkk4:145: ERROR: parser: parse error at or near "BACKWARD" at > > character 14 > > > > or > > > > MOVE BACKWARD 1 IN "ContextCursor"; > > > > psql:kkk4:145: ERROR: SPI_prepare() failed on "MOVE BACKWARD 1 IN > > "ContextCursor"" > > > > > > .... yet that same statement works fine elsewhere ... > > > > Ideas on how to move a cursor inside a plpgsql function ? > > OK - this one works. > > CREATE FUNCTION MoveBack() RETURNS unknown AS ' > MOVE BACKWARD 1 FROM "ContextCursor"; > select ''A''; > ' LANGUAGE SQL; > > ... then in the plpgsql function do this: > > PERFORM MoveBack(); > > It seems like there is a few issues with cursors and plpgsql functions. > Does anyone want some test cases ? > > So it seems like it is possible to create a somewhat simple context > handler using cursors. It's also good that with cursors by default > there is a scope by default in a transaction (the 7.4 doc seems to > suggest that you can declare cursors that live beyond a transaction). > > Having said all that, it would be good if you could define a "class" of > plpgsql functions that could share contextual information implicitly. > > > > > > > ---------------------------(end of broadcast)--------------------------- > TIP 5: Have you checked our extensive FAQ? > > http://www.postgresql.org/docs/faqs/FAQ.html > > -- ============================================================= elein@varlena.com Database Consulting www.varlena.com PostgreSQL General Bits http:/www.varlena.com/GeneralBits/ "Free your mind the rest will follow" -- en vogue