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.96) (envelope-from ) id 1vRqU8-006VCo-29 for pgsql-hackers@arkaria.postgresql.org; Sat, 06 Dec 2025 11:29:57 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vRqU7-00BWhG-0l for pgsql-hackers@arkaria.postgresql.org; Sat, 06 Dec 2025 11:29:55 +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.96) (envelope-from ) id 1vRqU6-00BWh7-2n for pgsql-hackers@lists.postgresql.org; Sat, 06 Dec 2025 11:29:55 +0000 Received: from udcm-wwu2.uni-muenster.de ([128.176.118.28]) by magus.postgresql.org with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vRqU5-003SFc-0M for pgsql-hackers@lists.postgresql.org; Sat, 06 Dec 2025 11:29:54 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=uni-muenster.de; i=@uni-muenster.de; q=dns/txt; s=uniout; t=1765020593; x=1796556593; h=message-id:date:mime-version:subject:to:cc:references: from:in-reply-to:content-transfer-encoding; bh=VxugvWy25mgP6GBdG4+bbcoUHWrLIDQwTwcjjovSH2A=; b=CQWAhA96p1iRgR0WTdHYxMRkpMDkkg8lzJBqmYoodpV63EGVlsHDAKOr latdVy7cH5W+bJRcItAq1/TJb6ERCW/Cttf3sWcY25d/XowpxNMYgSCI3 U7v9IPZfwY1g0Z73pzkuMb7asHcpmX6sDDNdmch00rqDNJDfiWqZzdeyF 1DI69exoxrosVQRajTB5qhPsSGGgNQXq0LTvWdGExd/fQidI2jlMqMGTS Js1+T7uhZTSYYrO6yCBBCAHvSsYfwk7GeGxG6mFWF8+nG0DGgZ+lQNrzJ zwoLHIjqVdG+77wOfofM9GzNYtB9q/qz13gcvp5Zm6+cQryqZTiqntCxD Q==; X-CSE-ConnectionGUID: kSa6JUVJSRachwW1iJ9CpQ== X-CSE-MsgGUID: gA7Vu5SyQraPjtAOwYIOXg== X-IronPort-AV: E=Sophos;i="6.20,254,1758578400"; d="scan'208";a="377530178" Received: from secmail.uni-muenster.de ([128.176.118.4]) by UDCM-RELAY2.UNI-MUENSTER.DE with ESMTP; 06 Dec 2025 12:29:51 +0100 Received: from [192.168.178.27] (dynamic-080-171-144-125.80.171.pool.telefonica.de [80.171.144.125]) by SECMAIL.UNI-MUENSTER.DE (Postfix) with ESMTPSA id BCB7E20ADF00; Sat, 6 Dec 2025 12:29:49 +0100 (CET) Message-ID: <8f7e3edc-ca20-46fc-8fa1-84aed33e1e46@uni-muenster.de> Date: Sat, 6 Dec 2025 12:29:48 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: proposal: schema variables To: Pavel Stehule Cc: Bruce Momjian , Dmitry Dolgov <9erthalion6@gmail.com>, Laurenz Albe , Erik Rijkers , Michael Paquier , Amit Kapila , DUVAL REMI , PostgreSQL Hackers , jian he , Alvaro Herrera , PegoraroF10 References: <62426ced-0795-4191-876a-4fa16d277757@uni-muenster.de> Content-Language: de-DE, en-GB From: Jim Jones In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 05/12/2025 07:50, Pavel Stehule wrote: > yes, there was a bug, fixed > Both mentioned issues are related to the declared target of this > patchset - maximal reduction of the size. Nice, the memory is now being freed after a DROP VARIABLE and the tab completion for LET and DROP VARIABLE works: postgres=# CREATE TEMPORARY VARIABLE var AS text; CREATE VARIABLE postgres=# LET var x postgres=# LET var = repeat('🐘', 200000000); LET postgres=# SELECT pg_size_pretty(used_bytes) FROM pg_backend_memory_contexts WHERE name = 'session variables'; pg_size_pretty ---------------- 763 MB (1 row) postgres=# DROP VARIABLE var x postgres=# DROP VARIABLE var; DROP VARIABLE postgres=# SELECT pg_size_pretty(used_bytes) FROM pg_backend_memory_contexts WHERE name = 'session variables'; pg_size_pretty ---------------- 240 bytes (1 row) -- DROP VARIABLE IF EXISTS also works: postgres=# DROP VARIABLE IF EXISTS x; DROP VARIABLE Some comments and a few minor issues: == session_variables_ddl.sql == 1) duplicate tests ... DROP VARIABLE IF EXISTS x; DROP VARIABLE IF EXISTS x; ... 2) Typos in some comments "should to fail" > "should fail" == Error messages == 3) It is not possible to create a VIEW that depends on a session variable, which makes perfect sense. postgres=# CREATE VIEW v AS SELECT variable(var); ERROR: session variable "var" cannot be referenced in a persistent object The error message is clear, but in case of TEMPORARY VIEWS it gets a bit misleading, since a TEMPORARY VIEW is not a persistent object: postgres=# CREATE TEMPORARY VIEW tv AS SELECT variable(var); ERROR: session variable "var" cannot be referenced in a persistent object Perhaps something more generic? For instance: errmsg("session variable \"%s\" cannot be referenced in catalog objects", param->paramvarname) == ddl.sgml == 4) There are invalid examples -- No schema qualified VARIABLE is supported: CREATE VARIABLE public.current_user_id AS integer; -- Only TEMPORARY VARIABLES are supported: CREATE VARIABLE var1 AS date; 5) The term "variable fence" is introduced and emphasised, but not described. 6) There is a slight repetition regarding the variable's isolation "This value is private to each session .." "The value of a session variable is local to the current session" I would write something along these lines: "Session variables are temporary database objects that can hold a value. A session variable can be created using the CREATE VARIABLE command and can only be accessed by its owner. The value of a session variable is stored in session memory and is private to each session. It is automatically released when the session ends. In a query, a session variable can only be referenced using the special VARIABLE(varname) syntax. This avoids any risk of collision between variable names and column names. You set the value of a session variable with the LET statement and retrieve it with SELECT: CREATE TEMPORARY VARIABLE var1 AS date; LET var1 = current_date; SELECT VARIABLE(var1); var1 ------------ 2025-12-06 (1 row) By default, retrieving a session variable returns NULL unless it has been set in the current session using the LET command. Session variables are not transactional: changes to their values persist even if the transaction is rolled back, similar to variables in procedural languages." == let.sgml == 7) Invalid example (missing TEMP/TEMPORARY) CREATE VARIABLE myvar AS integer; 8) Typo in the Synopsis (TEMPORAL should be TEMPORARY): CREATE { TEMP | TEMPORAL } VARIABLE [ IF NOT EXISTS ] name [ AS ] data_type 9) In the description it says "The CREATE VARIABLE command creates a temporal session variable.", but isn't the command now CREATE TEMP/TEMPORARY VARIABLE? Is it ok to remove the TEMPORARY in the description? 10) The description includes also info regarding SELECT and LET. Since this page is about CREATE TEMPORARY VARIABLE, I guess it is out of place? Thanks! Best, Jim