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 1sPpaT-006Y79-KQ for pgsql-hackers@arkaria.postgresql.org; Fri, 05 Jul 2024 20:31:21 +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 1sPpaR-00Dxvk-9p for pgsql-hackers@arkaria.postgresql.org; Fri, 05 Jul 2024 20:31:19 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sPpaQ-00DxvV-PP for pgsql-hackers@lists.postgresql.org; Fri, 05 Jul 2024 20:31:19 +0000 Received: from momjian.us ([72.94.173.45]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sPpaO-000aaK-Jl for pgsql-hackers@postgresql.org; Fri, 05 Jul 2024 20:31:18 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=momjian.us; s=2024011501; h=In-Reply-To:Content-Type:MIME-Version:References:Message-ID: Subject:Cc:To:From:Date:Sender:Reply-To:Content-Transfer-Encoding:Content-ID: Content-Description; bh=JVxk8hkGAkUfWwvjOnjPo8mTAnxHAd2Sj/HZOmPG4G8=; b=R0HKM fQwxU0XnoyMWDjGcFMnntxJ4vtn3MEZV5sh/C0C5U0L+Vk4C3QcTVgiv7G635Hga/yzgvCW5EvtRC ICYbQUXqU7sHtENhquJUxtH6BjeWyN/1lXnCbOmrip8KSQttci7gTmNZkw25PsO9A5gvqUvGfCFM9 /QrqyH+mzJCJ8I+aQcaN7ZjoLCG/EYhFjAhlMPQi4HPi/ula+A6AF4dgkHT3NIzElTiLArhUxSADu Dz8kTb91M1wP47sSPlGDLdPLUsKIwaYh9ArlhLLc+9p/CHirvYJarJ8TUfXlpwE+Xj7M+BYy5KPdz 0CZcWA5TnC7Nq1Q+xUFKAEJ3Dl/2w==; Received: from bruce by momjian.us with local (Exim 4.96) (envelope-from ) id 1sPpaL-008cif-1s; Fri, 05 Jul 2024 16:31:13 -0400 Date: Fri, 5 Jul 2024 16:31:13 -0400 From: Bruce Momjian To: David Rowley Cc: "David G. Johnston" , Peter Eisentraut , Tom Lane , James Coleman , pgsql-hackers Subject: Re: Should we document how column DEFAULT expressions work? Message-ID: References: <1642803.1719447063@sss.pgh.pa.us> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="5LFC0ZuhqVL/lrXN" Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --5LFC0ZuhqVL/lrXN Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Mon, Jul 1, 2024 at 02:52:42PM +1200, David Rowley wrote: > On Mon, 1 Jul 2024 at 13:41, David G. Johnston > wrote: > > I presume the relatively new atomic SQL functions pose a similar hazard. > > Do you have an example of this? > > > The fact that 'now()'::timestamp fails to fail doesn't help... > > If that's the case, maybe a tiny step towards what Peter proposed is > just to make trailing punctuation fail for timestamp special values in > v18. I dug into this and I have a suggestion at the end. First, the special values like 'now' are the only values that can be optionally quoted: SELECT current_timestamp::timestamptz; current_timestamp ------------------------------- 2024-07-05 15:15:22.692072-04 SELECT 'current_timestamp'::timestamptz; ERROR: invalid input syntax for type timestamp with time zone: "current_timestamp" Also interestingly, "now" without quotes requires parentheses to make it a function call: SELECT 'now'::timestamptz; timestamptz ------------------------------- 2024-07-05 15:17:11.394182-04 SELECT 'now()'::timestamptz; timestamptz ------------------------------- 2024-07-05 15:17:15.201621-04 SELECT now()::timestamptz; now ------------------------------- 2024-07-05 15:17:21.925611-04 SELECT now::timestamptz; ERROR: column "now" does not exist LINE 1: SELECT now::timestamptz; ^ And the quoting shows "now" evaluation at function creation time: CREATE OR REPLACE FUNCTION testnow() RETURNS timestamptz LANGUAGE SQL RETURN 'now'::timestamptz; SELECT testnow(); SELECT pg_sleep(5); SELECT testnow(); testnow ------------------------------- 2024-07-05 15:19:38.915255-04 testnow ------------------------------- 2024-07-05 15:19:38.915255-04 -- same --------------------------------------------------------------------------- CREATE OR REPLACE FUNCTION testnow() RETURNS timestamptz LANGUAGE SQL RETURN 'now()'::timestamptz; SELECT testnow(); SELECT pg_sleep(5); SELECT testnow(); testnow ------------------------------- 2024-07-05 15:20:41.475997-04 testnow ------------------------------- 2024-07-05 15:20:41.475997-04 -- same --------------------------------------------------------------------------- CREATE OR REPLACE FUNCTION testnow() RETURNS timestamptz LANGUAGE SQL RETURN now()::timestamptz; SELECT testnow(); SELECT pg_sleep(5); SELECT testnow(); testnow ------------------------------- 2024-07-05 15:21:18.204574-04 testnow ------------------------------- 2024-07-05 15:21:23.210442-04 -- different I don't think we can bounce people around to different sections to explain this --- I think we need text in the CREATE TABLE ... DEFAULT section. I think the now() case is unusual since there are few cases where function calls can be put inside of single quotes. I have written the attached patch to clarify the behavior. -- Bruce Momjian https://momjian.us EDB https://enterprisedb.com Only you can decide what is important to you. --5LFC0ZuhqVL/lrXN Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="create_default.diff" diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index f19306e7760..9bab4ec141e 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -888,6 +888,14 @@ WITH ( MODULUS numeric_literal, REM match the data type of the column. + + Note, a string that returns a volatile result once cast to + a data type, like 'now'::timestamptz and + 'now()'::timestamptz, is evaluated at table + creation time, while now()::timestamptz (without + quotes) is evaluated at data insertion time. + + The default expression will be used in any insert operation that does not specify a value for the column. If there is no default --5LFC0ZuhqVL/lrXN--