diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index 92cb72ebba6..6cbd31f0a3d 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -505,16 +505,18 @@ brininsertcleanup(Relation index, IndexInfo *indexInfo) BrinInsertState *bistate = (BrinInsertState *) indexInfo->ii_AmCache; /* bail out if cache not initialized */ - if (indexInfo->ii_AmCache == NULL) + if (bistate == NULL) return; + /* do this first to avoid dangling pointer if we fail partway through */ + indexInfo->ii_AmCache = NULL; + /* * Clean up the revmap. Note that the brinDesc has already been cleaned up * as part of its own memory context. */ brinRevmapTerminate(bistate->bis_rmAccess); - bistate->bis_rmAccess = NULL; - bistate->bis_desc = NULL; + pfree(bistate); } /* diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index d091a1dd27c..65e22306c48 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -2432,8 +2432,13 @@ apply_handle_insert(StringInfo s) apply_handle_tuple_routing(edata, remoteslot, NULL, CMD_INSERT); else - apply_handle_insert_internal(edata, edata->targetRelInfo, - remoteslot); + { + ResultRelInfo *relinfo = edata->targetRelInfo; + + ExecOpenIndices(relinfo, false); + apply_handle_insert_internal(edata, relinfo, remoteslot); + ExecCloseIndices(relinfo); + } finish_edata(edata); @@ -2460,15 +2465,14 @@ apply_handle_insert_internal(ApplyExecutionData *edata, { EState *estate = edata->estate; - /* We must open indexes here. */ - ExecOpenIndices(relinfo, false); + /* Caller should have opened indexes already. */ + Assert(relinfo->ri_IndexRelationDescs != NULL || + !relinfo->ri_RelationDesc->rd_rel->relhasindex || + RelationGetIndexList(relinfo->ri_RelationDesc) == NIL); /* Do the insert. */ TargetPrivilegesCheck(relinfo->ri_RelationDesc, ACL_INSERT); ExecSimpleRelationInsert(relinfo, estate, remoteslot); - - /* Cleanup. */ - ExecCloseIndices(relinfo); } /* @@ -2767,8 +2771,14 @@ apply_handle_delete(StringInfo s) apply_handle_tuple_routing(edata, remoteslot, NULL, CMD_DELETE); else - apply_handle_delete_internal(edata, edata->targetRelInfo, + { + ResultRelInfo *relinfo = edata->targetRelInfo; + + ExecOpenIndices(relinfo, false); + apply_handle_delete_internal(edata, relinfo, remoteslot, rel->localindexoid); + ExecCloseIndices(relinfo); + } finish_edata(edata); @@ -2802,7 +2812,11 @@ apply_handle_delete_internal(ApplyExecutionData *edata, bool found; EvalPlanQualInit(&epqstate, estate, NULL, NIL, -1, NIL); - ExecOpenIndices(relinfo, false); + + /* Caller should have opened indexes already. */ + Assert(relinfo->ri_IndexRelationDescs != NULL || + !localrel->rd_rel->relhasindex || + RelationGetIndexList(localrel) == NIL); found = FindReplTupleInLocalRel(edata, localrel, remoterel, localindexoid, remoteslot, &localslot); @@ -2831,7 +2845,6 @@ apply_handle_delete_internal(ApplyExecutionData *edata, } /* Cleanup. */ - ExecCloseIndices(relinfo); EvalPlanQualEnd(&epqstate); } @@ -3042,14 +3055,12 @@ apply_handle_tuple_routing(ApplyExecutionData *edata, EPQState epqstate; EvalPlanQualInit(&epqstate, estate, NULL, NIL, -1, NIL); - ExecOpenIndices(partrelinfo, false); EvalPlanQualSetSlot(&epqstate, remoteslot_part); TargetPrivilegesCheck(partrelinfo->ri_RelationDesc, ACL_UPDATE); ExecSimpleRelationUpdate(partrelinfo, estate, &epqstate, localslot, remoteslot_part); - ExecCloseIndices(partrelinfo); EvalPlanQualEnd(&epqstate); } else diff --git a/src/test/subscription/t/013_partition.pl b/src/test/subscription/t/013_partition.pl index 29580525a97..db7a1604643 100644 --- a/src/test/subscription/t/013_partition.pl +++ b/src/test/subscription/t/013_partition.pl @@ -49,6 +49,10 @@ $node_publisher->safe_psql('postgres', $node_subscriber1->safe_psql('postgres', "CREATE TABLE tab1 (c text, a int PRIMARY KEY, b text) PARTITION BY LIST (a)" ); +# make a BRIN index to test aminsertcleanup logic in subscriber +$node_subscriber1->safe_psql('postgres', + "CREATE INDEX tab1_c_brin_idx ON tab1 USING brin (c)" +); $node_subscriber1->safe_psql('postgres', "CREATE TABLE tab1_1 (b text, c text DEFAULT 'sub1_tab1', a int NOT NULL)" );