Hi,
This patch allows the PL/Python module to do (SRF) functions.
The patch was taken from the CVS version.
I have modified the plpython.c file and have added a test sql script for
testing the functionality. It was actually the script that was in the
8.0.3 version but have since been removed.
In order to signal the end of a set, the called python function must
simply return plpy.EndOfSet and the set would be returned.
Please feel free to email me if you experience any problems.
My next project I am working in is to get the PL/Python module to return
records (ie. structured data)
Regards
Gerrit van Dyk
AgileWorks (Pty) Ltd
diff -c -r -P orig/pgsql/src/pl/plpython/plpython.c
new/pgsql/src/pl/plpython/plpython.c
*** orig/pgsql/src/pl/plpython/plpython.c 2005-06-15 10:55:02.000000000
+0200
--- new/pgsql/src/pl/plpython/plpython.c 2005-06-14 14:12:01.000000000
+0200
***************
*** 286,291 ****
--- 286,294 ----
static PyObject *PLy_exc_fatal = NULL;
static PyObject *PLy_exc_spi_error = NULL;
+ /* End-of-set Indication */
+ static PyObject *PLy_endofset = NULL;
+
/* some globals for the python module
*/
static char PLy_plan_doc[] = {
***************
*** 770,775 ****
--- 773,788 ----
fcinfo->isnull = true;
rv = (Datum) NULL;
}
+ /* test for end-of-set condition */
+ else if (fcinfo->flinfo->fn_retset && plrv == PLy_endofset)
+ {
+ ReturnSetInfo *rsi;
+
+ fcinfo->isnull = true;
+ rv = (Datum)NULL;
+ rsi = (ReturnSetInfo *)fcinfo->resultinfo;
+ rsi->isDone = ExprEndResult;
+ }
else
{
fcinfo->isnull = false;
***************
*** 2317,2325 ****
--- 2330,2340 ----
PLy_exc_error = PyErr_NewException("plpy.Error", NULL, NULL);
PLy_exc_fatal = PyErr_NewException("plpy.Fatal", NULL, NULL);
PLy_exc_spi_error = PyErr_NewException("plpy.SPIError", NULL, NULL);
+ PLy_endofset = PyErr_NewException("plpy.EndOfSet",NULL,NULL);
PyDict_SetItemString(plpy_dict, "Error", PLy_exc_error);
PyDict_SetItemString(plpy_dict, "Fatal", PLy_exc_fatal);
PyDict_SetItemString(plpy_dict, "SPIError", PLy_exc_spi_error);
+ PyDict_SetItemString(plpy_dict, "EndOfSet", PLy_endofset);
/*
* initialize main module, and add plpy
diff -c -r -P orig/pgsql/src/pl/plpython/sql/plpython_setof.sql
new/pgsql/src/pl/plpython/sql/plpython_setof.sql
*** orig/pgsql/src/pl/plpython/sql/plpython_setof.sql 1970-01-01
02:00:00.000000000 +0200
--- new/pgsql/src/pl/plpython/sql/plpython_setof.sql 2005-06-14
14:12:01.000000000 +0200
***************
*** 0 ****
--- 1,12 ----
+
+ CREATE or replace FUNCTION test_setof() returns setof text
+ AS
+ 'if GD.has_key("calls"):
+ GD["calls"] = GD["calls"] + 1
+ if GD["calls"] > 2:
+ del GD["calls"]
+ return plpy.EndOfSet
+ else:
+ GD["calls"] = 1
+ return str(GD["calls"])'
+ LANGUAGE plpythonu;
---------------------------(end of broadcast)---------------------------
TIP 9: the planner will ignore your desire to choose an index scan if your
joining column's datatypes do not match