Thread: problem with custom_variable_classes

problem with custom_variable_classes

From
Malcolm Studd
Date:
Hi,

I have a pl/pgSQL function[1] to calculate row numbers (based on [2]).
It uses a custom variable. This was working earlier, but is breaking now
saying it can't recognise the variable. The custom_variable_classes is
set in the postgresql.conf.

pgdb001=> select rownum('') from generate_series(1,10);
ERROR:  unrecognized configuration parameter "olap.rownum_name"
pgdb001=> show custom_variable_classes;
  custom_variable_classes
-------------------------
  olap
(1 row)

I am using PostgreSQL 8.3.3 on CentOS 5.2 x64.

TIA,

Malcolm


[1]
  CREATE OR REPLACE FUNCTION rownum(in_code TEXT)
         RETURNS INT4
         LANGUAGE plpgsql
         as $BODY$
DECLARE
         current_id TEXT;
         current_rownum INT4;
         settings_id TEXT;
BEGIN
         current_id := statement_timestamp()::TEXT || in_code;
         settings_id := current_setting('olap.rownum_name');
         IF settings_id IS DISTINCT FROM current_id THEN
                 PERFORM set_config('olap.rownum_name',
current_id::TEXT, false);
                 current_rownum := 0;
         ELSE
                 current_rownum :=
current_setting('olap.rownum_count')::INT4;
         END IF;
         current_rownum := current_rownum + 1;
         PERFORM set_config('olap.rownum_count', current_rownum::TEXT,
false);
         RETURN current_rownum;
END;
         $BODY$;

[2]
<http://www.depesz.com/index.php/2007/08/17/rownum-anyone-cumulative-sum-in-one-query/>


Re: problem with custom_variable_classes

From
hubert depesz lubaczewski
Date:
On Wed, Sep 24, 2008 at 12:15:41PM -0400, Malcolm Studd wrote:
> I have a pl/pgSQL function[1] to calculate row numbers (based on [2]).
> It uses a custom variable. This was working earlier, but is breaking now
> saying it can't recognise the variable. The custom_variable_classes is
> set in the postgresql.conf.
> pgdb001=> select rownum('') from generate_series(1,10);
> ERROR:  unrecognized configuration parameter "olap.rownum_name"
> pgdb001=> show custom_variable_classes;
>  custom_variable_classes
> -------------------------
>  olap
> (1 row)
>         settings_id := current_setting('olap.rownum_name');

it looks like a bug to me.
it did work in 8.2, and it doesn't in 8.3, or in 8.4.

while manual in 8.4 still states:
"When custom_variable_classes is set, the server will accept definitions of arbitrary variables within each specified
class.".

so it should work, but it doesn't:
# show custom_variable_classes ;
 custom_variable_classes
-------------------------
 depesz
(1 row)
# select current_setting('depesz.xxx');
ERROR:  unrecognized configuration parameter "depesz.xxx"

of course i still can set a value, and then get it:
# select set_config('depesz.xxx', 'xx', false);
 set_config
------------
 xx
(1 row)
# select current_setting('depesz.xxx');
 current_setting
-----------------
 xx
(1 row)

but it means that there is currently no way to check if there is value in this
- i.e. if it has been initialized.

i would suggest to return "NULL" when calling current_setting on unknown variable.

this is not how it worked in 8.2 (it returned empty string), but NULL is (in my opinion) better choice.

strangely - name of "current_setting" function nor "custom_variable_classes"
doesn't show in any release docs, which makes the change somewhat mysterious.

Best regards,

depesz

--
Linkedin: http://www.linkedin.com/in/depesz  /  blog: http://www.depesz.com/
jid/gtalk: depesz@depesz.com / aim:depeszhdl / skype:depesz_hdl / gg:6749007

Re: problem with custom_variable_classes

From
"Taras Kopets"
Date:
On Thu, Sep 25, 2008 at 12:38 AM, hubert depesz lubaczewski
<depesz@depesz.com> wrote:
> but it means that there is currently no way to check if there is value in this
> - i.e. if it has been initialized.

now you have to initialize this variable once per session before usage:

SELECT set_config('olap.rownum_name', false);

Regards,
Taras Kopets

Re: problem with custom_variable_classes

From
Tom Lane
Date:
hubert depesz lubaczewski <depesz@depesz.com> writes:
> while manual in 8.4 still states:
> "When custom_variable_classes is set, the server will accept definitions of arbitrary variables within each specified
class.".

It will accept *definitions*, yes.  I can't imagine why you'd think
it's a good idea to not throw error when asked for an unknown variable's
value.

The whole custom-variable thing is being abused far beyond what the
facility was intended for, anyway.  Rather than allowing variables to
spring into existence like magic, what we should have is some facility
for letting session-local variables be *declared*, complete with type
(int/real/string) and other info as needed.  See the archives --- this
was discussed not too long ago.

            regards, tom lane

Re: problem with custom_variable_classes

From
hubert depesz lubaczewski
Date:
On Wed, Sep 24, 2008 at 07:33:27PM -0400, Tom Lane wrote:
> It will accept *definitions*, yes.  I can't imagine why you'd think
> it's a good idea to not throw error when asked for an unknown variable's
> value.

because this is how it worked.
i'm not saying it was good. it worked that way, and introducing such
change made some code (rownum in this example) not working.

i understand that postgresql is more about correctness than end-user
niceness, which has some obvious benefits, but i think - in such cases
at least a one-line information in release docs wouldn't be out of
place.

> The whole custom-variable thing is being abused far beyond what the
> facility was intended for, anyway.

i think it's great idea. somebody thought about cool thing for modules,
other people found other uses for it.
right now they are being effectively punished for
creativeness (unfortunatelly i can't say it is me, as i got the variable
trick from somebody else).

best regards,

depesz


--
Linkedin: http://www.linkedin.com/in/depesz  /  blog: http://www.depesz.com/
jid/gtalk: depesz@depesz.com / aim:depeszhdl / skype:depesz_hdl / gg:6749007

Re: problem with custom_variable_classes

From
Malcolm Studd
Date:
Taras Kopets wrote:
> now you have to initialize this variable once per session before usage:
>
> SELECT set_config('olap.rownum_name', false);

Ok, thanks. That has fixed my problem.

Malcolm