Re: Possible bug in PL/Python?

From: Jeroen Van Dongen <jeroen(at)jkwadraat(dot)net>
To: Adrian Klaver <adrian(dot)klaver(at)gmail(dot)com>
Cc: "pgsql-general(at)postgresql(dot)org" <pgsql-general(at)postgresql(dot)org>
Subject: Re: Possible bug in PL/Python?
Date: 2012-01-17 19:10:26
Message-ID: BA32EBA0-D5FF-46EB-83C8-22916731A7D7@jkwadraat.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Thanks! I'd missed that part apparently :(

Regards,
Jeroen

Op 17 jan. 2012 om 17:40 heeft Adrian Klaver <adrian(dot)klaver(at)gmail(dot)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(dot)klaver(at)gmail(dot)com

In response to

Browse pgsql-general by date

  From Date Subject
Next Message David Johnston 2012-01-17 19:54:14 Re: Whats the most efficient query for this result?
Previous Message Fujii Masao 2012-01-17 18:33:29 Re: Does Version 9.1 Streaming Replication Supports Multi-Master?