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 1lo9mv-0008IL-37 for pgsql-hackers@arkaria.postgresql.org; Tue, 01 Jun 2021 19:10:53 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1lo9mu-0004AD-1B for pgsql-hackers@arkaria.postgresql.org; Tue, 01 Jun 2021 19:10:52 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lo9mt-0004A5-Hz for pgsql-hackers@lists.postgresql.org; Tue, 01 Jun 2021 19:10:51 +0000 Received: from mail-il1-x132.google.com ([2607:f8b0:4864:20::132]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1lo9mq-0000hR-Ca for pgsql-hackers@postgresql.org; Tue, 01 Jun 2021 19:10:50 +0000 Received: by mail-il1-x132.google.com with SMTP id h11so13977797ili.9 for ; Tue, 01 Jun 2021 12:10:48 -0700 (PDT) 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=jphjU/yuqjCcLLIg4+o/3XWEERNfRWB9rflz2HD6GZ0=; b=HF7iq7HpA29dYvRPbL3G/cH9nhBoHU0iNoKdmy88T2l5QWAdWoEbf8eQyMEV9o6E36 PO0Bk3fj9F4BB3Ps6mIpxiwKsy/nWL/48xEY2YtiUdYVrpB/3sf5gJElDmFeT8eqQq/1 AvfBBd9S4SmHaovSmYCni2BCEV7PbBkXsHiaqXn8gOgsqdW3yuE2qwdytIaSs2kBgBDr ZizeELS/6jFRjKdI64nS5dbCiemiRD1C4kDQT1dAQ+6u+RKHUNjlZ7DXFKUa8AgkJxbD wR2ERwaGdVfktkfNgmBwmWfnnnl6O45j3kx4ynKTy3PoN2RI2GfToNvvUEVPwj1EFHX+ PCcg== 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=jphjU/yuqjCcLLIg4+o/3XWEERNfRWB9rflz2HD6GZ0=; b=miBi7ZBR086Lv+uF+KpUxqi8kjeESJh03LIR+NErPChZEaOdIJglH7ikBNg9m2XFk8 rXv21pgb787M45it4W2u7mdUj+SD26vbAqZcmiuziRAPRtqHrTecoVDsB6L6a6i7ptGQ Rfujv20AofD0u37nbEXpyzgRshqZHYO4w/zlpcrC70mtpHjZYnxtOPI0bi0ylKblDCML du97KJkWf53+nZN1Uq21ff5OgU2Kj/rIxnO1xKcLnSAVdsHIuUPlEObCjN3/ek8wrULS xpdsZOCNSbyKSZBuR+v7wqsGcJlOLIWPIWVpO14wI1sZ5ekHCrvaXZ/5Q+5B2ALcjBBT YX/w== X-Gm-Message-State: AOAM532OHLV+Ix3qABdaPjWUIiW46K8zIJqtJomeGJ8GlhQTPVsgR3Sc Y4HAzRjrR2KY1bBvGioiWPtHVg== X-Google-Smtp-Source: ABdhPJybxRse+nCc3FLF9HIf9v7RjVLCu679unRSKSoqHei5BeRaHiZDWAv9mawqMEL0KBq+5CSwvA== X-Received: by 2002:a92:d907:: with SMTP id s7mr2723150iln.30.1622574647563; Tue, 01 Jun 2021 12:10:47 -0700 (PDT) Received: from pryzbyj.telsasoft (charmander.telsasoft.com. [50.244.222.1]) by smtp.gmail.com with ESMTPSA id a11sm5349669ilk.3.2021.06.01.12.10.46 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Tue, 01 Jun 2021 12:10:46 -0700 (PDT) Received: by pryzbyj.telsasoft (Postfix, from userid 1000) id 8D7C88009D6; Tue, 1 Jun 2021 14:10:45 -0500 (CDT) Date: Tue, 1 Jun 2021 14:10:45 -0500 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: <20210601191045.GC2082@telsasoft.com> References: <20201209201328.GT24052@telsasoft.com> <20201229230805.GE25152@telsasoft.com> <20210119210331.GN8560@telsasoft.com> <20210323003926.GV4203@telsasoft.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="azLHFNyN32YCQGCU" Content-Disposition: inline In-Reply-To: <20210323003926.GV4203@telsasoft.com> User-Agent: Mutt/1.9.4 (2018-02-28) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --azLHFNyN32YCQGCU Content-Type: text/plain; charset=us-ascii Content-Disposition: inline rebased and alphabetized --azLHFNyN32YCQGCU Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v5-0001-create-table-like-.-including-ACCESS-METHOD.patch" From c1420e17cc2036d4bf3a6c1f9366bf1cd03bd831 Mon Sep 17 00:00:00 2001 From: Justin Pryzby Date: Sun, 15 Nov 2020 16:54:53 -0600 Subject: [PATCH v5] create table (like .. including ACCESS METHOD) --- doc/src/sgml/ref/create_table.sgml | 22 ++++++++++++++++++- src/backend/parser/gram.y | 3 ++- src/backend/parser/parse_utilcmd.c | 10 +++++++++ src/include/nodes/parsenodes.h | 19 ++++++++-------- .../regress/expected/create_table_like.out | 12 ++++++++++ src/test/regress/sql/create_table_like.sql | 8 +++++++ 6 files changed, 63 insertions(+), 11 deletions(-) diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index c6d0a35e50..ab84ca8718 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 | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } +{ INCLUDING | EXCLUDING } { ACCESS METHOD | COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } and partition_bound_spec is: @@ -618,6 +618,16 @@ WITH ( MODULUS numeric_literal, REM available options are: + + INCLUDING ACCESS METHOD + + + The table's access method will be copied. By default, the + default_table_access_method is used. + + + + INCLUDING COMMENTS @@ -725,6 +735,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 9ee90e3f13..c8991cead9 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -3754,7 +3754,8 @@ TableLikeOptionList: ; TableLikeOption: - COMMENTS { $$ = CREATE_TABLE_LIKE_COMMENTS; } + ACCESS METHOD { $$ = CREATE_TABLE_LIKE_ACCESS_METHOD; } + | COMMENTS { $$ = CREATE_TABLE_LIKE_COMMENTS; } | COMPRESSION { $$ = CREATE_TABLE_LIKE_COMPRESSION; } | CONSTRAINTS { $$ = CREATE_TABLE_LIKE_CONSTRAINTS; } | DEFAULTS { $$ = CREATE_TABLE_LIKE_DEFAULTS; } diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index d5b67d48cf..0cdea516ac 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -97,6 +97,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 */ @@ -349,6 +351,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); @@ -1139,6 +1144,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_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 ef73342019..726f15f78a 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -689,15 +689,16 @@ typedef struct TableLikeClause typedef enum TableLikeOption { - CREATE_TABLE_LIKE_COMMENTS = 1 << 0, - CREATE_TABLE_LIKE_COMPRESSION = 1 << 1, - CREATE_TABLE_LIKE_CONSTRAINTS = 1 << 2, - CREATE_TABLE_LIKE_DEFAULTS = 1 << 3, - CREATE_TABLE_LIKE_GENERATED = 1 << 4, - CREATE_TABLE_LIKE_IDENTITY = 1 << 5, - CREATE_TABLE_LIKE_INDEXES = 1 << 6, - CREATE_TABLE_LIKE_STATISTICS = 1 << 7, - CREATE_TABLE_LIKE_STORAGE = 1 << 8, + CREATE_TABLE_LIKE_ACCESS_METHOD = 1 << 0, + CREATE_TABLE_LIKE_COMMENTS = 1 << 1, + CREATE_TABLE_LIKE_COMPRESSION = 1 << 2, + CREATE_TABLE_LIKE_CONSTRAINTS = 1 << 3, + CREATE_TABLE_LIKE_DEFAULTS = 1 << 4, + CREATE_TABLE_LIKE_GENERATED = 1 << 5, + CREATE_TABLE_LIKE_IDENTITY = 1 << 6, + CREATE_TABLE_LIKE_INDEXES = 1 << 7, + CREATE_TABLE_LIKE_STATISTICS = 1 << 8, + CREATE_TABLE_LIKE_STORAGE = 1 << 9, 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 4dc5e6aa5f..68411e3a84 100644 --- a/src/test/regress/expected/create_table_like.out +++ b/src/test/regress/expected/create_table_like.out @@ -433,6 +433,18 @@ SELECT s.stxname, objsubid, description FROM pg_description, pg_statistic_ext s ctlt_all_expr_stat | 0 | ab expr stats (2 rows) +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 4929d373a2..1845b9adb5 100644 --- a/src/test/regress/sql/create_table_like.sql +++ b/src/test/regress/sql/create_table_like.sql @@ -167,6 +167,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 --azLHFNyN32YCQGCU--