From dfdae5d63cd0c7eb75fb419c61a5fd62c7e4b326 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Fri, 17 Dec 2004 02:14:48 +0000
Subject: [PATCH] Hook up the plpython result-object nrows and status methods
 correctly. Adjust documentation to match current reality.

---
 doc/src/sgml/plpython.sgml | 55 ++++++++++++++++----------------------
 src/pl/plpython/plpython.c | 30 +++++----------------
 2 files changed, 29 insertions(+), 56 deletions(-)

diff --git a/doc/src/sgml/plpython.sgml b/doc/src/sgml/plpython.sgml
index 6655219d3e6..a3d64bd353e 100644
--- a/doc/src/sgml/plpython.sgml
+++ b/doc/src/sgml/plpython.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/plpython.sgml,v 1.24 2004/09/13 20:05:18 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/plpython.sgml,v 1.25 2004/12/17 02:14:44 tgl Exp $ -->
 
 <chapter id="plpython">
  <title>PL/Python - Python Procedural Language</title>
@@ -46,7 +46,8 @@
   <title>PL/Python Functions</title>
 
   <para>
-   The Python code you write gets transformed into a Python function.  E.g.,
+   The Python code you write gets transformed into a Python function.
+   For example,
 <programlisting>
 CREATE FUNCTION myfunc(text) RETURNS text
     AS 'return args[0]'
@@ -60,13 +61,14 @@ def __plpython_procedure_myfunc_23456():
         return args[0]
 </programlisting>
 
-   assuming that 23456 is the OID of the function.
+   assuming that 23456 is the OID assigned to the function by
+   <productname>PostgreSQL</productname>.
   </para>
 
   <para>
    If you do not provide a return value, Python returns the default
-   <symbol>None</symbol>. The language module translates Python's
-   <symbol>None</symbol> into the SQL null
+   <symbol>None</symbol>. <application>PL/Python</application> translates
+   Python's <symbol>None</symbol> into the SQL null
    value.<indexterm><primary>null value</><secondary
    sortas="PL/Python">in PL/Python</></indexterm>
   </para>
@@ -108,7 +110,7 @@ def __plpython_procedure_myfunc_23456():
   </indexterm>
 
   <para>
-   When a function is used in a trigger, the dictionary
+   When a function is used as a trigger, the dictionary
    <literal>TD</literal> contains trigger-related values.  The trigger
    rows are in <literal>TD["new"]</> and/or <literal>TD["old"]</>
    depending on the trigger event.  <literal>TD["event"]</> contains
@@ -120,9 +122,9 @@ def __plpython_procedure_myfunc_23456():
    <literal>STATEMENT</>, and <literal>UNKNOWN</>.
    <literal>TD["name"]</> contains the trigger name, and
    <literal>TD["relid"]</> contains the OID of the table on
-   which the trigger occurred.  If the trigger was called with
-   arguments they are available in <literal>TD["args"][0]</> to
-   <literal>TD["args"][(n-1)]</>.
+   which the trigger occurred.  If the <command>CREATE TRIGGER</> command
+   included arguments, they are available in <literal>TD["args"][0]</> to
+   <literal>TD["args"][(<replaceable>n</>-1)]</>.
   </para>
 
   <para>
@@ -143,23 +145,23 @@ def __plpython_procedure_myfunc_23456():
    this module are available to you in the Python code as
    <literal>plpy.<replaceable>foo</replaceable></literal>.  At present
    <literal>plpy</literal> implements the functions
-   <literal>plpy.debug("msg")</literal>,
-   <literal>plpy.log("msg")</literal>,
-   <literal>plpy.info("msg")</literal>,
-   <literal>plpy.notice("msg")</literal>,
-   <literal>plpy.warning("msg")</literal>,
-   <literal>plpy.error("msg")</literal>, and
-   <literal>plpy.fatal("msg")</literal>.  They are mostly equivalent
-   to calling <literal>elog(<replaceable>LEVEL</>, "msg")</literal>
+   <literal>plpy.debug(<replaceable>msg</>)</literal>,
+   <literal>plpy.log(<replaceable>msg</>)</literal>,
+   <literal>plpy.info(<replaceable>msg</>)</literal>,
+   <literal>plpy.notice(<replaceable>msg</>)</literal>,
+   <literal>plpy.warning(<replaceable>msg</>)</literal>,
+   <literal>plpy.error(<replaceable>msg</>)</literal>, and
+   <literal>plpy.fatal(<replaceable>msg</>)</literal>.
+   These are mostly equivalent to calling
+   <literal>elog(<replaceable>level</>, <replaceable>msg</>)</literal>
    from C code.<indexterm><primary>elog</><secondary>in
    PL/Python</></indexterm>  <function>plpy.error</function> and
    <function>plpy.fatal</function> actually raise a Python exception
    which, if uncaught, causes the PL/Python module to call
    <literal>elog(ERROR, msg)</literal> when the function handler
