Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1l1yA7-0005Jf-05 for pgsql-hackers@arkaria.postgresql.org; Tue, 19 Jan 2021 21:03:39 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1l1yA5-0005Wm-Vr for pgsql-hackers@arkaria.postgresql.org; Tue, 19 Jan 2021 21:03:37 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1l1yA5-0005Wf-NX for pgsql-hackers@lists.postgresql.org; Tue, 19 Jan 2021 21:03:37 +0000 Received: from mail-io1-xd32.google.com ([2607:f8b0:4864:20::d32]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1l1yA3-0001QB-FG for pgsql-hackers@postgresql.org; Tue, 19 Jan 2021 21:03:37 +0000 Received: by mail-io1-xd32.google.com with SMTP id n2so25376869iom.7 for ; Tue, 19 Jan 2021 13:03:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=telsasoft-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=Sil+ciLxmQWZmm2VZ7jIbiLwwS5NgNkb9s0Ea4C6D+Y=; b=FtkwVB68sorjhOkpTS/tHC8p5NzLqYUA7Y5GKOLqv4Gkoago8ki8npY0nS97Grl/zB grgrr/bc7z+mEuvuv5VED2TtqHuX/2gfBtmLVjj1DuaOTBcor1NxdapVtzqAe0Hkpnbn VuCRE8Z5PM2b7InpbL7tOyy5hxjvYoKWED3LILGIJ8VuM2wj07f+HCeKJp5zwJs3L6mO Inl3A9svKslTx+psjwQP6VvGsHNmopqjXslYb57cCvW+MdwjiExwkDIJMwWFSGMJyaLQ iCFHHCZJr0ihk/dpoFb1ETBFVK2gGMXxezoCPYN/aKjuxA/CmkOPAePgrc/wQ3ZhYZ+c 62Ig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=Sil+ciLxmQWZmm2VZ7jIbiLwwS5NgNkb9s0Ea4C6D+Y=; b=g8+LQFrhzPezdt4OlQflPf0aIjAlrzbWrVy07Wi9ZbtpdL+97n4BazCWGmhSgIFomd ZmElSp0jhwTCI3SJvD8ggeRuK7J3v36sfV6gfxhyjQogrUTN1wvHZwcAqhT2TS7OoMeG DoEhSQU1+Le5uZdBWHGUs/rLOh1ce5YwM+LjkY/6Y2P81iu7LUlDuFwHYP88dWPWkMzS i8RvbwIU9Dyy/yDp9e9s/Isn/5vWNLCgHW2QYJCCV6ZHSU0MTRx5FtJfqPPzdmK7xspD cn29q/tFVeccA3Ki/WYqmyVDIrBeZwisM+IrmFnSD6X+BNvxCcH0AgZwGU8LytDolqr9 SU9A== X-Gm-Message-State: AOAM530NCzh3BKcCIUael6YDvGwSU926bmwwK0SolBHgv6/ZVUa0KkwL UzX41t3dnZHA8zsy8x5uyLVTmQ== X-Google-Smtp-Source: ABdhPJwEUiBIg6kxPqZ871awBv7lKdP8Z9AFCyr5r68b+wojMvsNu7aA5v4npXu6EMjOCQsDP0U4Sw== X-Received: by 2002:a05:6638:248:: with SMTP id w8mr5129561jaq.51.1611090213560; Tue, 19 Jan 2021 13:03:33 -0800 (PST) Received: from pryzbyj.telsasoft (charmander.telsasoft.com. [50.244.222.1]) by smtp.gmail.com with ESMTPSA id e10sm28156ili.75.2021.01.19.13.03.32 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Jan 2021 13:03:32 -0800 (PST) Received: by pryzbyj.telsasoft (Postfix, from userid 1000) id 80D54800C62; Tue, 19 Jan 2021 15:03:31 -0600 (CST) Date: Tue, 19 Jan 2021 15:03:31 -0600 From: Justin Pryzby To: Simon Riggs Cc: Michael Paquier , pgsql-hackers@postgresql.org, Jacob Champion , Heikki Linnakangas , Ashwin Agrawal , Ashutosh Sharma , Andres Freund , Robert Haas , Amit Kapila , Alvaro Herrera Subject: Re: create table like: ACCESS METHOD Message-ID: <20210119210331.GN8560@telsasoft.com> References: <20201209201328.GT24052@telsasoft.com> <20201229230805.GE25152@telsasoft.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="T6xhMxlHU34Bk0ad" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.9.4 (2018-02-28) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --T6xhMxlHU34Bk0ad Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, Dec 30, 2020 at 12:33:56PM +0000, Simon Riggs wrote: > There are no tests for the new functionality, please could you add some? Did you look at the most recent patch? +CREATE ACCESS METHOD heapdup TYPE TABLE HANDLER heap_tableam_handler; +CREATE TABLE likeam() USING heapdup; +CREATE TABLE likeamlike(LIKE likeam INCLUDING ALL); Also, I just realized that Dilip's toast compression patch adds "INCLUDING COMPRESSION", which is stored in pg_am. That's an implementation detail of that patch, but it's not intuitive that "including access method" wouldn't include the compression stored there. So I think this should use "INCLUDING TABLE ACCESS METHOD" not just ACCESS METHOD. -- Justin --T6xhMxlHU34Bk0ad Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v3-0001-create-table-like-.-including-ACCESS-METHOD.patch" From f27fd6291aa10af1ca0be4bc72a656811c8e0c9f Mon Sep 17 00:00:00 2001 From: Justin Pryzby Date: Sun, 15 Nov 2020 16:54:53 -0600 Subject: [PATCH v3] create table (like .. including ACCESS METHOD) --- doc/src/sgml/ref/create_table.sgml | 12 +++++++++++- src/backend/parser/gram.y | 1 + src/backend/parser/parse_utilcmd.c | 10 ++++++++++ src/include/nodes/parsenodes.h | 1 + src/test/regress/expected/create_table_like.out | 12 ++++++++++++ src/test/regress/sql/create_table_like.sql | 8 ++++++++ 6 files changed, 43 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index 569f4c9da7..e3c607f6b1 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -87,7 +87,7 @@ class="parameter">referential_action ] [ ON UPDATE and like_option is: -{ INCLUDING | EXCLUDING } { COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } +{ INCLUDING | EXCLUDING } { COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | TABLE ACCESS METHOD | ALL } and partition_bound_spec is: @@ -689,6 +689,16 @@ WITH ( MODULUS numeric_literal, REM + + INCLUDING TABLE ACCESS METHOD + + + The table's access method will be copied. By default, the + default_table_access_method is used. + + + + INCLUDING ALL diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 31c95443a5..719ac838e3 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -3708,6 +3708,7 @@ TableLikeOption: | INDEXES { $$ = CREATE_TABLE_LIKE_INDEXES; } | STATISTICS { $$ = CREATE_TABLE_LIKE_STATISTICS; } | STORAGE { $$ = CREATE_TABLE_LIKE_STORAGE; } + | TABLE ACCESS METHOD { $$ = CREATE_TABLE_LIKE_TABLE_ACCESS_METHOD; } | ALL { $$ = CREATE_TABLE_LIKE_ALL; } ; diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index b31f3afa03..f34f42aae3 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -96,6 +96,7 @@ typedef struct bool ispartitioned; /* true if table is partitioned */ PartitionBoundSpec *partbound; /* transformed FOR VALUES */ bool ofType; /* true if statement contains OF typename */ + char *accessMethod; /* table access method */ } CreateStmtContext; /* State shared by transformCreateSchemaStmt and its subroutines */ @@ -252,6 +253,7 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) cxt.ispartitioned = stmt->partspec != NULL; cxt.partbound = stmt->partbound; cxt.ofType = (stmt->ofTypename != NULL); + cxt.accessMethod = NULL; Assert(!stmt->ofTypename || !stmt->inhRelations); /* grammar enforces */ @@ -346,6 +348,9 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) stmt->tableElts = cxt.columns; stmt->constraints = cxt.ckconstraints; + if (cxt.accessMethod != NULL) + stmt->accessMethod = cxt.accessMethod; + result = lappend(cxt.blist, stmt); result = list_concat(result, cxt.alist); result = list_concat(result, save_alist); @@ -1118,6 +1123,11 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla cxt->likeclauses = lappend(cxt->likeclauses, table_like_clause); } + /* ACCESS METHOD doesn't apply and isn't copied for partitioned tables */ + if ((table_like_clause->options & CREATE_TABLE_LIKE_TABLE_ACCESS_METHOD) != 0 && + !cxt->ispartitioned) + cxt->accessMethod = get_am_name(relation->rd_rel->relam); + /* * We may copy extended statistics if requested, since the representation * of CreateStatsStmt doesn't depend on column numbers. diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index dc2bb40926..600856c229 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -685,6 +685,7 @@ typedef enum TableLikeOption CREATE_TABLE_LIKE_INDEXES = 1 << 5, CREATE_TABLE_LIKE_STATISTICS = 1 << 6, CREATE_TABLE_LIKE_STORAGE = 1 << 7, + CREATE_TABLE_LIKE_TABLE_ACCESS_METHOD = 1 << 8, CREATE_TABLE_LIKE_ALL = PG_INT32_MAX } TableLikeOption; diff --git a/src/test/regress/expected/create_table_like.out b/src/test/regress/expected/create_table_like.out index 10d17be23c..a09cd48ed0 100644 --- a/src/test/regress/expected/create_table_like.out +++ b/src/test/regress/expected/create_table_like.out @@ -429,6 +429,18 @@ SELECT s.stxname, objsubid, description FROM pg_description, pg_statistic_ext s ctlt_all_a_b_stat | 0 | ab stats (1 row) +CREATE ACCESS METHOD heapdup TYPE TABLE HANDLER heap_tableam_handler; +CREATE TABLE likeam() USING heapdup; +CREATE TABLE likeamlike(LIKE likeam INCLUDING ALL); +-- pg_regress helpfully hides the Access Method output, which we need: +SELECT a.amname FROM pg_class c JOIN pg_am a ON c.relam=a.oid WHERE c.oid='likeamlike'::regclass; + amname +--------- + heapdup +(1 row) + +DROP TABLE likeam, likeamlike; +DROP ACCESS METHOD heapdup; CREATE TABLE inh_error1 () INHERITS (ctlt1, ctlt4); NOTICE: merging multiple inherited definitions of column "a" ERROR: inherited column "a" has a storage parameter conflict diff --git a/src/test/regress/sql/create_table_like.sql b/src/test/regress/sql/create_table_like.sql index 06b76f949d..ee6c464851 100644 --- a/src/test/regress/sql/create_table_like.sql +++ b/src/test/regress/sql/create_table_like.sql @@ -165,6 +165,14 @@ CREATE TABLE ctlt_all (LIKE ctlt1 INCLUDING ALL); SELECT c.relname, objsubid, description FROM pg_description, pg_index i, pg_class c WHERE classoid = 'pg_class'::regclass AND objoid = i.indexrelid AND c.oid = i.indexrelid AND i.indrelid = 'ctlt_all'::regclass ORDER BY c.relname, objsubid; SELECT s.stxname, objsubid, description FROM pg_description, pg_statistic_ext s WHERE classoid = 'pg_statistic_ext'::regclass AND objoid = s.oid AND s.stxrelid = 'ctlt_all'::regclass ORDER BY s.stxname, objsubid; +CREATE ACCESS METHOD heapdup TYPE TABLE HANDLER heap_tableam_handler; +CREATE TABLE likeam() USING heapdup; +CREATE TABLE likeamlike(LIKE likeam INCLUDING ALL); +-- pg_regress helpfully hides the Access Method output, which we need: +SELECT a.amname FROM pg_class c JOIN pg_am a ON c.relam=a.oid WHERE c.oid='likeamlike'::regclass; +DROP TABLE likeam, likeamlike; +DROP ACCESS METHOD heapdup; + CREATE TABLE inh_error1 () INHERITS (ctlt1, ctlt4); CREATE TABLE inh_error2 (LIKE ctlt4 INCLUDING STORAGE) INHERITS (ctlt1); -- 2.17.0 --T6xhMxlHU34Bk0ad--