Skip to content

Commit 7bc4d45

Browse files

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

lib/pg_btree.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,40 @@ SpoolerClose(Spooler *self)
188188

189189
/* Terminate spooler. */
190190
ExecDropSingleTupleTableSlot(self->slot);
191-
#if PG_VERSION_NUM >= 140000
191+
#if PG_VERSION_NUM >= 180000
192+
/*
193+
* In PostgreSQL 18 and later, ExecCloseIndices() asserts that it is not
194+
* called on a ResultRelInfo with already-closed indexes. However,
195+
* IndexSpoolEnd() may have already closed some indexes (e.g. non-btree
196+
* indexes that get reindexed), which causes the assertion to fail.
197+
*
198+
* To work around this, we replicate the logic of ExecCloseIndices()
199+
* here, but with a check to skip already-closed indexes, similar to how
200+
* older PostgreSQL versions behaved. We don't call
201+
* ExecCloseResultRelations() to avoid the problematic assertion.
202+
*/
203+
if (self->relinfo)
204+
{
205+
ResultRelInfo *resultRelInfo = self->relinfo;
206+
int i;
207+
208+
if (resultRelInfo->ri_NumIndices > 0)
209+
{
210+
for (i = 0; i < resultRelInfo->ri_NumIndices; i++)
211+
{
212+
if (resultRelInfo->ri_IndexRelationDescs[i] == NULL)
213+
continue;
214+
215+
/* Give the index a chance to do some post-insert cleanup */
216+
index_insert_cleanup(resultRelInfo->ri_IndexRelationDescs[i],
217+
resultRelInfo->ri_IndexRelationInfo[i]);
218+
219+
/* Drop lock acquired by ExecOpenIndices */
220+
index_close(resultRelInfo->ri_IndexRelationDescs[i], RowExclusiveLock);
221+
}
222+
}
223+
}
224+
#elif PG_VERSION_NUM >= 140000
192225
if (self->relinfo)
193226
ExecCloseResultRelations(self->estate);
194227
#else

0 commit comments

Comments
 (0)