problem with custom_variable_classes

Started by Malcolm Studdover 17 years ago6 messagesgeneral
Jump to latest
#1Malcolm Studd
mstudd@recognia.com

Hi,

I have a pl/pgSQL function[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$; to calculate row numbers (based on [2]<http://www.depesz.com/index.php/2007/08/17/rownum-anyone-cumulative-sum-in-one-query/&gt;).
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$;
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/&gt;
<http://www.depesz.com/index.php/2007/08/17/rownum-anyone-cumulative-sum-in-one-query/&gt;

In reply to: Malcolm Studd (#1)
Re: problem with custom_variable_classes

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

#3Taras Kopets
tkopets@gmail.com
In reply to: hubert depesz lubaczewski (#2)
Re: problem with custom_variable_classes

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

#4Tom Lane
tgl@sss.pgh.pa.us
In reply to: hubert depesz lubaczewski (#2)
Re: problem with custom_variable_classes

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

In reply to: Tom Lane (#4)
Re: problem with custom_variable_classes

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

#6Malcolm Studd
mstudd@recognia.com
In reply to: Taras Kopets (#3)
Re: problem with custom_variable_classes

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