Re: Possible bug in PL/Python? - Mailing list pgsql-general

From Jeroen Van Dongen
Subject Re: Possible bug in PL/Python?
Date
Msg-id BA32EBA0-D5FF-46EB-83C8-22916731A7D7@jkwadraat.net
Whole thread Raw
In response to Re: Possible bug in PL/Python?  (Adrian Klaver <adrian.klaver@gmail.com>)
List pgsql-general
Thanks! I'd missed that part apparently :(

Regards,
Jeroen

Op 17 jan. 2012 om 17:40 heeft Adrian Klaver <adrian.klaver@gmail.com> het volgende geschreven:

> On Tuesday, January 17, 2012 8:27:19 am Jeroen van Dongen wrote:
>> Hi,
>>
>> In a current project I've a PL/Python function that uses default
>> parameters, like this:
>>
>> CREATE FUNCTION auth.create_user(
>>    email text,
>>    initial_password text,
>>    display_name text DEFAULT NULL,
>>    mobile_phone text DEFAULT NULL,
>>    status auth.enum_user_status DEFAULT 'active'
>> ) RETURNS text AS $$
>> ... rest of function ...
>>
>> Now I try to test if 'display_name' is actually passed or not, and if not
>> set it to something sensible, like so:
>> ...
>>    if display_name is None:
>>        display_name = email[:email.find('@')]
>> ...
>>
>> And ... that fails with an error stating that 'display_name' is referenced
>> before assignment.
>> However, if I do it like this, it works:
>> ...
>> if display_name is None:
>>        real_display_name = email[:email.find('@')]
>> ...
>>
>> In straight Python the first example works, however in PL/Python only the
>> second works.
>>
>> Is this how it is supposed to be and did I perhaps miss something in the
>> docs, or is it a bug?
>
> http://www.postgresql.org/docs/9.0/interactive/plpython-funcs.html
>
> "
> 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:
>
> CREATE FUNCTION pystrip(x text)
>  RETURNS text
> AS $$
>  x = x.strip()  # error
>  return x
> $$ LANGUAGE plpythonu;
> because assigning to x makes x a local variable for the entire block, and so the
> x on the right-hand side of the assignment refers to a not-yet-assigned local
> variable x, not the PL/Python function parameter. Using the global statement,
> this can be made to work:
>
> CREATE FUNCTION pystrip(x text)
>  RETURNS text
> AS $$
>  global x
>  x = x.strip()  # ok now
>  return x
> $$ LANGUAGE plpythonu;
> 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.
>
> "
>>
>> Kind regards,
>> Jeroen
>
> --
> Adrian Klaver
> adrian.klaver@gmail.com

pgsql-general by date:

Previous
From: Fujii Masao
Date:
Subject: Re: Does Version 9.1 Streaming Replication Supports Multi-Master?
Next
From: Nick
Date:
Subject: Re: Whats the most efficient query for this result?