Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.92) (envelope-from ) id 1j8wU6-0002dM-DO for pgsql-hackers@arkaria.postgresql.org; Tue, 03 Mar 2020 01:36:34 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1j8wU4-0004CH-Vs for pgsql-hackers@arkaria.postgresql.org; Tue, 03 Mar 2020 01:36:32 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1j8wU4-0004CA-MX for pgsql-hackers@lists.postgresql.org; Tue, 03 Mar 2020 01:36:32 +0000 Received: from mail-yw1-xc35.google.com ([2607:f8b0:4864:20::c35]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1j8wU2-0004Nd-0l for pgsql-hackers@postgresql.org; Tue, 03 Mar 2020 01:36:32 +0000 Received: by mail-yw1-xc35.google.com with SMTP id t192so1880441ywe.7 for ; Mon, 02 Mar 2020 17:36:29 -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=DrQX1oCxp0s+a46Xt2BfzXTbB6nw2Dn28LOaZVLJ5s8=; b=HIClfT1BBY73qJhet6aEh/ydedb5x/U9rpY9Az/iAdeM5FmJAXkfoW27/ztvdKvNxZ YoFki6e35z582iO76UVwqVgx2TDPUWv1cSoAzAbs2BAWameRsutYXn8rQBLTcamZRQhE QnWTk/L55UK4BTFaBvOBTuFilzddGSHMIVa57OioAcH+PasC1sjaNxOuw/DRqX+cMPWy owEJoNUwaSZtI7P+mN4jUosuNt6Rlu01hfEdCGz6e/UD5YEY1bX/MQErIxLzH8b/W9MV 5USV91BftsUFWhgARiJzvt8g+27qCZ2Y3NaNnCue/LbZXrEyn1HP7DlFUbv5BamNnl0t I32g== 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=DrQX1oCxp0s+a46Xt2BfzXTbB6nw2Dn28LOaZVLJ5s8=; b=L3s/gSLXIu/vzh0w7/jO7WpDEC/hHRYzUl7Djw8ZcASGuZTE10YYD5bYwO9SMbuMHS LeJR25+sLX2SO4tZbCBnajINQWgTOG9KYteR13TC/4erv4Tg04u4L2qZ1e2ncljEbi18 dIekVrjXEOcTiW/4oNcrHKzncBys+1FcxzPwm4NJY9to03wK4YiJy6PbyUyGl8jWHnXg hZg5kGI97DwU3dyOfVt8EfX2AvtDM1SYH71h7aFAc1/zLz4nzxIPjQx1kgRN+/KagWI1 7+5oRqaYZv3Tu8XZDv0X5IAEyyn2q5jKGoWEsxep/hd0SqJIWkS+8WfMcNlACPlrvh9F i2gQ== X-Gm-Message-State: ANhLgQ1k7/90paCDh55ZaEwSg8KhsTgh4TLfPLLybnupvU17IwSnhZAQ SJ0eDjdfa7W5ROc7EnxWd5dExQ== X-Google-Smtp-Source: ADFU+vs8z2yM8flYL5udxxSnaW2rNhGXdOm3XKU/cqf9qqx2zFBaWEKBzSosxWqVtc5/1IMyJ27d2A== X-Received: by 2002:a81:9a16:: with SMTP id r22mr2320706ywg.326.1583199388105; Mon, 02 Mar 2020 17:36:28 -0800 (PST) Received: from pryzbyj (charmander.telsasoft.com. [50.244.222.1]) by smtp.gmail.com with ESMTPSA id l27sm18676ywa.48.2020.03.02.17.36.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 02 Mar 2020 17:36:27 -0800 (PST) Received: by pryzbyj (Postfix, from userid 1000) id DCB39800925; Mon, 2 Mar 2020 19:36:25 -0600 (CST) Date: Mon, 2 Mar 2020 19:36:25 -0600 From: Justin Pryzby To: Michael Paquier Cc: Tom Lane , Alvaro Herrera , Amit Langote , pgsql-hackers@postgresql.org Subject: Re: ALTER tbl rewrite loses CLUSTER ON index Message-ID: <20200303013625.GA21225@telsasoft.com> References: <20200206144426.GH403@telsasoft.com> <20200206172447.GA28041@alvherre.pgsql> <20200207143935.GP403@telsasoft.com> <17937.1582932364@sss.pgh.pa.us> <20200229024202.GH29456@telsasoft.com> <20200229165258.GJ29456@telsasoft.com> <20200302032818.GB32059@paquier.xyz> <20200303013132.GA684@telsasoft.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="bg08WKrSYDhXBjb5" Content-Disposition: inline In-Reply-To: <20200303013132.GA684@telsasoft.com> User-Agent: Mutt/1.5.24 (2015-08-30) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --bg08WKrSYDhXBjb5 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline @cfbot: resending with only Amit's 0001, since Michael pushed a variation on 0002. -- Justin --bg08WKrSYDhXBjb5 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v5-0001-ALTER-tbl-rewrite-loses-CLUSTER-ON-index.patch" From 865fc2713ad29d0f8c0f63609a7c15c83cfa5cfe Mon Sep 17 00:00:00 2001 From: Amit Langote Date: Thu, 6 Feb 2020 18:14:16 +0900 Subject: [PATCH v5] ALTER tbl rewrite loses CLUSTER ON index --- src/backend/commands/tablecmds.c | 39 +++++++++++++++++++++++ src/test/regress/expected/alter_table.out | 34 ++++++++++++++++++++ src/test/regress/sql/alter_table.sql | 16 +++++++++- 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 02a7c04fdb..6b2469bd09 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -490,6 +490,7 @@ static void ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, static void RebuildConstraintComment(AlteredTableInfo *tab, int pass, Oid objid, Relation rel, List *domname, const char *conname); +static void PreserveClusterOn(AlteredTableInfo *tab, int pass, Oid indoid); static void TryReuseIndex(Oid oldId, IndexStmt *stmt); static void TryReuseForeignKey(Oid oldId, Constraint *con); static ObjectAddress ATExecAlterColumnGenericOptions(Relation rel, const char *colName, @@ -11838,6 +11839,9 @@ ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, newcmd->def = (Node *) stmt; tab->subcmds[AT_PASS_OLD_INDEX] = lappend(tab->subcmds[AT_PASS_OLD_INDEX], newcmd); + + /* Preserve index's indisclustered property, if set. */ + PreserveClusterOn(tab, AT_PASS_OLD_INDEX, oldId); } else if (IsA(stm, AlterTableStmt)) { @@ -11874,6 +11878,9 @@ ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, rel, NIL, indstmt->idxname); + + /* Preserve index's indisclustered property, if set. */ + PreserveClusterOn(tab, AT_PASS_OLD_INDEX, indoid); } else if (cmd->subtype == AT_AddConstraint) { @@ -11996,6 +12003,38 @@ RebuildConstraintComment(AlteredTableInfo *tab, int pass, Oid objid, tab->subcmds[pass] = lappend(tab->subcmds[pass], newcmd); } +/* + * For a table's index that is to be recreated due to PostAlterType + * processing, preserve its indisclustered property by issuing ALTER TABLE + * CLUSTER ON command on the table that will run after the command to recreate + * the index. + */ +static void +PreserveClusterOn(AlteredTableInfo *tab, int pass, Oid indoid) +{ + HeapTuple indexTuple; + Form_pg_index indexForm; + + Assert(OidIsValid(indoid)); + Assert(pass == AT_PASS_OLD_INDEX); + + indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indoid)); + if (!HeapTupleIsValid(indexTuple)) + elog(ERROR, "cache lookup failed for index %u", indoid); + indexForm = (Form_pg_index) GETSTRUCT(indexTuple); + + if (indexForm->indisclustered) + { + AlterTableCmd *newcmd = makeNode(AlterTableCmd); + + newcmd->subtype = AT_ClusterOn; + newcmd->name = get_rel_name(indoid); + tab->subcmds[pass] = lappend(tab->subcmds[pass], newcmd); + } + + ReleaseSysCache(indexTuple); +} + /* * Subroutine for ATPostAlterTypeParse(). Calls out to CheckIndexCompatible() * for the real analysis, then mutates the IndexStmt based on that verdict. diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index fb6d86a269..a01c6d6ec5 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -4296,3 +4296,37 @@ create trigger xtrig update bar1 set a = a + 1; INFO: a=1, b=1 /* End test case for bug #16242 */ +-- alter type rewrite/rebuild should preserve cluster marking on index +create table alttype_cluster (a int); +create index alttype_cluster_a on alttype_cluster (a); +alter table alttype_cluster cluster on alttype_cluster_a; +select indisclustered from pg_index where indrelid = 'alttype_cluster'::regclass; + indisclustered +---------------- + t +(1 row) + +alter table alttype_cluster alter a type bigint; +select indisclustered from pg_index where indrelid = 'alttype_cluster'::regclass; + indisclustered +---------------- + t +(1 row) + +drop index alttype_cluster_a; +alter table alttype_cluster add primary key (a); +alter table alttype_cluster cluster on alttype_cluster_pkey; +select indisclustered from pg_index where indrelid = 'alttype_cluster'::regclass; + indisclustered +---------------- + t +(1 row) + +alter table alttype_cluster alter a type int; +select indisclustered from pg_index where indrelid = 'alttype_cluster'::regclass; + indisclustered +---------------- + t +(1 row) + +drop table alttype_cluster; diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index 3801f19c58..6e9048bbec 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -2802,7 +2802,6 @@ drop table at_test_sql_partop; drop operator class at_test_sql_partop using btree; drop function at_test_sql_partop; - /* Test case for bug #16242 */ -- We create a parent and child where the child has missing @@ -2840,3 +2839,18 @@ create trigger xtrig update bar1 set a = a + 1; /* End test case for bug #16242 */ + +-- alter type rewrite/rebuild should preserve cluster marking on index +create table alttype_cluster (a int); +create index alttype_cluster_a on alttype_cluster (a); +alter table alttype_cluster cluster on alttype_cluster_a; +select indisclustered from pg_index where indrelid = 'alttype_cluster'::regclass; +alter table alttype_cluster alter a type bigint; +select indisclustered from pg_index where indrelid = 'alttype_cluster'::regclass; +drop index alttype_cluster_a; +alter table alttype_cluster add primary key (a); +alter table alttype_cluster cluster on alttype_cluster_pkey; +select indisclustered from pg_index where indrelid = 'alttype_cluster'::regclass; +alter table alttype_cluster alter a type int; +select indisclustered from pg_index where indrelid = 'alttype_cluster'::regclass; +drop table alttype_cluster; -- 2.17.0 --bg08WKrSYDhXBjb5--