BUG #15646: Inconsistent behavior for current_setting/set_config

Started by PG Bug reporting formalmost 7 years ago9 messages
#1PG Bug reporting form
noreply@postgresql.org

The following bug has been logged on the website:

Bug reference: 15646
Logged by: Eugen Konkov
Email address: kes-kes@yandex.ru
PostgreSQL version: 10.4
Operating system: (Debian 10.4-2.pgdg90+1)
Description:

Hi.

[documentation](https://www.postgresql.org/docs/11/functions-admin.html#FUNCTIONS-ADMIN-SET)
describes that:

set_config sets the parameter setting_name to new_value. If is_local is

true, the new value will only apply to the current transaction.

Thus if I rollback transaction original value should be available.

But current behavior returns empty string instead of NULL (the initial
value) after transaction is rolled back. When I restart session, NULL is
returned again as it is expected.
( I expect NULL just because 'my.app_period' is not configuration variable
is not defined yet. The documentation (link provided above) does not cover
what should be returned)

How to reproduce steps:
$ make dbshell
psql -h databases -p 5433 -U tucha tucha ||:
psql (11.1 (Ubuntu 11.1-1.pgdg16.04+1), server 10.4 (Debian
10.4-2.pgdg90+1))
Type "help" for help.

We start a new session and check setting value before transaction. It is
NULL:
tucha=> select current_setting( 'my.app_period', true ) is null;
?column?
----------
t
(1 row)

We start transaction and change the setting value:
tucha=> begin;
BEGIN
tucha=> select set_config( 'my.app_period', 'some value', true );
set_config
------------
some value
(1 row)

We can see that value is changed. It is NOT NULL:
tucha=> select current_setting( 'my.app_period', true ) is null;
?column?
----------
f
(1 row)

tucha=> select current_setting( 'my.app_period', true );
current_setting
-----------------
some value
(1 row)

Here I finish transaction (it has no matter how: commit/rollback):
tucha=> rollback;
ROLLBACK

Here we can see that setting value is different from value that was before
transaction
tucha=> select current_setting( 'my.app_period', true ) is null;
?column?
----------
f
(1 row)

tucha=> \q

When I restart session I get NULL again (as expected):
kes@work ~/t $ make dbshell
psql -h databases -p 5433 -U tucha tucha ||:
psql (11.1 (Ubuntu 11.1-1.pgdg16.04+1), server 10.4 (Debian
10.4-2.pgdg90+1))
Type "help" for help.

tucha=> select current_setting( 'my.app_period', true ) is null;
?column?
----------
t
(1 row)

My database version:
tucha=> select version();
version

------------------------------------------------------------------------------------------
PostgreSQL 10.4 (Debian 10.4-2.pgdg90+1) on x86_64-pc-linux-gnu, compiled
by gcc (Debian
(1 row)

#2Joe Conway
mail@joeconway.com
In reply to: PG Bug reporting form (#1)
Re: BUG #15646: Inconsistent behavior for current_setting/set_config

On 2/20/19 11:10 AM, PG Bug reporting form wrote:

The following bug has been logged on the website:

Bug reference: 15646
Logged by: Eugen Konkov
Email address: kes-kes@yandex.ru
PostgreSQL version: 10.4
Operating system: (Debian 10.4-2.pgdg90+1)
Description:

Hi.

[documentation](https://www.postgresql.org/docs/11/functions-admin.html#FUNCTIONS-ADMIN-SET)
describes that:

set_config sets the parameter setting_name to new_value. If is_local is

true, the new value will only apply to the current transaction.

Thus if I rollback transaction original value should be available.

But current behavior returns empty string instead of NULL (the initial
value) after transaction is rolled back. When I restart session, NULL is
returned again as it is expected.

This has been discussed before and dismissed:
/messages/by-id/56842412.5000005@joeconway.com

Personally I agree it is a bug, but I am not sure you will get much
support for that position.

Joe

--
Crunchy Data - http://crunchydata.com
PostgreSQL Support for Secure Enterprises
Consulting, Training, & Open Source Development

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Joe Conway (#2)
Re: BUG #15646: Inconsistent behavior for current_setting/set_config

Joe Conway <mail@joeconway.com> writes:

On 2/20/19 11:10 AM, PG Bug reporting form wrote:

But current behavior returns empty string instead of NULL (the initial
value) after transaction is rolled back. When I restart session, NULL is
returned again as it is expected.

This has been discussed before and dismissed:
/messages/by-id/56842412.5000005@joeconway.com
Personally I agree it is a bug, but I am not sure you will get much
support for that position.

The fact that we allow undeclared user-defined GUCs at all is a bug IMO.
We need to find a way to replace that behavior with something whereby
the name and type of a parameter are declared up-front before you can
set it.

regards, tom lane

#4David G. Johnston
david.g.johnston@gmail.com
In reply to: Tom Lane (#3)
Re: BUG #15646: Inconsistent behavior for current_setting/set_config

On Wed, Feb 20, 2019 at 10:11 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Joe Conway <mail@joeconway.com> writes:

On 2/20/19 11:10 AM, PG Bug reporting form wrote:

But current behavior returns empty string instead of NULL (the initial
value) after transaction is rolled back. When I restart session, NULL is
returned again as it is expected.

This has been discussed before and dismissed:
/messages/by-id/56842412.5000005@joeconway.com
Personally I agree it is a bug, but I am not sure you will get much
support for that position.

The fact that we allow undeclared user-defined GUCs at all is a bug IMO.
We need to find a way to replace that behavior with something whereby
the name and type of a parameter are declared up-front before you can
set it.

We should at least document the existing working-as-intended behavior
then. This, the linked thread, and Bug # 14877 are all caused by
insufficient documentation of the current behavior. Users should be
informed that as far as the GUC system is concerned NULL and the empty
string are equivalent and that resetting uses the empty string while
never being set returns NULL.

Its immaterial whether its existence is due to a bug that simply
became acceptable or was an otherwise retrospectively poor design
decision - at this point we have to live with it and should treat it
as a proper and supported feature, if only in its current form. At
least until someone feels strongly enough to deprecate it and put
something else more suitable in its place.

David J.

#5Jerry Sievert
jerry@legitimatesounding.com
In reply to: David G. Johnston (#4)
Re: BUG #15646: Inconsistent behavior for current_setting/set_config

Hi,

On Feb 20, 2019, at 9:32 AM, David G. Johnston <david.g.johnston@gmail.com> wrote:
Users should be
informed that as far as the GUC system is concerned NULL and the empty
string are equivalent and that resetting uses the empty string while
never being set returns NULL.

Except that it’s not - the code path in guc.c uses what is passed as the boot value:

var->boot_val <https://doxygen.postgresql.org/structconfig__string.html#ad6895b2d95aa9e5c3ff2169d7fe2bc20&gt; = bootValue;

It’s up to the extension developer to understand that this can be changed back to something other than the boot value and not actually be the boot value - you can see this assumption being made in plpgsql, pltcl, and plperl. The GUC system makes no notification that the two are equivalent, neither in code nor in documentation.

Its immaterial whether its existence is due to a bug that simply
became acceptable or was an otherwise retrospectively poor design
decision - at this point we have to live with it and should treat it
as a proper and supported feature, if only in its current form. At
least until someone feels strongly enough to deprecate it and put
something else more suitable in its place.

Agreed, but it needs to be documented, the current documentation gives only the boot value, and does not note that string variables are the only variables that behave differently and do not return to their boot value.

#6Joe Conway
mail@joeconway.com
In reply to: Tom Lane (#3)
Re: BUG #15646: Inconsistent behavior for current_setting/set_config

On 2/20/19 12:11 PM, Tom Lane wrote:

Joe Conway <mail@joeconway.com> writes:

On 2/20/19 11:10 AM, PG Bug reporting form wrote:

But current behavior returns empty string instead of NULL (the initial
value) after transaction is rolled back. When I restart session, NULL is
returned again as it is expected.

This has been discussed before and dismissed:
/messages/by-id/56842412.5000005@joeconway.com
Personally I agree it is a bug, but I am not sure you will get much
support for that position.

The fact that we allow undeclared user-defined GUCs at all is a bug IMO.
We need to find a way to replace that behavior with something whereby
the name and type of a parameter are declared up-front before you can
set it.

(moving to hackers)

Perhaps we could do something like:

1. If the user-defined GUC is defined in postgresql.conf, et al, same
behavior as now
2. Backward compatibility concerns would be an issue, so create another
new GUC declare_custom_settings which initially defaults to false.
3. If declare_custom_settings is true, and the user-defined GUC is not
defined in postgresql.conf, then in order to create it dynamically
via SET or similar methods, you must do something like:

CREATE SETTING name TYPE guctype [LIST];
SET name TO value;

Joe

--
Crunchy Data - http://crunchydata.com
PostgreSQL Support for Secure Enterprises
Consulting, Training, & Open Source Development

#7Eugen Konkov
kes-kes@yandex.ru
In reply to: Joe Conway (#6)
Re: BUG #15646: Inconsistent behavior for current_setting/set_config

Hello,

Not sure I should open new issue or continue this one.

select set_config( 'my.some_conf', 'value', true );

does not issue warning if there is no transaction in progress.

I faced into this problem when call to stored function which make use
of configurations. and missed that this function has no effect because
there is no transaction in progress

--
Best regards,
Eugen Konkov

#8Eugen Konkov
kes-kes@yandex.ru
In reply to: Eugen Konkov (#7)
Re: BUG #15646: Inconsistent behavior for current_setting/set_config

Hello

Documentation has no description how 'false' value for 'is_local' parameter interact with transaction

Do I understand correct?

https://www.postgresql.org/docs/11/functions-admin.html#FUNCTIONS-ADMIN-SET

set_config sets the parameter setting_name to new_value. If is_local is true, the new value will only apply to the current transaction. If you want the new value to apply for the current session, use false instead.

If I use 'false' then transaction will not have effect, because I set the value to session?

tucha=> select current_setting( 'my.app_period', true );
current_setting
-----------------

(1 row)

tucha=> begin;
BEGIN
tucha=> select set_config( 'my.app_period', tstzrange( '-infinity', 'infinity' )::text, false );
set_config
----------------------
[-infinity,infinity)
(1 row)

tucha=> rollback;
ROLLBACK

NOTICE: session is rolled back and session value is rolled back despite on that I did not use 'true' as parameter for local:

tucha=> select current_setting( 'my.app_period', true );
current_setting
-----------------

(1 row)

tucha=> begin;
BEGIN
tucha=> select set_config( 'my.app_period', tstzrange( '-infinity', 'infinity' )::text, false );
set_config
----------------------
[-infinity,infinity)
(1 row)

tucha=> commit;
COMMIT

When I commit then the value is applied to session:
tucha=> select current_setting( 'my.app_period', true );
current_setting
----------------------
[-infinity,infinity)
(1 row)

--
Best regards,
Eugen Konkov

#9David G. Johnston
david.g.johnston@gmail.com
In reply to: Eugen Konkov (#8)
Re: BUG #15646: Inconsistent behavior for current_setting/set_config

On Tuesday, February 26, 2019, Eugen Konkov <kes-kes@yandex.ru> wrote:

If I use 'false' then transaction will not have effect, because I set the
value to session?

The current transaction is always affected. True meansonly; false causes
the change to persist beyond, for the life of the session.

Davis J.