-   returns from the Python interpreter.  Long-jumping out of the
-   Python interpreter is probably not good.  <literal>raise
-   plpy.ERROR("msg")</literal> and <literal>raise
-   plpy.FATAL("msg")</literal> are equivalent to calling
+   returns from the Python interpreter.  <literal>raise
+   plpy.ERROR(<replaceable>msg</>)</literal> and <literal>raise
+   plpy.FATAL(<replaceable>msg</>)</literal> are equivalent to calling
    <function>plpy.error</function> and
    <function>plpy.fatal</function>, respectively.
   </para>
@@ -210,17 +212,6 @@ rv = plpy.execute(plan, [ "name" ], 5)
    The third argument is the limit and is optional.
   </para>
 
-  <para>
-   In the current version, any database error encountered while
-   running a <application>PL/Python</application> function will result
-   in the immediate termination of that function by the server; it is
-   not possible to trap error conditions using Python <literal>try
-   ... catch</literal> constructs.  For example, a syntax error in an
-   SQL statement passed to the <literal>plpy.execute</literal> call
-   will terminate the function.  This behavior may be changed in a
-   future release.
-  </para>
-
   <para>
    When you prepare a plan using the PL/Python module it is
    automatically saved.  Read the SPI documentation (<xref
diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c
index 5826ad48c62..5f5b36b0a50 100644
--- a/src/pl/plpython/plpython.c
+++ b/src/pl/plpython/plpython.c
@@ -29,7 +29,7 @@
  * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  *
  * IDENTIFICATION
- *	$PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.57 2004/09/19 23:38:21 tgl Exp $
+ *	$PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.58 2004/12/17 02:14:48 tgl Exp $
  *
  *********************************************************************
  */
@@ -1531,13 +1531,8 @@ static PyObject *PLy_plan_status(PyObject *, PyObject *);
 static PyObject *PLy_result_new(void);
 static void PLy_result_dealloc(PyObject *);
 static PyObject *PLy_result_getattr(PyObject *, char *);
-
-#ifdef NOT_USED
-/* Appear to be unused */
-static PyObject *PLy_result_fetch(PyObject *, PyObject *);
 static PyObject *PLy_result_nrows(PyObject *, PyObject *);
 static PyObject *PLy_result_status(PyObject *, PyObject *);
-#endif
 static int	PLy_result_length(PyObject *);
 static PyObject *PLy_result_item(PyObject *, int);
 static PyObject *PLy_result_slice(PyObject *, int, int);
@@ -1582,7 +1577,7 @@ static PyTypeObject PLy_PlanType = {
 };
 
 static PyMethodDef PLy_plan_methods[] = {
-	{"status", (PyCFunction) PLy_plan_status, METH_VARARGS, NULL},
+	{"status", PLy_plan_status, METH_VARARGS, NULL},
 	{NULL, NULL, 0, NULL}
 };
 
@@ -1626,15 +1621,11 @@ static PyTypeObject PLy_ResultType = {
 	PLy_result_doc,				/* tp_doc */
 };
 
-#ifdef NOT_USED
-/* Appear to be unused */
 static PyMethodDef PLy_result_methods[] = {
-	{"fetch", (PyCFunction) PLy_result_fetch, METH_VARARGS, NULL,},
-	{"nrows", (PyCFunction) PLy_result_nrows, METH_VARARGS, NULL},
-	{"status", (PyCFunction) PLy_result_status, METH_VARARGS, NULL},
+	{"nrows", PLy_result_nrows, METH_VARARGS, NULL},
+	{"status", PLy_result_status, METH_VARARGS, NULL},
 	{NULL, NULL, 0, NULL}
 };
-#endif
 
 static PyMethodDef PLy_methods[] = {
 	/*
@@ -1758,17 +1749,9 @@ PLy_result_dealloc(PyObject * arg)
 }
 
 static PyObject *
-PLy_result_getattr(PyObject * self, char *attr)
+PLy_result_getattr(PyObject * self, char *name)
 {
-	return NULL;
-}
-
-#ifdef NOT_USED
-/* Appear to be unused */
-static PyObject *
-PLy_result_fetch(PyObject * self, PyObject * args)
-{
-	return NULL;
+	return Py_FindMethod(PLy_result_methods, self, name);
 }
 
 static PyObject *
@@ -1788,7 +1771,6 @@ PLy_result_status(PyObject * self, PyObject * args)
 	Py_INCREF(ob->status);
 	return ob->status;
 }
-#endif
 
 static int
 PLy_result_length(PyObject * arg)
-- 
GitLab