From 8f649c9ac45fbdff06efce84eb8cca17b29e9d3a Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Sat, 19 Dec 2009 22:23:21 +0000
Subject: [PATCH] Add documentation why reassigning PL/Python function
 parameters in the function body can have undesirable outcomes. (bug #5232)

---
 doc/src/sgml/plpython.sgml | 38 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/plpython.sgml b/doc/src/sgml/plpython.sgml
index 01feab8ec1a..a623f3509bd 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.42 2009/12/15 22:59:53 petere Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/plpython.sgml,v 1.43 2009/12/19 22:23:21 petere Exp $ -->
 
 <chapter id="plpython">
  <title>PL/Python - Python Procedural Language</title>
@@ -213,6 +213,42 @@ def __plpython_procedure_pymax_23456():
    above.  Use of named parameters is usually more readable.
   </para>
 
+  <para>
+   The arguments are set as global variables.  Because of the scoping
+   rules of Python, this has the subtle consequence that an argument
+   variable cannot be reassigned inside the function to the value of
+   an expression that involves the variable name itself, unless the
+   variable is redeclared as global in the block.  For example, the
+   following won't work:
+<programlisting>
+CREATE FUNCTION pystrip(x text)
+  RETURNS text
+AS $$
+  x = x.strip()  # error
+  return x
+$$ LANGUAGE plpythonu;
+</programlisting>
+   because assigning to <varname>x</varname>
+   makes <varname>x</varname> a local variable for the entire block,
+   and so the <varname>x</varname> on the right-hand side of the
+   assignment refers to a not-yet-assigned local
+   variable <varname>x</varname>, not the PL/Python function
+   parameter.  Using the <literal>global</literal> statement, this can
+   be made to work:
+<programlisting>
+CREATE FUNCTION pystrip(x text)
+  RETURNS text
+AS $$
+  global x
+  x = x.strip()  # ok now
+  return x
+$$ LANGUAGE plpythonu;
+</programlisting>
+   But it is advisable not to rely on this implementation detail of
+   PL/Python.  It is better to treat the function parameters as
+   read-only.
+  </para>
+
   <para>
    If an SQL null value<indexterm><primary>null value</primary><secondary
    sortas="PL/Python">PL/Python</secondary></indexterm> is passed to a
-- 
GitLab