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 1s89Ja-00AFMZ-T1 for pgsql-hackers@arkaria.postgresql.org; Sat, 18 May 2024 01:56:52 +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 1s89JZ-002AdJ-Vv for pgsql-hackers@arkaria.postgresql.org; Sat, 18 May 2024 01:56:49 +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 1s89JZ-002Acv-F6 for pgsql-hackers@lists.postgresql.org; Sat, 18 May 2024 01:56:49 +0000 Received: from mout-u-107.mailbox.org ([80.241.59.207]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1s89JW-000kXb-20 for pgsql-hackers@lists.postgresql.org; Sat, 18 May 2024 01:56:48 +0000 Received: from smtp1.mailbox.org (smtp1.mailbox.org [IPv6:2001:67c:2050:b231:465::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-u-107.mailbox.org (Postfix) with ESMTPS id 4Vh6Py1ybLz9t1d; Sat, 18 May 2024 03:56:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ewie.name; s=MBO0001; t=1715997398; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=LOKnr1soaLaBxablhDsaaCMzlPlmAzmDgFV3Lh8F0Xk=; b=Mvo6Tnl7tTX3nUuJPvePYz1SOp9Ff7zQXBM7MXuBNPYInwYHWHP2/ZgIUzCYX43dsNeYHG 2TViV6Nd+xDjixCHyVE6QZdPruuacZBjcBVUIpN3kiMZ6l4XTMvABTeDbh/cVT5HXZzXGW FHDwNCOM0Haub5tXSYdAwYP+1XzXSL24mSuyvpHrOqkINyqp6nyOEiwsG9x0wIg2OK/+J8 Th3Yi8mnEsJlYJgEczvqiPpvMbAvfgzjl5Me1kb2roa67rFe+15uCN6/pV6lR/SPZgVDga O+HEtpfcwjDB45DFF40HTpLtWO68RSoZerYTMbAwceShp5tPpjNGgqvDVSuqwA== Date: Sat, 18 May 2024 03:56:36 +0200 From: Erik Wienhold To: "David G. Johnston" Cc: Robert Haas , Hannu Krosing , Peter Eisentraut , PostgreSQL Hackers Subject: Re: CREATE TABLE creates a composite type corresponding to the table row, which is and is not there Message-ID: <1cd8a224-4038-43ba-bb11-a4cd8d015462@ewie.name> References: <73jtqglviqor5ozqrthjmau7nj4xi7z4obzaqflf7cvliaf4em@4obr7wqlqkye> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="p7whpo2b3ruhdelr" Content-Disposition: inline In-Reply-To: X-Rspamd-Queue-Id: 4Vh6Py1ybLz9t1d List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --p7whpo2b3ruhdelr Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On 2024-05-18 03:27 +0200, David G. Johnston wrote: > > On 2024-05-16 17:47 +0200, David G. Johnston wrote: > > > We have a glossary. > > If sticking with stand-alone composite type as a formal term we should > document it in the glossary. It's unclear whether this will survive review > though. With the wording provided in this patch it doesn't really add > enough to continue a strong defense of it. Oh, I thought you meant we already have that term in the glossary (I haven't checked until now). Let's see if we can convince Robert of the rewording. > > It's now a separate error message (like I already had in v1) which > > states that the specified type must not be a row type of another table > > (based on Peter's feedback). And the hint directs the user to CREATE > > TYPE. > > > > In passing, I also quoted the type name in the existing error message > > for consistency. I saw that table names etc. are already quoted in > > other error messages. > > > > > The hint and the quoting both violate the documented rules for these things: > > https://www.postgresql.org/docs/current/error-style-guide.html#ERROR-STYLE-GUIDE-QUOTES > > There are functions in the backend that will double-quote their own output > as needed (for example, format_type_be()). Do not put additional quotes > around the output of such functions. > > https://www.postgresql.org/docs/current/error-style-guide.html#ERROR-STYLE-GUIDE-GRAMMAR-PUNCTUATION > > Detail and hint messages: Use complete sentences, and end each with a > period. Capitalize the first word of sentences. Thanks, I didn't know that guideline. Both fixed in v6. -- Erik --p7whpo2b3ruhdelr Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v6-0001-Document-that-typed-tables-rely-on-CREATE-TYPE.patch" From 39d2dc9b58dfa3b68245070648ecdf9eed892c7a Mon Sep 17 00:00:00 2001 From: Erik Wienhold Date: Fri, 8 Mar 2024 04:21:56 +0100 Subject: [PATCH v6] Document that typed tables rely on CREATE TYPE CREATE TABLE OF requires a stand-alone composite type that is not the row type of another table. Clarify that with a reference to CREATE TYPE in the docs. Also report a separate error message in this case. Reworded docs provided by David G. Johnston. --- doc/src/sgml/ref/create_table.sgml | 16 ++++++++-------- src/backend/commands/tablecmds.c | 9 ++++++++- src/test/regress/expected/typed_table.out | 7 ++++++- src/test/regress/sql/typed_table.sql | 4 ++++ 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index f19306e776..11458be9cf 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -249,18 +249,18 @@ WITH ( MODULUS numeric_literal, REM Creates a typed table, which takes its - structure from the specified composite type (name optionally - schema-qualified). A typed table is tied to its type; for - example the table will be dropped if the type is dropped - (with DROP TYPE ... CASCADE). + structure from an existing (name optionally schema-qualified) stand-alone + composite type (i.e., created using ) + though it still produces a new composite type as well. The table will + have a dependency on the referenced type such that cascaded alter and + drop actions on the type will propagate to the table. - When a typed table is created, then the data types of the - columns are determined by the underlying composite type and are - not specified by the CREATE TABLE command. + A typed table always has the same column names and data types as the + type it is derived from, and you cannot specify additional columns. But the CREATE TABLE command can add defaults - and constraints to the table and can specify storage parameters. + and constraints to the table, as well as specify storage parameters. diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 313c782cae..2331a9185a 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -6935,8 +6935,15 @@ check_of_type(HeapTuple typetuple) * the type before the typed table creation/conversion commits. */ relation_close(typeRelation, NoLock); + + if (!typeOk) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("type %s must not be a row type of another table", + format_type_be(typ->oid)), + errhint("Must be a stand-alone composite type created with CREATE TYPE."))); } - if (!typeOk) + else ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("type %s is not a composite type", diff --git a/src/test/regress/expected/typed_table.out b/src/test/regress/expected/typed_table.out index 2e47ecbcf5..5743e74978 100644 --- a/src/test/regress/expected/typed_table.out +++ b/src/test/regress/expected/typed_table.out @@ -89,8 +89,13 @@ drop cascades to function get_all_persons() drop cascades to table persons2 drop cascades to table persons3 CREATE TABLE persons5 OF stuff; -- only CREATE TYPE AS types may be used -ERROR: type stuff is not a composite type +ERROR: type stuff must not be a row type of another table +HINT: Must be a stand-alone composite type created with CREATE TYPE. DROP TABLE stuff; +CREATE TYPE simple AS ENUM ('a'); +CREATE TABLE of_simple OF simple; -- not a composite type +ERROR: type simple is not a composite type +DROP TYPE simple; -- implicit casting CREATE TYPE person_type AS (id int, name text); CREATE TABLE persons OF person_type; diff --git a/src/test/regress/sql/typed_table.sql b/src/test/regress/sql/typed_table.sql index 9ef0cdfcc7..d9b9398857 100644 --- a/src/test/regress/sql/typed_table.sql +++ b/src/test/regress/sql/typed_table.sql @@ -50,6 +50,10 @@ CREATE TABLE persons5 OF stuff; -- only CREATE TYPE AS types may be used DROP TABLE stuff; +CREATE TYPE simple AS ENUM ('a'); +CREATE TABLE of_simple OF simple; -- not a composite type +DROP TYPE simple; + -- implicit casting -- 2.45.1 --p7whpo2b3ruhdelr--