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.96) (envelope-from ) id 1wCUEN-002217-1G for pgsql-hackers@arkaria.postgresql.org; Tue, 14 Apr 2026 03:14:28 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wCUEL-009XRC-1r for pgsql-hackers@arkaria.postgresql.org; Tue, 14 Apr 2026 03:14:26 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wCUEL-009XR3-0h for pgsql-hackers@lists.postgresql.org; Tue, 14 Apr 2026 03:14:26 +0000 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wCUEJ-00000000xG4-38FT for pgsql-hackers@lists.postgresql.org; Tue, 14 Apr 2026 03:14:25 +0000 Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-2ab46931cf1so30846575ad.0 for ; Mon, 13 Apr 2026 20:14:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776136460; x=1776741260; darn=lists.postgresql.org; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:from:to:cc:subject:date:message-id:reply-to; bh=8x2O+jNcDqj63u4PGBT3SgWZfakzvYefdGfDvTjC8n0=; b=dVpIjVLvhuDPna4RnSx6eOJjTm4zqUYsukAEqsjw+nqparsnhSuM+pv3AgmBhh9bcd 9DHqjDh7hBchMhTSFq2C7mDYBuQ29lqqNdvbgUk9qKrAWLLVPJ+nP92Trc/l+JEAgkYN eaTw/P4/EexTObLxpfwbZitZjyTOZWjt9glYolP1QG/XoffnjtYldpWt0t5ecfUbEeF3 nUz9blhFLFxwSJkzKMkv/wXE+Fd8ZjWOa8lgvC904/DozqOA36QoR+12+UBuivlLJVCC bTy+RluzGmaM+dgnupaFpWEDFpl8+4/Hx6EmCAaDusMDgkpyPixdz3G4HEukVAWJixbL SqOg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776136460; x=1776741260; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=8x2O+jNcDqj63u4PGBT3SgWZfakzvYefdGfDvTjC8n0=; b=FYK91UZguszwu/VRxdxOZBm6i85SvZ4PCNh2pRLmN9EpJ6eA5+NBBLvifVBpfwNCbR +kw248PEkzsDRYdWjXxY+nMrHTO0A81O1irX35GGqZZpnXOSCG8UzHozes3v5WzGs3YS aHpeMaEHW26N5Dl9rsYmum/M6uQ9QD78rrkpEYSiY5LsLIKXesgxiHpFUZ43l1SSzjmN DxdMn1QeDh3xUM59Sqaw2ZXfexzri6YcHYnon+WANdBgryAq18Nrml77XtJ6/PSNG4Df ewgoHEgZ3WUcne2W1cE8cBkVCuUcvS1V4qOdkcKMTBO9Y0+xGXyXIerXVIftihzRncjI 1QeA== X-Gm-Message-State: AOJu0YxUyTx7oLgWPcLonLYca/7yM3OtVhAjp9FJsKYblWAyTXcugTG2 c6o8OPtVOoO8Tpkpo1IwXxEpYVOpwfYmYi3N5Ri1d/W1A3XCap8kyhkO X-Gm-Gg: AeBDiev++CVUbvlbPznfwvCm0Bc+UZXN5jiFnfYmYkAbGyrfFWokYwQfuxmo7VML/pG tLEDHXkwQ11eMxeEEqSQAtIi4pB2pW2d8Re+Ukfw2hLoNsXpBagKS896jy3PNdfkXvdrV+1abm3 BOV/xS8VI1qOdAbGCAh04jPlXRrSWXuocT8gVmcSK1FB1o9651GbVZsCMdpVD961qXF77T30nam cTq3hqhVWkEIqZWT9h2kUt40sfpSouDXvgsHxNqdXtjlbsENDIq/izXPaK+vrT+pSxjjzoTu5NL JOlaXfsF0/QQDFXFdXD9WJW7E1oiAXf12LbaKMDmtKkO9FhYKH8s8xjg7wuwM/5SOxjz4tyd9sA KYo/Av3fKGfRwsC5RDfzf9BZrMT12U62cYZwtfqRt8IRdmkF1rPLYJV2IQHxUI1j6297K/baq5k 0Ev7wez/zNWL7lLzBSXh45Hm0/j8pEcH4= X-Received: by 2002:a17:903:1663:b0:2b4:6320:8d0a with SMTP id d9443c01a7336-2b46320947fmr39550825ad.0.1776136459815; Mon, 13 Apr 2026 20:14:19 -0700 (PDT) Received: from smtpclient.apple ([45.32.121.103]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2b45c217ba6sm54636285ad.36.2026.04.13.20.14.17 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Apr 2026 20:14:19 -0700 (PDT) From: Chao Li Message-Id: <08B10151-B5F3-4734-A0FD-60FA68F36678@gmail.com> Content-Type: multipart/mixed; boundary="Apple-Mail=_19C03C97-5D2B-4064-9D8A-02D2E976D35B" Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3864.400.21\)) Subject: Re: tablecmds: fix bug where index rebuild loses replica identity on partitions Date: Tue, 14 Apr 2026 11:13:40 +0800 In-Reply-To: Cc: Postgres hackers To: Xuneng Zhou References: <0B38B9DC-A53C-437C-B9BD-807F30A032BA@gmail.com> <424A3799-D7FD-4691-BD10-6CBDACB14938@gmail.com> <43825F3D-6156-4030-B5E1-9A0841969022@gmail.com> <260E4616-43B7-4C24-BF53-352DC8DEB7AA@gmail.com> <8F791DCB-0307-4A8C-B5AF-1EF0CF678AC2@gmail.com> X-Mailer: Apple Mail (2.3864.400.21) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --Apple-Mail=_19C03C97-5D2B-4064-9D8A-02D2E976D35B Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On Apr 6, 2026, at 14:04, Xuneng Zhou wrote: >=20 > On Tue, Mar 24, 2026 at 3:26=E2=80=AFPM Chao Li = wrote: >>=20 >>=20 >>=20 >>> On Mar 23, 2026, at 16:41, Xuneng Zhou wrote: >>>=20 >>> Hi, >>>=20 >>> On Mon, Mar 23, 2026 at 3:57=E2=80=AFPM Chao Li = wrote: >>>>=20 >>>>=20 >>>>=20 >>>>> On Mar 21, 2026, at 18:29, Xuneng Zhou = wrote: >>>>>=20 >>>>> On Thu, Mar 19, 2026 at 1:07=E2=80=AFPM Chao Li = wrote: >>>>>>=20 >>>>>>=20 >>>>>>=20 >>>>>>> On Feb 26, 2026, at 14:59, Chao Li = wrote: >>>>>>>=20 >>>>>>>=20 >>>>>>>=20 >>>>>>>> On Jan 28, 2026, at 10:49, Chao Li = wrote: >>>>>>>>=20 >>>>>>>>=20 >>>>>>>>=20 >>>>>>>>> On Jan 27, 2026, at 16:30, Chao Li = wrote: >>>>>>>>>=20 >>>>>>>>>=20 >>>>>>>>>=20 >>>>>>>>>> On Jan 27, 2026, at 15:59, Chao Li = wrote: >>>>>>>>>>=20 >>>>>>>>>>=20 >>>>>>>>>>=20 >>>>>>>>>>> On Jan 27, 2026, at 15:39, Michael Paquier = wrote: >>>>>>>>>>>=20 >>>>>>>>>>> On Tue, Jan 27, 2026 at 01:13:32PM +0800, Chao Li wrote: >>>>>>>>>>>> I found this bug while working on a related patch [1]. >>>>>>>>>>>>=20 >>>>>>>>>>>> When ALTER TABLE ... ALTER COLUMN TYPE causes an index = rebuild, and >>>>>>>>>>>> that index is used as REPLICA IDENTITY on a partitioned = table, the >>>>>>>>>>>> replica identity marking on partitions can be silently lost = after the >>>>>>>>>>>> rebuild. >>>>>>>>>>>=20 >>>>>>>>>>> I am slightly confused by the tests included in the proposed = patch. >>>>>>>>>>> On HEAD, if I undo the proposed changes of tablecmds.c, the = tests >>>>>>>>>>> pass. If I run the tests of the patch with the changes of >>>>>>>>>>> tablecmds.c, the tests also pass. >>>>>>>>>>=20 >>>>>>>>>> Oops, that isn=E2=80=99t supposed to be so. I=E2=80=99ll = check the test. >>>>>>>>>>=20 >>>>>>>>>=20 >>>>>>>>> Okay, I see the problem is here: >>>>>>>>> ``` >>>>>>>>> +CREATE UNIQUE INDEX test_replica_identity_partitioned_pkey ON = test_replica_identity_partitioned (id); >>>>>>>>> ``` >>>>>>>>>=20 >>>>>>>>> I missed to add column =E2=80=9Cval=E2=80=9D into the index, = so that alter type of val didn=E2=80=99t cause index rebuild. >>>>>>>>>=20 >>>>>>>>> Ideally, it=E2=80=99s better to also verify that index OIDs = should have changed before and after alter column type, but I haven=E2=80=99= t figured out how to do so. Do you have an idea? >>>>>>>>=20 >>>>>>>> I just updated the test to store index OIDs before and after = rebuild into 2 temp tables, so that we can compare the OIDs to verify = rebuild happens and replica identity preserved. >>>>>>>>=20 >>>>>>>> I tried to port the test to master branch, and the test failed. = =46rom the test diff file, we can see replica identity lost on 3 leaf = partitions: >>>>>>>> ``` >>>>>>>> @@ -360,9 +360,9 @@ >>>>>>>> ORDER BY b.index_name; >>>>>>>> index_name | rebuilt | = ri_lost >>>>>>>> = ---------------------------------------------------+---------+--------- >>>>>>>> - test_replica_identity_partitioned_p1_id_val_idx | t | = f >>>>>>>> - test_replica_identity_partitioned_p2_1_id_val_idx | t | = f >>>>>>>> - test_replica_identity_partitioned_p2_2_id_val_idx | t | = f >>>>>>>> + test_replica_identity_partitioned_p1_id_val_idx | t | = t >>>>>>>> + test_replica_identity_partitioned_p2_1_id_val_idx | t | = t >>>>>>>> + test_replica_identity_partitioned_p2_2_id_val_idx | t | = t >>>>>>>> test_replica_identity_partitioned_p2_id_val_idx | t | f >>>>>>>> test_replica_identity_partitioned_pkey | t | f >>>>>>>> (5 rows) >>>>>>>> ``` >>>>>>>>=20 >>>>>>>> With this patch, the test passes and all replica identity are = preserved. >>>>>>>>=20 >>>>>>>> PFA v3: >>>>>>>> * Enhanced the test. >>>>>>>> * A small change in find_partition_replica_identity_indexes(): = if we will not update a partition, then unlock it. >>>>>>>>=20 >>>>>>>> Best regards, >>>>>>>> -- >>>>>>>> Chao Li (Evan) >>>>>>>> HighGo Software Co., Ltd. >>>>>>>> https://www.highgo.com/ >>>>>>>>=20 >>>>>>>>=20 >>>>>>>>=20 >>>>>>>>=20 >>>>>>>> = >>>>>>>=20 >>>>>>> The CF asked for a rebase, thus rebased as v4. >>>>>>>=20 >>>>>=20 >>>>>=20 >>>>> Hi, I reproduced this with the test case, and the patch appears >>>>> to resolve it. >>>>>=20 >>>>> Some comments on v5: >>>>=20 >>>> Thanks a lot for your review. >>>>=20 >>>>>=20 >>>>> -- Whether it makes sense to use a single list of pair structs = instead >>>>> of two parallel OID lists (replicaIdentityIndexOids + >>>>> replicaIdentityTableOids) to avoid accidental desync. >>>>=20 >>>> I don=E2=80=99t think that helps much. The current code of = rebuilding index uses two lists changedIndexOids and changedIndexDefs. = So, this patch matches the pattern of the existing code. >>>>=20 >>>>>=20 >>>>> -- It would be better to make lock handling in >>>>> find_partition_replica_identity_indexes() consistent >>>>> (relation_open(..., NoLock) if child is already locked, and avoid >>>>> mixed relation_close(..., lockmode)/NoLock behavior). >>>>=20 >>>> That=E2=80=99s because if we are going to update a partition, then = we need to hold the lock on the partition. >>>=20 >>> There is one locking cleanup in = find_partition_replica_identity_indexes(). >>>=20 >>> find_inheritance_children(relId, lockmode) already acquires = lockmode on >>> every partition it returns, so I think the later relation_open() = should use >>> NoLock, not lockmode. For the same reason, all relation_close() = calls in >>> this function should use NoLock as well. >>>=20 >>> Today the code does: >>>=20 >>> partRel =3Drelation_open(partRelOid, lockmode); >>> ... >>> relation_close(partRel, lockmode); >>>=20 >>> That does not cause a correctness issue, because the lock manager >>> reference-counts same-transaction acquisitions, so the lock remains = held >>> either way. But it is misleading: it suggests that relation_open() = is where >>> the partition lock is taken, and that the early relation_close(..., = lockmode) >>> is intentionally releasing it. Neither is actually true here, = because the lock >>> was already acquired by find_inheritance_children(). >>>=20 >>> So I think this should be adjusted to: >>>=20 >>> partRel =3D relation_open(partRelOid, NoLock); >>>=20 >>> and all close sites in this function should be: >>>=20 >>> relation_close(partRel, NoLock); >>>=20 >>> The comment on the early-close path should also be updated, since = it is not >>> really unlocking the partition. Something like "No matching = partition index; >>> just close the relcache entry" would match the actual behavior = better. >>>=20 >>=20 >> Okay, in find_partition_replica_identity_indexes, we can use NOLOCK = to open partitions as they have been locked by = find_inheritance_children. But for those partitions that we won=E2=80=99t = touch, we still want to unlock them. >>=20 >> PFA v7. >>=20 >=20 > v7 LGTM. >=20 > --=20 > Best, > Xuneng Rebased as v8. Nothing changed. Per [1], to participate Peter E.=E2=80=99s =E2=80=9Cin-person = commitfest=E2=80=9D session, I am adding tag =E2=80=9CPGConf.dev=E2=80=9D = to the CF entry: https://commitfest.postgresql.org/patch/6440/=20 [1] = https://postgr.es/m/9dd5b2f4-fba6-416b-b732-45f284d4097b@eisentraut.org Best regards, -- Chao Li (Evan) HighGo Software Co., Ltd. https://www.highgo.com/ --Apple-Mail=_19C03C97-5D2B-4064-9D8A-02D2E976D35B Content-Disposition: attachment; filename=v8-0001-tablecmds-fix-bug-where-index-rebuild-loses-repli.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="v8-0001-tablecmds-fix-bug-where-index-rebuild-loses-repli.patch" Content-Transfer-Encoding: quoted-printable =46rom=206819d67b0905e5c56337ece8ae38ea0477f16951=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20"Chao=20Li=20(Evan)"=20=0A= Date:=20Tue,=2027=20Jan=202026=2012:41:05=20+0800=0ASubject:=20[PATCH=20= v8]=20tablecmds:=20fix=20bug=20where=20index=20rebuild=20loses=20replica=0A= =20identity=20on=20partitions=0A=0AALTER=20TABLE=20...=20ALTER=20COLUMN=20= TYPE=20may=20require=20rebuilding=20dependent=0Aindexes.=20=20When=20the=20= rebuilt=20index=20is=20marked=20as=20REPLICA=20IDENTITY=20on=20a=0A= partitioned=20table,=20tablecmds=20previously=20failed=20to=20restore=20= replica=0Aidentity=20on=20the=20affected=20partitions,=20leaving=20= logical=20replication=0Amisconfigured.=0A=0AFix=20this=20by=20tracking=20= replica=20identity=20indexes=20using=20OIDs=20and=20by=0Arecursively=20= collecting=20replica=20identity=20indexes=20on=20all=20partitions=20of=20= a=0Apartitioned=20table.=20=20After=20index=20rebuilds=20complete,=20= restore=20replica=0Aidentity=20markings=20for=20each=20affected=20table.=0A= =0AAdd=20regression=20tests=20covering=20multi-level=20partition=20= hierarchies,=0Aincluding=20partitions=20in=20different=20schemas,=20to=20= verify=20that=20replica=0Aidentity=20is=20preserved=20across=20index=20= rebuilds.=0A=0AAuthor:=20Chao=20Li=20=0AReviewed-by:=20= Michael=20Paquier=20=0AReviewed-by:=20Xuneng=20Zhou=20= =0ADiscussion:=20= https://postgr.es/m/DB533C25-C6BA-4C0F-8046-96168E9CDD72@gmail.com=0A---=0A= =20src/backend/commands/tablecmds.c=20=20=20=20=20=20=20=20=20=20=20=20=20= =20|=20119=20+++++++++++++-----=0A=20= .../regress/expected/replica_identity.out=20=20=20=20=20|=20=2082=20= ++++++++++++=0A=20src/test/regress/sql/replica_identity.sql=20=20=20=20=20= |=20=2055=20++++++++=0A=203=20files=20changed,=20227=20insertions(+),=20= 29=20deletions(-)=0A=0Adiff=20--git=20a/src/backend/commands/tablecmds.c=20= b/src/backend/commands/tablecmds.c=0Aindex=20eec09ba1ded..26999c8ad0b=20= 100644=0A---=20a/src/backend/commands/tablecmds.c=0A+++=20= b/src/backend/commands/tablecmds.c=0A@@=20-205,7=20+205,10=20@@=20= typedef=20struct=20AlteredTableInfo=0A=20=09List=09=20=20=20= *changedConstraintDefs;=09/*=20string=20definitions=20of=20same=20*/=0A=20= =09List=09=20=20=20*changedIndexOids;=09/*=20OIDs=20of=20indexes=20to=20= rebuild=20*/=0A=20=09List=09=20=20=20*changedIndexDefs;=09/*=20string=20= definitions=20of=20same=20*/=0A-=09char=09=20=20=20= *replicaIdentityIndex;=09/*=20index=20to=20reset=20as=20REPLICA=20= IDENTITY=20*/=0A+=09List=09=20=20=20*replicaIdentityIndexOids;=09/*=20= OIDs=20of=20index=20to=20reset=20as=0A+=09=09=09=09=09=09=09=09=09=09=09=20= *=20REPLICA=20IDENTITY=20*/=0A+=09List=09=20=20=20= *replicaIdentityTableOids;=09/*=20OIDs=20of=20tables=20to=20reset=20as=0A= +=09=09=09=09=09=09=09=09=09=09=09=20*=20REPLICA=20IDENTITY=20*/=0A=20=09= char=09=20=20=20*clusterOnIndex;=20/*=20index=20to=20use=20for=20CLUSTER=20= */=0A=20=09List=09=20=20=20*changedStatisticsOids;=09/*=20OIDs=20of=20= statistics=20to=20rebuild=20*/=0A=20=09List=09=20=20=20= *changedStatisticsDefs;=09/*=20string=20definitions=20of=20same=20*/=0A= @@=20-662,9=20+665,9=20@@=20static=20bool=20= ATColumnChangeRequiresRewrite(Node=20*expr,=20AttrNumber=20varattno);=0A=20= static=20ObjectAddress=20ATExecAlterColumnType(AlteredTableInfo=20*tab,=20= Relation=20rel,=0A=20=09=09=09=09=09=09=09=09=09=09=20=20=20= AlterTableCmd=20*cmd,=20LOCKMODE=20lockmode);=0A=20static=20void=20= RememberAllDependentForRebuilding(AlteredTableInfo=20*tab,=20= AlterTableType=20subtype,=0A-=09=09=09=09=09=09=09=09=09=09=09=20=20= Relation=20rel,=20AttrNumber=20attnum,=20const=20char=20*colName);=0A= -static=20void=20RememberConstraintForRebuilding(Oid=20conoid,=20= AlteredTableInfo=20*tab);=0A-static=20void=20= RememberIndexForRebuilding(Oid=20indoid,=20AlteredTableInfo=20*tab);=0A+=09= =09=09=09=09=09=09=09=09=09=09=20=20Relation=20rel,=20AttrNumber=20= attnum,=20const=20char=20*colName,=20LOCKMODE=20lockmode);=0A+static=20= void=20RememberConstraintForRebuilding(Oid=20conoid,=20AlteredTableInfo=20= *tab,=20LOCKMODE=20lockmode);=0A+static=20void=20= RememberIndexForRebuilding(Oid=20indoid,=20AlteredTableInfo=20*tab,=20= LOCKMODE=20lockmode);=0A=20static=20void=20= RememberStatisticsForRebuilding(Oid=20stxoid,=20AlteredTableInfo=20= *tab);=0A=20static=20void=20ATPostAlterTypeCleanup(List=20**wqueue,=20= AlteredTableInfo=20*tab,=0A=20=09=09=09=09=09=09=09=09=20=20=20LOCKMODE=20= lockmode);=0A@@=20-8763,7=20+8766,7=20@@=20= ATExecSetExpression(AlteredTableInfo=20*tab,=20Relation=20rel,=20const=20= char=20*colName,=0A=20=09=20*=20Find=20everything=20that=20depends=20on=20= the=20column=20(constraints,=20indexes,=20etc),=0A=20=09=20*=20and=20= record=20enough=20information=20to=20let=20us=20recreate=20the=20= objects.=0A=20=09=20*/=0A-=09RememberAllDependentForRebuilding(tab,=20= AT_SetExpression,=20rel,=20attnum,=20colName);=0A+=09= RememberAllDependentForRebuilding(tab,=20AT_SetExpression,=20rel,=20= attnum,=20colName,=20lockmode);=0A=20=0A=20=09/*=0A=20=09=20*=20Drop=20= the=20dependency=20records=20of=20the=20GENERATED=20expression,=20in=20= particular=0A@@=20-15084,7=20+15087,7=20@@=20= ATExecAlterColumnType(AlteredTableInfo=20*tab,=20Relation=20rel,=0A=20=09= =20*=20the=20info=20before=20executing=20ALTER=20TYPE,=20though,=20else=20= the=20deparser=20will=0A=20=09=20*=20get=20confused.=0A=20=09=20*/=0A-=09= RememberAllDependentForRebuilding(tab,=20AT_AlterColumnType,=20rel,=20= attnum,=20colName);=0A+=09RememberAllDependentForRebuilding(tab,=20= AT_AlterColumnType,=20rel,=20attnum,=20colName,=20lockmode);=0A=20=0A=20=09= /*=0A=20=09=20*=20Now=20scan=20for=20dependencies=20of=20this=20column=20= on=20other=20things.=20=20The=20only=0A@@=20-15287,7=20+15290,7=20@@=20= ATExecAlterColumnType(AlteredTableInfo=20*tab,=20Relation=20rel,=0A=20=20= */=0A=20static=20void=0A=20= RememberAllDependentForRebuilding(AlteredTableInfo=20*tab,=20= AlterTableType=20subtype,=0A-=09=09=09=09=09=09=09=09=20=20Relation=20= rel,=20AttrNumber=20attnum,=20const=20char=20*colName)=0A+=09=09=09=09=09= =09=09=09=20=20Relation=20rel,=20AttrNumber=20attnum,=20const=20char=20= *colName,=20LOCKMODE=20lockmode)=0A=20{=0A=20=09Relation=09depRel;=0A=20=09= ScanKeyData=20key[3];=0A@@=20-15333,7=20+15336,7=20@@=20= RememberAllDependentForRebuilding(AlteredTableInfo=20*tab,=20= AlterTableType=20subtype,=0A=20=09=09=09=09=09=09relKind=20=3D=3D=20= RELKIND_PARTITIONED_INDEX)=0A=20=09=09=09=09=09{=0A=20=09=09=09=09=09=09= Assert(foundObject.objectSubId=20=3D=3D=200);=0A-=09=09=09=09=09=09= RememberIndexForRebuilding(foundObject.objectId,=20tab);=0A+=09=09=09=09=09= =09RememberIndexForRebuilding(foundObject.objectId,=20tab,=20lockmode);=0A= =20=09=09=09=09=09}=0A=20=09=09=09=09=09else=20if=20(relKind=20=3D=3D=20= RELKIND_SEQUENCE)=0A=20=09=09=09=09=09{=0A@@=20-15354,7=20+15357,7=20@@=20= RememberAllDependentForRebuilding(AlteredTableInfo=20*tab,=20= AlterTableType=20subtype,=0A=20=0A=20=09=09=09case=20= ConstraintRelationId:=0A=20=09=09=09=09Assert(foundObject.objectSubId=20= =3D=3D=200);=0A-=09=09=09=09= RememberConstraintForRebuilding(foundObject.objectId,=20tab);=0A+=09=09=09= =09RememberConstraintForRebuilding(foundObject.objectId,=20tab,=20= lockmode);=0A=20=09=09=09=09break;=0A=20=0A=20=09=09=09case=20= ProcedureRelationId:=0A@@=20-15507,20=20+15510,66=20@@=20= RememberAllDependentForRebuilding(AlteredTableInfo=20*tab,=20= AlterTableType=20subtype,=0A=20=09table_close(depRel,=20NoLock);=0A=20}=0A= =20=0A+static=20void=0A= +find_partition_replica_identity_indexes(AlteredTableInfo=20*tab,=20Oid=20= relId,=20Oid=20indexId,=20LOCKMODE=20lockmode)=0A+{=0A+=09List=09=20=20=20= *partRelIds=20=3D=20NIL;=0A+=0A+=09partRelIds=20=3D=20= find_inheritance_children(relId,=20lockmode);=0A+=09= foreach_oid(partRelOid,=20partRelIds)=0A+=09{=0A+=09=09Relation=09= partRel;=0A+=09=09Oid=09=09=09partIndexId;=0A+=0A+=09=09/*=20= find_inheritance_children=20already=20got=20lock=20*/=0A+=09=09partRel=20= =3D=20relation_open(partRelOid,=20NoLock);=0A+=0A+=09=09partIndexId=20=3D=20= index_get_partition(partRel,=20indexId);=0A+=09=09if=20= (!OidIsValid(partIndexId))=0A+=09=09{=0A+=09=09=09/*=20if=20we=20won't=20= touch=20the=20partition,=20then=20unlock=20it=20*/=0A+=09=09=09= relation_close(partRel,=20lockmode);=0A+=09=09=09continue;=0A+=09=09}=0A= +=0A+=09=09if=20(get_index_isreplident(partIndexId))=0A+=09=09{=0A+=09=09= =09tab->replicaIdentityIndexOids=20=3D=20= lappend_oid(tab->replicaIdentityIndexOids,=20partIndexId);=0A+=09=09=09= tab->replicaIdentityTableOids=20=3D=20= lappend_oid(tab->replicaIdentityTableOids,=20partRelOid);=0A+=09=09}=0A+=0A= +=09=09if=20(partRel->rd_rel->relkind=20=3D=3D=20= RELKIND_PARTITIONED_TABLE)=0A+=09=09{=0A+=09=09=09= find_partition_replica_identity_indexes(tab,=20partRelOid,=20= partIndexId,=20lockmode);=0A+=09=09}=0A+=0A+=09=09= relation_close(partRel,=20NoLock);=0A+=09}=0A+=09list_free(partRelIds);=0A= +}=0A+=0A=20/*=0A=20=20*=20Subroutine=20for=20ATExecAlterColumnType:=20= remember=20that=20a=20replica=20identity=0A=20=20*=20needs=20to=20be=20= reset.=0A=20=20*/=0A=20static=20void=0A= -RememberReplicaIdentityForRebuilding(Oid=20indoid,=20AlteredTableInfo=20= *tab)=0A+RememberReplicaIdentityForRebuilding(Oid=20indoid,=20= AlteredTableInfo=20*tab,=20LOCKMODE=20lockmode)=0A=20{=0A=20=09if=20= (!get_index_isreplident(indoid))=0A=20=09=09return;=0A=20=0A-=09if=20= (tab->replicaIdentityIndex)=0A+=09if=20(tab->replicaIdentityIndexOids=20= !=3D=20NIL)=0A=20=09=09elog(ERROR,=20"relation=20%u=20has=20multiple=20= indexes=20marked=20as=20replica=20identity",=20tab->relid);=0A=20=0A-=09= tab->replicaIdentityIndex=20=3D=20get_rel_name(indoid);=0A+=09= tab->replicaIdentityIndexOids=20=3D=20= lappend_oid(tab->replicaIdentityIndexOids,=20indoid);=0A+=09= tab->replicaIdentityTableOids=20=3D=20= lappend_oid(tab->replicaIdentityTableOids,=20tab->relid);=0A+=0A+=09/*=20= For=20regular=20tables,=20we=20can=20only=20have=20one=20replica=20= identity=20index=20*/=0A+=09if=20(tab->rel->rd_rel->relkind=20!=3D=20= RELKIND_PARTITIONED_TABLE)=0A+=09=09return;=0A+=0A+=09/*=20For=20= partitioned=20tables,=20find=20all=20partitions'=20replica=20identity=20= indexes=20*/=0A+=09find_partition_replica_identity_indexes(tab,=20= tab->relid,=20indoid,=20lockmode);=0A=20}=0A=20=0A=20/*=0A@@=20-15543,7=20= +15592,7=20@@=20RememberClusterOnForRebuilding(Oid=20indoid,=20= AlteredTableInfo=20*tab)=0A=20=20*=20to=20be=20rebuilt=20(which=20we=20= might=20already=20know).=0A=20=20*/=0A=20static=20void=0A= -RememberConstraintForRebuilding(Oid=20conoid,=20AlteredTableInfo=20= *tab)=0A+RememberConstraintForRebuilding(Oid=20conoid,=20= AlteredTableInfo=20*tab,=20LOCKMODE=20lockmode)=0A=20{=0A=20=09/*=0A=20=09= =20*=20This=20de-duplication=20check=20is=20critical=20for=20two=20= independent=20reasons:=20we=0A@@=20-15588,7=20+15637,7=20@@=20= RememberConstraintForRebuilding(Oid=20conoid,=20AlteredTableInfo=20*tab)=0A= =20=09=09indoid=20=3D=20get_constraint_index(conoid);=0A=20=09=09if=20= (OidIsValid(indoid))=0A=20=09=09{=0A-=09=09=09= RememberReplicaIdentityForRebuilding(indoid,=20tab);=0A+=09=09=09= RememberReplicaIdentityForRebuilding(indoid,=20tab,=20lockmode);=0A=20=09= =09=09RememberClusterOnForRebuilding(indoid,=20tab);=0A=20=09=09}=0A=20=09= }=0A@@=20-15599,7=20+15648,7=20@@=20RememberConstraintForRebuilding(Oid=20= conoid,=20AlteredTableInfo=20*tab)=0A=20=20*=20to=20be=20rebuilt=20= (which=20we=20might=20already=20know).=0A=20=20*/=0A=20static=20void=0A= -RememberIndexForRebuilding(Oid=20indoid,=20AlteredTableInfo=20*tab)=0A= +RememberIndexForRebuilding(Oid=20indoid,=20AlteredTableInfo=20*tab,=20= LOCKMODE=20lockmode)=0A=20{=0A=20=09/*=0A=20=09=20*=20This=20= de-duplication=20check=20is=20critical=20for=20two=20independent=20= reasons:=20we=0A@@=20-15622,7=20+15671,7=20@@=20= RememberIndexForRebuilding(Oid=20indoid,=20AlteredTableInfo=20*tab)=0A=20= =0A=20=09=09if=20(OidIsValid(conoid))=0A=20=09=09{=0A-=09=09=09= RememberConstraintForRebuilding(conoid,=20tab);=0A+=09=09=09= RememberConstraintForRebuilding(conoid,=20tab,=20lockmode);=0A=20=09=09}=0A= =20=09=09else=0A=20=09=09{=0A@@=20-15639,7=20+15688,7=20@@=20= RememberIndexForRebuilding(Oid=20indoid,=20AlteredTableInfo=20*tab)=0A=20= =09=09=09=20*=20or=20if=20it=20is=20a=20clustered=20index,=20so=20that=20= ATPostAlterTypeCleanup()=0A=20=09=09=09=20*=20can=20queue=20up=20= commands=20necessary=20to=20restore=20those=20properties.=0A=20=09=09=09=20= */=0A-=09=09=09RememberReplicaIdentityForRebuilding(indoid,=20tab);=0A+=09= =09=09RememberReplicaIdentityForRebuilding(indoid,=20tab,=20lockmode);=0A= =20=09=09=09RememberClusterOnForRebuilding(indoid,=20tab);=0A=20=09=09}=0A= =20=09}=0A@@=20-15818,19=20+15867,31=20@@=20ATPostAlterTypeCleanup(List=20= **wqueue,=20AlteredTableInfo=20*tab,=20LOCKMODE=20lockmode)=0A=20=09/*=0A= =20=09=20*=20Queue=20up=20command=20to=20restore=20replica=20identity=20= index=20marking=0A=20=09=20*/=0A-=09if=20(tab->replicaIdentityIndex)=0A+=09= if=20(tab->replicaIdentityIndexOids=20!=3D=20NIL)=0A=20=09{=0A-=09=09= AlterTableCmd=20*cmd=20=3D=20makeNode(AlterTableCmd);=0A-=09=09= ReplicaIdentityStmt=20*subcmd=20=3D=20makeNode(ReplicaIdentityStmt);=0A-=0A= -=09=09subcmd->identity_type=20=3D=20REPLICA_IDENTITY_INDEX;=0A-=09=09= subcmd->name=20=3D=20tab->replicaIdentityIndex;=0A-=09=09cmd->subtype=20= =3D=20AT_ReplicaIdentity;=0A-=09=09cmd->def=20=3D=20(Node=20*)=20subcmd;=0A= -=0A-=09=09/*=20do=20it=20after=20indexes=20and=20constraints=20*/=0A-=09= =09tab->subcmds[AT_PASS_OLD_CONSTR]=20=3D=0A-=09=09=09= lappend(tab->subcmds[AT_PASS_OLD_CONSTR],=20cmd);=0A+=09=09= forboth(oid_item,=20tab->replicaIdentityIndexOids,=0A+=09=09=09=09= def_item,=20tab->replicaIdentityTableOids)=0A+=09=09{=0A+=09=09=09Oid=09=09= =09indexId=20=3D=20lfirst_oid(oid_item);=0A+=09=09=09Oid=09=09=09relId=20= =3D=20lfirst_oid(def_item);=0A+=09=09=09Relation=09partrel;=0A+=09=09=09= AlteredTableInfo=20*parttab;=0A+=0A+=09=09=09AlterTableCmd=20*cmd=20=3D=20= makeNode(AlterTableCmd);=0A+=09=09=09ReplicaIdentityStmt=20*subcmd=20=3D=20= makeNode(ReplicaIdentityStmt);=0A+=0A+=09=09=09subcmd->identity_type=20=3D= =20REPLICA_IDENTITY_INDEX;=0A+=09=09=09subcmd->name=20=3D=20= get_rel_name(indexId);=0A+=09=09=09cmd->subtype=20=3D=20= AT_ReplicaIdentity;=0A+=09=09=09cmd->def=20=3D=20(Node=20*)=20subcmd;=0A= +=0A+=09=09=09/*=20do=20it=20after=20indexes=20and=20constraints=20*/=0A= +=09=09=09partrel=20=3D=20relation_open(relId,=20lockmode);=0A+=09=09=09= parttab=20=3D=20ATGetQueueEntry(wqueue,=20partrel);=0A+=09=09=09= parttab->subcmds[AT_PASS_OLD_CONSTR]=20=3D=0A+=09=09=09=09= lappend(parttab->subcmds[AT_PASS_OLD_CONSTR],=20cmd);=0A+=09=09=09= relation_close(partrel,=20NoLock);=0A+=09=09}=0A=20=09}=0A=20=0A=20=09/*=0A= diff=20--git=20a/src/test/regress/expected/replica_identity.out=20= b/src/test/regress/expected/replica_identity.out=0Aindex=20= 336b04fa278..4f363b88090=20100644=0A---=20= a/src/test/regress/expected/replica_identity.out=0A+++=20= b/src/test/regress/expected/replica_identity.out=0A@@=20-292,6=20+292,88=20= @@=20ALTER=20TABLE=20test_replica_identity5=20DROP=20CONSTRAINT=20= test_replica_identity5_pkey;=0A=20ERROR:=20=20constraint=20= "test_replica_identity5_pkey"=20of=20relation=20"test_replica_identity5"=20= does=20not=20exist=0A=20ALTER=20TABLE=20test_replica_identity5=20ALTER=20= b=20DROP=20NOT=20NULL;=0A=20ERROR:=20=20column=20"b"=20is=20in=20index=20= used=20as=20replica=20identity=0A+--=0A+--=20Test=20index=20rebuild=20= preserves=20replica=20identity=20against=20partitioned=20tables=0A+--=0A= +CREATE=20TABLE=20test_replica_identity_partitioned=20(id=20int=20NOT=20= NULL,=20val=20int=20NOT=20NULL)=20PARTITION=20BY=20RANGE=20(id);=0A= +CREATE=20TABLE=20test_replica_identity_partitioned_p1=20PARTITION=20OF=20= test_replica_identity_partitioned=0A+=20=20=20=20FOR=20VALUES=20FROM=20= (0)=20TO=20(100);=0A+CREATE=20TABLE=20= test_replica_identity_partitioned_p2=20PARTITION=20OF=20= test_replica_identity_partitioned=0A+=20=20=20=20FOR=20VALUES=20FROM=20= (101)=20TO=20(200)=20PARTITION=20BY=20LIST=20(id);=0A+CREATE=20TABLE=20= test_replica_identity_partitioned_p2_1=20PARTITION=20OF=20= test_replica_identity_partitioned_p2=0A+=20=20=20=20FOR=20VALUES=20IN=20= (150,=20160);=0A+--=20For=20better=20coverage,=20create=20a=20parition=20= in=20a=20different=20schema=0A+CREATE=20SCHEMA=20= test_replica_identity_schema;=0A+CREATE=20TABLE=20= test_replica_identity_schema.test_replica_identity_partitioned_p2_2=20= PARTITION=20OF=20test_replica_identity_partitioned_p2=0A+=20=20=20=20FOR=20= VALUES=20IN=20(170,=20180);=0A+CREATE=20UNIQUE=20INDEX=20= test_replica_identity_partitioned_pkey=20ON=20= test_replica_identity_partitioned=20(id,=20val);=0A+ALTER=20TABLE=20= test_replica_identity_partitioned=20REPLICA=20IDENTITY=20USING=20INDEX=20= test_replica_identity_partitioned_pkey;=0A+ALTER=20TABLE=20= test_replica_identity_partitioned_p1=20REPLICA=20IDENTITY=20USING=20= INDEX=20test_replica_identity_partitioned_p1_id_val_idx;=0A+ALTER=20= TABLE=20test_replica_identity_partitioned_p2_1=20REPLICA=20IDENTITY=20= USING=20INDEX=20test_replica_identity_partitioned_p2_1_id_val_idx;=0A= +ALTER=20TABLE=20= test_replica_identity_schema.test_replica_identity_partitioned_p2_2=20= REPLICA=20IDENTITY=20USING=20INDEX=20= test_replica_identity_partitioned_p2_2_id_val_idx;=0A+SELECT=20= tc.relname=20as=20table_name,=20tc.relreplident,=20= i.indexrelid::regclass=20AS=20index_name,=20i.indisreplident=20FROM=20= pg_class=20c=0A+=20=20LEFT=20JOIN=20pg_index=20i=20ON=20c.oid=20=3D=20= i.indexrelid=0A+=20=20LEFT=20JOIN=20pg_class=20tc=20ON=20i.indrelid=20=3D=20= tc.oid=0A+=20=20WHERE=20c.relname=20LIKE=20= 'test_replica_identity_partitioned%'=20and=20c.relkind=20in=20('i',=20= 'I')=0A+=20=20ORDER=20BY=20c.relname;=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20table_name=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=20= relreplident=20|=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20index_name=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20|=20indisreplident=20=0A= +----------------------------------------+--------------+-----------------= ---------------------------------------------------------------+----------= ------=0A+=20test_replica_identity_partitioned_p1=20=20=20|=20i=20=20=20=20= =20=20=20=20=20=20=20=20|=20= test_replica_identity_partitioned_p1_id_val_idx=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=20= t=0A+=20test_replica_identity_partitioned_p2_1=20|=20i=20=20=20=20=20=20=20= =20=20=20=20=20|=20test_replica_identity_partitioned_p2_1_id_val_idx=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20|=20t=0A+=20test_replica_identity_partitioned_p2_2=20|=20i=20=20= =20=20=20=20=20=20=20=20=20=20|=20= test_replica_identity_schema.test_replica_identity_partitioned_p2_2_id_val= _idx=20|=20t=0A+=20test_replica_identity_partitioned_p2=20=20=20|=20d=20=20= =20=20=20=20=20=20=20=20=20=20|=20= test_replica_identity_partitioned_p2_id_val_idx=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=20= f=0A+=20test_replica_identity_partitioned=20=20=20=20=20=20|=20i=20=20=20= =20=20=20=20=20=20=20=20=20|=20test_replica_identity_partitioned_pkey=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20|=20t=0A+(5=20rows)=0A+=0A+--=20= Create=20a=20temp=20table=20to=20store=20the=20index=20OIDs=20before=20= rebuild=0A+CREATE=20TEMP=20TABLE=20= test_replica_identity_partitioned_temp_index_oids_before=20AS=0A+SELECT=20= c.oid=20AS=20index_oid,=20c.relname=20AS=20index_name,=20= i.indisreplident=20FROM=20pg_class=20c=0A+=20=20LEFT=20JOIN=20pg_index=20= i=20ON=20c.oid=20=3D=20i.indexrelid=0A+=20=20LEFT=20JOIN=20pg_class=20tc=20= ON=20i.indrelid=20=3D=20tc.oid=0A+=20=20WHERE=20c.relname=20LIKE=20= 'test_replica_identity_partitioned%'=20and=20c.relkind=20in=20('i',=20= 'I')=0A+=20=20ORDER=20BY=20c.relname;=0A+ALTER=20TABLE=20= test_replica_identity_partitioned=20ALTER=20COLUMN=20val=20TYPE=20= bigint;=0A+SELECT=20tc.relname=20as=20table_name,=20tc.relreplident,=20= i.indexrelid::regclass=20AS=20index_name,=20i.indisreplident=20FROM=20= pg_class=20c=0A+=20=20LEFT=20JOIN=20pg_index=20i=20ON=20c.oid=20=3D=20= i.indexrelid=0A+=20=20LEFT=20JOIN=20pg_class=20tc=20ON=20i.indrelid=20=3D=20= tc.oid=0A+=20=20WHERE=20c.relname=20LIKE=20= 'test_replica_identity_partitioned%'=20and=20c.relkind=20in=20('i',=20= 'I')=0A+=20=20ORDER=20BY=20c.relname;=0A+=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20table_name=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=20= relreplident=20|=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20index_name=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20|=20indisreplident=20=0A= +----------------------------------------+--------------+-----------------= ---------------------------------------------------------------+----------= ------=0A+=20test_replica_identity_partitioned_p1=20=20=20|=20i=20=20=20=20= =20=20=20=20=20=20=20=20|=20= test_replica_identity_partitioned_p1_id_val_idx=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=20= t=0A+=20test_replica_identity_partitioned_p2_1=20|=20i=20=20=20=20=20=20=20= =20=20=20=20=20|=20test_replica_identity_partitioned_p2_1_id_val_idx=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20|=20t=0A+=20test_replica_identity_partitioned_p2_2=20|=20i=20=20= =20=20=20=20=20=20=20=20=20=20|=20= test_replica_identity_schema.test_replica_identity_partitioned_p2_2_id_val= _idx=20|=20t=0A+=20test_replica_identity_partitioned_p2=20=20=20|=20d=20=20= =20=20=20=20=20=20=20=20=20=20|=20= test_replica_identity_partitioned_p2_id_val_idx=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=20= f=0A+=20test_replica_identity_partitioned=20=20=20=20=20=20|=20i=20=20=20= =20=20=20=20=20=20=20=20=20|=20test_replica_identity_partitioned_pkey=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20|=20t=0A+(5=20rows)=0A+=0A+--=20= Create=20a=20temp=20table=20to=20store=20the=20index=20OIDs=20after=20= rebuild=0A+CREATE=20TEMP=20TABLE=20= test_replica_identity_partitioned_temp_index_oids_after=20AS=0A+SELECT=20= c.oid=20AS=20index_oid,=20c.relname=20AS=20index_name,=20= i.indisreplident=20FROM=20pg_class=20c=0A+=20=20LEFT=20JOIN=20pg_index=20= i=20ON=20c.oid=20=3D=20i.indexrelid=0A+=20=20LEFT=20JOIN=20pg_class=20tc=20= ON=20i.indrelid=20=3D=20tc.oid=0A+=20=20WHERE=20c.relname=20LIKE=20= 'test_replica_identity_partitioned%'=20and=20c.relkind=20in=20('i',=20= 'I')=0A+=20=20ORDER=20BY=20c.relname;=0A+--=20Compare=20the=20before=20= and=20after=20to=20ensure=20replica=20identity=20preserved=0A+SELECT=20= b.index_name,=20b.index_oid=20!=3D=20a.index_oid=20as=20rebuilt,=20= b.indisreplident=20!=3D=20a.indisreplident=20AS=20ri_lost=0A+=20=20FROM=20= test_replica_identity_partitioned_temp_index_oids_before=20b=0A+=20=20= JOIN=20test_replica_identity_partitioned_temp_index_oids_after=20a=0A+=20= =20ON=20b.index_name=20=3D=20a.index_name=0A+=20=20ORDER=20BY=20= b.index_name;=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20index_name=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20|=20rebuilt=20|=20ri_lost=20=0A= +---------------------------------------------------+---------+---------=0A= +=20test_replica_identity_partitioned_p1_id_val_idx=20=20=20|=20t=20=20=20= =20=20=20=20|=20f=0A+=20= test_replica_identity_partitioned_p2_1_id_val_idx=20|=20t=20=20=20=20=20=20= =20|=20f=0A+=20test_replica_identity_partitioned_p2_2_id_val_idx=20|=20t=20= =20=20=20=20=20=20|=20f=0A+=20= test_replica_identity_partitioned_p2_id_val_idx=20=20=20|=20t=20=20=20=20= =20=20=20|=20f=0A+=20test_replica_identity_partitioned_pkey=20=20=20=20=20= =20=20=20=20=20=20=20|=20t=20=20=20=20=20=20=20|=20f=0A+(5=20rows)=0A+=0A= +DROP=20SCHEMA=20test_replica_identity_schema=20CASCADE;=0A+NOTICE:=20=20= drop=20cascades=20to=20table=20= test_replica_identity_schema.test_replica_identity_partitioned_p2_2=0A= +--=0A+--=20Cleanup=0A+--=0A=20DROP=20TABLE=20test_replica_identity;=0A=20= DROP=20TABLE=20test_replica_identity2;=0A=20DROP=20TABLE=20= test_replica_identity3;=0Adiff=20--git=20= a/src/test/regress/sql/replica_identity.sql=20= b/src/test/regress/sql/replica_identity.sql=0Aindex=20= 30daec05b71..e9a71eac8a9=20100644=0A---=20= a/src/test/regress/sql/replica_identity.sql=0A+++=20= b/src/test/regress/sql/replica_identity.sql=0A@@=20-134,6=20+134,61=20@@=20= ALTER=20TABLE=20test_replica_identity5=20ALTER=20b=20SET=20NOT=20NULL;=0A= =20ALTER=20TABLE=20test_replica_identity5=20DROP=20CONSTRAINT=20= test_replica_identity5_pkey;=0A=20ALTER=20TABLE=20test_replica_identity5=20= ALTER=20b=20DROP=20NOT=20NULL;=0A=20=0A+--=0A+--=20Test=20index=20= rebuild=20preserves=20replica=20identity=20against=20partitioned=20= tables=0A+--=0A+CREATE=20TABLE=20test_replica_identity_partitioned=20(id=20= int=20NOT=20NULL,=20val=20int=20NOT=20NULL)=20PARTITION=20BY=20RANGE=20= (id);=0A+CREATE=20TABLE=20test_replica_identity_partitioned_p1=20= PARTITION=20OF=20test_replica_identity_partitioned=0A+=20=20=20=20FOR=20= VALUES=20FROM=20(0)=20TO=20(100);=0A+CREATE=20TABLE=20= test_replica_identity_partitioned_p2=20PARTITION=20OF=20= test_replica_identity_partitioned=0A+=20=20=20=20FOR=20VALUES=20FROM=20= (101)=20TO=20(200)=20PARTITION=20BY=20LIST=20(id);=0A+CREATE=20TABLE=20= test_replica_identity_partitioned_p2_1=20PARTITION=20OF=20= test_replica_identity_partitioned_p2=0A+=20=20=20=20FOR=20VALUES=20IN=20= (150,=20160);=0A+--=20For=20better=20coverage,=20create=20a=20parition=20= in=20a=20different=20schema=0A+CREATE=20SCHEMA=20= test_replica_identity_schema;=0A+CREATE=20TABLE=20= test_replica_identity_schema.test_replica_identity_partitioned_p2_2=20= PARTITION=20OF=20test_replica_identity_partitioned_p2=0A+=20=20=20=20FOR=20= VALUES=20IN=20(170,=20180);=0A+CREATE=20UNIQUE=20INDEX=20= test_replica_identity_partitioned_pkey=20ON=20= test_replica_identity_partitioned=20(id,=20val);=0A+ALTER=20TABLE=20= test_replica_identity_partitioned=20REPLICA=20IDENTITY=20USING=20INDEX=20= test_replica_identity_partitioned_pkey;=0A+ALTER=20TABLE=20= test_replica_identity_partitioned_p1=20REPLICA=20IDENTITY=20USING=20= INDEX=20test_replica_identity_partitioned_p1_id_val_idx;=0A+ALTER=20= TABLE=20test_replica_identity_partitioned_p2_1=20REPLICA=20IDENTITY=20= USING=20INDEX=20test_replica_identity_partitioned_p2_1_id_val_idx;=0A= +ALTER=20TABLE=20= test_replica_identity_schema.test_replica_identity_partitioned_p2_2=20= REPLICA=20IDENTITY=20USING=20INDEX=20= test_replica_identity_partitioned_p2_2_id_val_idx;=0A+SELECT=20= tc.relname=20as=20table_name,=20tc.relreplident,=20= i.indexrelid::regclass=20AS=20index_name,=20i.indisreplident=20FROM=20= pg_class=20c=0A+=20=20LEFT=20JOIN=20pg_index=20i=20ON=20c.oid=20=3D=20= i.indexrelid=0A+=20=20LEFT=20JOIN=20pg_class=20tc=20ON=20i.indrelid=20=3D=20= tc.oid=0A+=20=20WHERE=20c.relname=20LIKE=20= 'test_replica_identity_partitioned%'=20and=20c.relkind=20in=20('i',=20= 'I')=0A+=20=20ORDER=20BY=20c.relname;=0A+--=20Create=20a=20temp=20table=20= to=20store=20the=20index=20OIDs=20before=20rebuild=0A+CREATE=20TEMP=20= TABLE=20test_replica_identity_partitioned_temp_index_oids_before=20AS=0A= +SELECT=20c.oid=20AS=20index_oid,=20c.relname=20AS=20index_name,=20= i.indisreplident=20FROM=20pg_class=20c=0A+=20=20LEFT=20JOIN=20pg_index=20= i=20ON=20c.oid=20=3D=20i.indexrelid=0A+=20=20LEFT=20JOIN=20pg_class=20tc=20= ON=20i.indrelid=20=3D=20tc.oid=0A+=20=20WHERE=20c.relname=20LIKE=20= 'test_replica_identity_partitioned%'=20and=20c.relkind=20in=20('i',=20= 'I')=0A+=20=20ORDER=20BY=20c.relname;=0A+ALTER=20TABLE=20= test_replica_identity_partitioned=20ALTER=20COLUMN=20val=20TYPE=20= bigint;=0A+SELECT=20tc.relname=20as=20table_name,=20tc.relreplident,=20= i.indexrelid::regclass=20AS=20index_name,=20i.indisreplident=20FROM=20= pg_class=20c=0A+=20=20LEFT=20JOIN=20pg_index=20i=20ON=20c.oid=20=3D=20= i.indexrelid=0A+=20=20LEFT=20JOIN=20pg_class=20tc=20ON=20i.indrelid=20=3D=20= tc.oid=0A+=20=20WHERE=20c.relname=20LIKE=20= 'test_replica_identity_partitioned%'=20and=20c.relkind=20in=20('i',=20= 'I')=0A+=20=20ORDER=20BY=20c.relname;=0A+--=20Create=20a=20temp=20table=20= to=20store=20the=20index=20OIDs=20after=20rebuild=0A+CREATE=20TEMP=20= TABLE=20test_replica_identity_partitioned_temp_index_oids_after=20AS=0A= +SELECT=20c.oid=20AS=20index_oid,=20c.relname=20AS=20index_name,=20= i.indisreplident=20FROM=20pg_class=20c=0A+=20=20LEFT=20JOIN=20pg_index=20= i=20ON=20c.oid=20=3D=20i.indexrelid=0A+=20=20LEFT=20JOIN=20pg_class=20tc=20= ON=20i.indrelid=20=3D=20tc.oid=0A+=20=20WHERE=20c.relname=20LIKE=20= 'test_replica_identity_partitioned%'=20and=20c.relkind=20in=20('i',=20= 'I')=0A+=20=20ORDER=20BY=20c.relname;=0A+--=20Compare=20the=20before=20= and=20after=20to=20ensure=20replica=20identity=20preserved=0A+SELECT=20= b.index_name,=20b.index_oid=20!=3D=20a.index_oid=20as=20rebuilt,=20= b.indisreplident=20!=3D=20a.indisreplident=20AS=20ri_lost=0A+=20=20FROM=20= test_replica_identity_partitioned_temp_index_oids_before=20b=0A+=20=20= JOIN=20test_replica_identity_partitioned_temp_index_oids_after=20a=0A+=20= =20ON=20b.index_name=20=3D=20a.index_name=0A+=20=20ORDER=20BY=20= b.index_name;=0A+DROP=20SCHEMA=20test_replica_identity_schema=20CASCADE;=0A= +=0A+--=0A+--=20Cleanup=0A+--=0A=20DROP=20TABLE=20test_replica_identity;=0A= =20DROP=20TABLE=20test_replica_identity2;=0A=20DROP=20TABLE=20= test_replica_identity3;=0A--=20=0A2.50.1=20(Apple=20Git-155)=0A=0A= --Apple-Mail=_19C03C97-5D2B-4064-9D8A-02D2E976D35B--