Re: [HACKERS] PL/Python: Add cursor and execute methods to plan object
On 3/22/17 11:46, Andrew Dunstan wrote: > This is a very simple patch that does what it advertises. It applies > cleanly and provides tests for both the new methods (plan.cursor and > plan.execute). > > Marking Ready For Committer. committed -- Peter Eisentraut http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] PL/Python: Add cursor and execute methods to plan object
Jim Nasby writes: > On 2/25/17 10:27 AM, Peter Eisentraut wrote: >> So I'm also wondering here which style people prefer so >> I can implement it there. > > I think the more OO style is definitely better. I expect it would > simplify the code as well. I'm not a Python person, but I'd argue that the "more OO" style should be the primary style documented, and the old style should just be mentioned for reference. - ilmari -- - Twitter seems more influential [than blogs] in the 'gets reported in the mainstream press' sense at least. - Matt McLeod - That'd be because the content of a tweet is easier to condense down to a mainstream media article. - Calle Dybedahl -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] PL/Python: Add cursor and execute methods to plan object
On 2/25/17 10:27 AM, Peter Eisentraut wrote: So I'm also wondering here which style people prefer so I can implement it there. I think the more OO style is definitely better. I expect it would simplify the code as well. -- Jim C. Nasby, Data Architect j...@nasby.net 512.569.9461 (cell) http://jim.nasby.net -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] PL/Python: Add cursor and execute methods to plan object
On 03/21/2017 06:27 PM, Andrew Dunstan wrote: > On 03/16/2017 05:32 PM, David Steele wrote: >> On 2/25/17 1:27 PM, Peter Eisentraut wrote: >>> Something that has been bothering me in PL/Python for a long time is the >>> non-object-oriented way in which plans are prepared and executed: >>> >>> plan = plpy.prepare(...) >>> res = plpy.execute(plan, ...) >>> >>> where plpy.execute() takes either a plan or a query string. >>> >>> I think a better style would be >>> >>> plan = plpy.prepare(...) >>> res = plan.execute(...) >>> >>> so that the "plan" is more like a statement handle that one finds in >>> other APIs. >>> >>> This ended up being very easy to implement, so I'm proposing to allow >>> this new syntax as an alternative. >>> >>> I came across this again as I was developing the background sessions API >>> for PL/Python. So I'm also wondering here which style people prefer so >>> I can implement it there. >> This patch applies cleanly at cccbdde. >> >> Any Python folks out there who would like to take a crack at reviewing this? >> >> > I'm not particularly a Python folk, but I've done enough over the years > with PLs, including PLPython, that I think I can review this :-) > This is a very simple patch that does what it advertises. It applies cleanly and provides tests for both the new methods (plan.cursor and plan.execute). Marking Ready For Committer. cheers andrew -- Andrew Dunstanhttps://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] PL/Python: Add cursor and execute methods to plan object
On 03/16/2017 05:32 PM, David Steele wrote: > On 2/25/17 1:27 PM, Peter Eisentraut wrote: >> Something that has been bothering me in PL/Python for a long time is the >> non-object-oriented way in which plans are prepared and executed: >> >> plan = plpy.prepare(...) >> res = plpy.execute(plan, ...) >> >> where plpy.execute() takes either a plan or a query string. >> >> I think a better style would be >> >> plan = plpy.prepare(...) >> res = plan.execute(...) >> >> so that the "plan" is more like a statement handle that one finds in >> other APIs. >> >> This ended up being very easy to implement, so I'm proposing to allow >> this new syntax as an alternative. >> >> I came across this again as I was developing the background sessions API >> for PL/Python. So I'm also wondering here which style people prefer so >> I can implement it there. > This patch applies cleanly at cccbdde. > > Any Python folks out there who would like to take a crack at reviewing this? > > I'm not particularly a Python folk, but I've done enough over the years with PLs, including PLPython, that I think I can review this :-) cheers andrew -- Andrew Dunstanhttps://www.2ndQuadrant.com PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
Re: [HACKERS] PL/Python: Add cursor and execute methods to plan object
On 2/25/17 1:27 PM, Peter Eisentraut wrote: > Something that has been bothering me in PL/Python for a long time is the > non-object-oriented way in which plans are prepared and executed: > > plan = plpy.prepare(...) > res = plpy.execute(plan, ...) > > where plpy.execute() takes either a plan or a query string. > > I think a better style would be > > plan = plpy.prepare(...) > res = plan.execute(...) > > so that the "plan" is more like a statement handle that one finds in > other APIs. > > This ended up being very easy to implement, so I'm proposing to allow > this new syntax as an alternative. > > I came across this again as I was developing the background sessions API > for PL/Python. So I'm also wondering here which style people prefer so > I can implement it there. This patch applies cleanly at cccbdde. Any Python folks out there who would like to take a crack at reviewing this? -- -David da...@pgmasters.net -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers
[HACKERS] PL/Python: Add cursor and execute methods to plan object
Something that has been bothering me in PL/Python for a long time is the non-object-oriented way in which plans are prepared and executed: plan = plpy.prepare(...) res = plpy.execute(plan, ...) where plpy.execute() takes either a plan or a query string. I think a better style would be plan = plpy.prepare(...) res = plan.execute(...) so that the "plan" is more like a statement handle that one finds in other APIs. This ended up being very easy to implement, so I'm proposing to allow this new syntax as an alternative. I came across this again as I was developing the background sessions API for PL/Python. So I'm also wondering here which style people prefer so I can implement it there. -- Peter Eisentraut http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services From 9dccf70110d9d5818318c651c2662f2b8f86b2bc Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Sat, 25 Feb 2017 08:42:25 -0500 Subject: [PATCH] PL/Python: Add cursor and execute methods to plan object Instead of plan = plpy.prepare(...) res = plpy.execute(plan, ...) you can now write plan = plpy.prepare(...) res = plan.execute(...) or even res = plpy.prepare(...).execute(...) and similarly for the cursor() method. This is more in object oriented style, and makes the hybrid nature of the existing execute() function less confusing. --- doc/src/sgml/plpython.sgml| 14 -- src/pl/plpython/expected/plpython_spi.out | 19 --- src/pl/plpython/plpy_cursorobject.c | 3 +-- src/pl/plpython/plpy_cursorobject.h | 1 + src/pl/plpython/plpy_planobject.c | 31 +++ src/pl/plpython/plpy_spi.c| 3 +-- src/pl/plpython/plpy_spi.h| 1 + src/pl/plpython/sql/plpython_spi.sql | 18 -- 8 files changed, 79 insertions(+), 11 deletions(-) diff --git a/doc/src/sgml/plpython.sgml b/doc/src/sgml/plpython.sgml index 46397781be..6888ce1ae3 100644 --- a/doc/src/sgml/plpython.sgml +++ b/doc/src/sgml/plpython.sgml @@ -1048,6 +1048,14 @@ Database Access Functions + Alternatively, you can call the execute method on + the plan object: + +rv = plan.execute(["name"], 5) + + + + Query parameters and result row fields are converted between PostgreSQL and Python data types as described in . @@ -1082,7 +1090,9 @@ Database Access Functions as plpy.execute (except for the row limit) and returns a cursor object, which allows you to process large result sets in smaller chunks. As with plpy.execute, either a query string - or a plan object along with a list of arguments can be used. + or a plan object along with a list of arguments can be used, or + the cursor function can be called as a method of + the plan object. @@ -1126,7 +1136,7 @@ Database Access Functions CREATE FUNCTION count_odd_prepared() RETURNS integer AS $$ odd = 0 plan = plpy.prepare("select num from largetable where num % $1 <> 0", ["integer"]) -rows = list(plpy.cursor(plan, [2])) +rows = list(plpy.cursor(plan, [2])) # or: = list(plan.cursor([2])) return len(rows) $$ LANGUAGE plpythonu; diff --git a/src/pl/plpython/expected/plpython_spi.out b/src/pl/plpython/expected/plpython_spi.out index 0d78ca1de4..e54dca9e2e 100644 --- a/src/pl/plpython/expected/plpython_spi.out +++ b/src/pl/plpython/expected/plpython_spi.out @@ -31,6 +31,19 @@ except Exception, ex: return None ' LANGUAGE plpythonu; +CREATE FUNCTION spi_prepared_plan_test_two(a text) RETURNS text + AS +'if "myplan" not in SD: + q = "SELECT count(*) FROM users WHERE lname = $1" + SD["myplan"] = plpy.prepare(q, [ "text" ]) +try: + rv = SD["myplan"].execute([a]) + return "there are " + str(rv[0]["count"]) + " " + str(a) + "s" +except Exception, ex: + plpy.error(str(ex)) +return None +' + LANGUAGE plpythonu; CREATE FUNCTION spi_prepared_plan_test_nested(a text) RETURNS text AS 'if "myplan" not in SD: @@ -80,8 +93,8 @@ select spi_prepared_plan_test_one('doe'); there are 3 does (1 row) -select spi_prepared_plan_test_one('smith'); - spi_prepared_plan_test_one +select spi_prepared_plan_test_two('smith'); + spi_prepared_plan_test_two there are 1 smiths (1 row) @@ -372,7 +385,7 @@ plan = plpy.prepare( ["text"]) for row in plpy.cursor(plan, ["w"]): yield row['fname'] -for row in plpy.cursor(plan, ["j"]): +for row in plan.cursor(["j"]): yield row['fname'] $$ LANGUAGE plpythonu; CREATE FUNCTION cursor_plan_wrong_args() RETURNS SETOF text AS $$ diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index 7bb8992148..18e689f141 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -25,7 +25,6 @@ static PyObject *PLy_cursor_query(const char *query); -static PyObject *PLy_cursor_