[BUGS] BUG #5232: plpythonu s=s.op() raises an exception

3 views
Skip to first unread message

David Gardner

unread,
Dec 3, 2009, 3:06:59 PM12/3/09
to

The following bug has been logged online:

Bug reference: 5232
Logged by: David Gardner
Email address: dgar...@creatureshop.com
PostgreSQL version: 8.4.1
Operating system: Debian, amd64
Description: plpythonu s=s.op() raises an exception
Details:

If I create the following:
CREATE OR REPLACE FUNCTION pyreplace(src text,s text)
RETURNS text AS
$BODY$
try:
src=src.replace(s,'')
return src
except Exception,e:
return str(e)
$BODY$
LANGUAGE 'plpythonu' VOLATILE
COST 100;
ALTER FUNCTION pyreplace(src text,s text) OWNER TO dgardner;

Then:
SELECT * FROM pyreplace('this is a very long string','is');
pyreplace
---------------------------------------------------
local variable 'src' referenced before assignment
(1 row)


However in python I can do:
def pyreplace(src,s):
try:
src=src.replace(s,'')
return src
except Exception,e:
return str(e)

pyreplace('this is a very long string','is')
-----
produces:
'th a very long string'

--
Sent via pgsql-bugs mailing list (pgsql...@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

Tom Lane

unread,
Dec 3, 2009, 5:30:38 PM12/3/09
to
"David Gardner" <dgar...@creatureshop.com> writes:
> CREATE OR REPLACE FUNCTION pyreplace(src text,s text)
> RETURNS text AS
> $BODY$
> try:
> src=src.replace(s,'')
> return src
> except Exception,e:
> return str(e)
> $BODY$
> LANGUAGE 'plpythonu' VOLATILE
> COST 100;

Weird. You seem to need both the try block and the overwrite of the
parameter to make it misbehave. I suspect this means we're doing
something a bit wrong in setting up the python variable for the
parameter. Unfortunately I don't know enough about python to go further
than that.

regards, tom lane

David Gardner

unread,
Dec 3, 2009, 5:46:31 PM12/3/09
to
Not sure about the try block being related, I included it in my example mostly because the example is a simplified version of some code I was working on that had a try/except block.
I tried the function without the try block and it raised the same exception (just uncaught):

CREATE OR REPLACE FUNCTION pyreplacenotry(src text, s text)
  RETURNS text AS
$BODY$
src=src.replace(s,'')
return src

$BODY$
  LANGUAGE 'plpythonu' VOLATILE
  COST 100;
ALTER FUNCTION pyreplacenotry(text, text) OWNER TO dgardner;

gives me:
ERROR:  PL/Python: PL/Python function "pyreplacenotry" failed
DETAIL:  <type 'exceptions.UnboundLocalError'>: local variable 'src' referenced before assignment


********** Error **********

ERROR: PL/Python: PL/Python function "pyreplacenotry" failed
SQL state: XX000
Detail: <type 'exceptions.UnboundLocalError'>: local variable 'src' referenced before assignment


However this works:
CREATE OR REPLACE FUNCTION pyreplacenoreassign(src text, s text)
  RETURNS text AS
$BODY$
return src.replace(s,'')

$BODY$
  LANGUAGE 'plpythonu' VOLATILE
  COST 100;
ALTER FUNCTION pyreplacenoreassign(text, text) OWNER TO dgardner;



Tom Lane wrote:
"David Gardner" <dgar...@creatureshop.com> writes:
  
CREATE OR REPLACE FUNCTION pyreplace(src text,s text)
  RETURNS text AS
$BODY$
try:
    src=src.replace(s,'')
    return src
except Exception,e:
    return str(e)
$BODY$
  LANGUAGE 'plpythonu' VOLATILE
  COST 100;
    
Weird.  You seem to need both the try block and the overwrite of the
parameter to make it misbehave.  I suspect this means we're doing
something a bit wrong in setting up the python variable for the
parameter.  Unfortunately I don't know enough about python to go further
than that.

			regards, tom lane

  


-- 
David Gardner
Pipeline Tools Programmer
Jim Henson Creature Shop
dgar...@creatureshop.com

Peter Eisentraut

unread,
Dec 3, 2009, 6:57:10 PM12/3/09
to
On tor, 2009-12-03 at 14:46 -0800, David Gardner wrote:
> Not sure about the try block being related, I included it in my
> example mostly because the example is a simplified version of some
> code I was working on that had a try/except block.
> I tried the function without the try block and it raised the same
> exception (just uncaught):
>
> CREATE OR REPLACE FUNCTION pyreplacenotry(src text, s text)
> RETURNS text AS
> $BODY$
> src=src.replace(s,'')
> return src
> $BODY$
> LANGUAGE 'plpythonu' VOLATILE
> COST 100;
> ALTER FUNCTION pyreplacenotry(text, text) OWNER TO dgardner;
>
> gives me:
> ERROR: PL/Python: PL/Python function "pyreplacenotry" failed
> DETAIL: <type 'exceptions.UnboundLocalError'>: local variable 'src'
> referenced before assignment

What is going on internally is something like this:

src = 'xyz'

def pyreplacenotry():
src=src.replace('x', 'y')
return src

pyreplacenotry()

which fails with that same error. So you should not try to assign to
the parameters of a function.

Tom Lane

unread,
Dec 3, 2009, 7:02:31 PM12/3/09
to
Peter Eisentraut <pet...@gmx.net> writes:
> ... So you should not try to assign to

> the parameters of a function.

If it's allowed in normal Python functions, that definitely needs to be
documented. Better would be to fix it or at least throw a more
intelligible error ...

regards, tom lane

Peter Eisentraut

unread,
Dec 19, 2009, 5:23:30 PM12/19/09
to
On tor, 2009-12-03 at 19:02 -0500, Tom Lane wrote:
> Peter Eisentraut <pet...@gmx.net> writes:
> > ... So you should not try to assign to
> > the parameters of a function.
>
> If it's allowed in normal Python functions, that definitely needs to be
> documented. Better would be to fix it or at least throw a more
> intelligible error ...

I have added documentation for it.

Reply all
Reply to author
Forward
0 new messages