Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t2AzT-002LCJ-Rc for pgsql-general@arkaria.postgresql.org; Sat, 19 Oct 2024 15:03:40 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1t2AzR-003tqC-Rn for pgsql-general@arkaria.postgresql.org; Sat, 19 Oct 2024 15:03:38 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t2AzR-003tq4-Cy for pgsql-general@lists.postgresql.org; Sat, 19 Oct 2024 15:03:37 +0000 Received: from mail-oi1-x22b.google.com ([2607:f8b0:4864:20::22b]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1t2AzQ-001uqt-0f for pgsql-general@lists.postgresql.org; Sat, 19 Oct 2024 15:03:37 +0000 Received: by mail-oi1-x22b.google.com with SMTP id 5614622812f47-3e600ae1664so1062020b6e.2 for ; Sat, 19 Oct 2024 08:03:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1729350214; x=1729955014; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:references:in-reply-to :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=Npv0KrUHaebUirtILvUoXorl8easGiX6jokKp8wpLMc=; b=N8dLxz2S5nLdMz3NpW5a/gUPuKSnv6uXauolxzu7rtHnS2tVx4KOVu1YipjZgQVtOO fYok0A0dpsXPZ/PUYxG2QIT54H6QRXObBoZ1qL/lXs2vDbhdLONyInFLDVUy5sTxly/J NPwVYWAKDp4b1AIMSRQ+l7y2sBk/qLNldpySFk+6QS3OcFUNA4v3YRyegdGZKlrKgd3w fStqnAd8Doy3uIu/UtQWHf4gn55q5XrwPc8usoNZV2XbJl4IynYEDjMoIU4d8RGXh76a lt7eNQogn5hqQdKd3/jrlftbc8K0qKTSDvRG30Kh4mXK+zYev1OM03I+HZBKKpGJYZfv mcCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1729350214; x=1729955014; h=cc:to:subject:message-id:date:from:references:in-reply-to :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=Npv0KrUHaebUirtILvUoXorl8easGiX6jokKp8wpLMc=; b=RO21PleWN57ljwta0mOGYZ7xQVUtg3zfFc8BFxPjekrogZt6KTYBTHJCC3JpomC54J dnVJjzFlvcJSVNB1ApI4H3n/iCjRwtdhaOvjitTWQ/NF2RPinCQehP13qmZrjbdoIDq3 kj9F+0Ziw9y6ekm3pTfkXAD8CQvuiurB6aEeX2wBSrL70ZTbJu5xf4wc5ZMcIg0yg005 RS1M3nsM/7QedfGuKiYu5/0XAV96W100nNievPo9vwdbYXZg4RMLBmyQtrl8Gdh8Sdkj 8V6aFvNqO2dAsjjFmalXRqNnF9T4iaTUnyxBAE90w4MsNBy2CYBEftsKd7y7TdknCCkT gEOg== X-Gm-Message-State: AOJu0Yy5TMqvxpBKBGgFkoszUZ9BJYjuyvMLx3AmSUPLfEyAlrOlc3F3 4K70YEm/Pb+KcqdHXm/KORVqvayrRik2wgruYuAY0F1xGuLAYuaxIPdHqwcXZEVOzHN2IGYc2n/ lqTFQBt0uWsMKRNHh4uz9k4cdQQc= X-Google-Smtp-Source: AGHT+IGn//o+Clt0V3zQDYCwO1go+Yfu+2/RUPc219OJEzlWZ+ZluxniN7c0DPDvLmsDd1rNGGxYDdJ9cyoNsYhERw0= X-Received: by 2002:a05:6808:201f:b0:3e5:f9ee:a2b3 with SMTP id 5614622812f47-3e602c651admr4879693b6e.4.1729350214154; Sat, 19 Oct 2024 08:03:34 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:ac9:6c84:0:b0:56c:c9af:3ee6 with HTTP; Sat, 19 Oct 2024 08:03:33 -0700 (PDT) In-Reply-To: References: From: "David G. Johnston" Date: Sat, 19 Oct 2024 08:03:33 -0700 Message-ID: Subject: Re: RESET, NULL and empty-string valued settings and transaction isolation To: Marcelo Zabani Cc: "pgsql-generallists.postgresql.org" Content-Type: multipart/alternative; boundary="0000000000003504d90624d5b921" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000003504d90624d5b921 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Saturday, October 19, 2024, Marcelo Zabani wrote: > Hi, according to the docs, RESET sets the value of a setting to > "The default value is defined as the value that the parameter would have > had, if no SET had ever been issued for it in the current session" > > Which confuses me given that the value starts being NULL in the session > and then turns into an empty string: > $ psql > =3D> select current_setting('my.test', true) is null; -- true > =3D> set my.test =3D 'abc'; > =3D> reset my.test; > =3D> select current_setting('my.test', true) is null; -- false > =3D> select current_setting('my.test', true)=3D''; -- true > > A similar effect happens with transactions and SET LOCAL: > =3D> begin; > =3D*> set local my.test=3D'abc'; > =3D*> rollback; -- commit works too > =3D> select current_setting('my.test', true) =3D ''; -- true > > Is this expected? I thought even if I misunderstand the docs, the effect > isn't very nice because SQL like current_setting('my.some_boolean_setting= ')::boolean > will fail after a transaction with SET LOCAL sets it, a side-effect that > can be particularly confusing and basically requires usage of nullif(.., > '') or other explicit checks around every current_setting call-site in > practice. > The observed behavior is also the documented behavior. A setting value can never actually be the NULL value. NULL is only an indicator that a setting doesn=E2=80=99t exist - i.e., when current_setting= returns null it is not giving you the value of the named setting but instead giving you an alternative representation to an error message that the setting doesn=E2=80=99t exist. You can only reset a setting that does exist at which point it resets to its default/initial value. For custom settings this is always text and the default/initial value for a text setting is the empty string. There is a pending documentation patch about NULL values that enhances the coverage of this in the documentation. If you design a system that has to deal with a setting not existing in the session then you at least have the ability to test for that case without provoking an error. But it=E2=80=99s better IMO to design the system to en= sure the setting always exists up front and let its absence be an error that indicates a coding bug that needs to be fixed. There is also an open patch to add proper session variables and formally deprecate this hack-ish usage of the settings subsystem for this use case. David J. --0000000000003504d90624d5b921 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Saturday, October 19, 2024, Marcelo Zabani <mzabani@gmail.com> wrote:
Hi, according to the docs, RESET sets the value o= f a setting to
"The default value is defined as the value th= at the parameter would have had, if no SET had ever been issue= d for it in the current session"

Which confus= es me given that the value starts being NULL in the session and then turns = into an empty string:
$ psql
=3D> select current= _setting('my.test', true) is null; -- true
=3D> set my.test = =3D 'abc';
=3D> reset my.test;
=3D> select current_sett= ing('my.test', true) is null; -- false
=3D> select current_se= tting('my.test', true)=3D''; -- true

A similar effect happens with transactions and SET LOCAL:
=3D&= gt; begin;
=3D*> set local my.test=3D'abc';
=3D*> rollb= ack; -- commit works too
=3D> select current_setting('my.test'= ;, true) =3D ''; -- true

Is this expec= ted? I thought even if I misunderstand the docs, the effect isn't very = nice because SQL like current_setting('my.some_boolean_setting'= ;)::boolean will fail after a transaction with SET LOCAL sets it, a side-ef= fect that can be particularly confusing and basically requires usage of nul= lif(.., '') or other explicit checks around every current_setting c= all-site in practice.

The obser= ved behavior is also the documented behavior.

A se= tting value can never actually be the NULL value.=C2=A0 NULL is only an ind= icator that a setting doesn=E2=80=99t exist - i.e., when current_setting re= turns null it is not giving you the value of the named setting but instead = giving you an alternative representation to an error message that the setti= ng doesn=E2=80=99t exist.

You can only reset a set= ting that does exist at which point it resets to its default/initial value.= =C2=A0 For custom settings this is always text and the default/initial valu= e for a text setting is the empty string.

There is= a pending documentation patch about NULL values that enhances the coverage= of this in the documentation.

If you design a sys= tem that has to deal with a setting not existing in the session then you at= least have the ability to test for that case without provoking an error.= =C2=A0 But it=E2=80=99s better IMO to design the system to ensure the setti= ng always exists up front and let its absence be an error that indicates a = coding bug that needs to be fixed.

There is also a= n open patch to add proper session variables and formally deprecate this ha= ck-ish usage of the settings subsystem for this use case.

David J.

--0000000000003504d90624d5b921--