=== Applying patches on top of PostgreSQL commit ID 3c982c9bf1af994090a181c68f9407ff39d3ddf7 === /etc/rc.d/jail: WARNING: Per-jail configuration via jail_* variables is obsolete. Please consider migrating to /etc/jail.conf. Tue Aug 25 19:19:25 UTC 2026 On branch cf/7195 nothing to commit, working tree clean === using 'git am' to apply patch ./v2-0001-Fix-GIN-VACUUM-unfinished-split-page-deletion-bug.patch === Applying: Fix GIN VACUUM unfinished split page deletion bug. Using index info to reconstruct a base tree... M src/backend/access/gin/ginvacuum.c M src/test/modules/gin/Makefile M src/test/modules/gin/expected/gin_incomplete_splits.out M src/test/modules/gin/sql/gin_incomplete_splits.sql Falling back to patching base and 3-way merge... Auto-merging src/test/modules/gin/sql/gin_incomplete_splits.sql CONFLICT (content): Merge conflict in src/test/modules/gin/sql/gin_incomplete_splits.sql Auto-merging src/test/modules/gin/expected/gin_incomplete_splits.out CONFLICT (content): Merge conflict in src/test/modules/gin/expected/gin_incomplete_splits.out Auto-merging src/backend/access/gin/ginvacuum.c CONFLICT (content): Merge conflict in src/backend/access/gin/ginvacuum.c error: Failed to merge in the changes. hint: Use 'git am --show-current-patch=diff' to see the failed patch Patch failed at 0001 Fix GIN VACUUM unfinished split page deletion bug. When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort". === using patch(1) to apply patch ./v2-0001-Fix-GIN-VACUUM-unfinished-split-page-deletion-bug.patch === patching file src/backend/access/gin/ginvacuum.c Hunk #1 succeeded at 169 with fuzz 2 (offset 2 lines). Hunk #2 FAILED at 336. 1 out of 2 hunks FAILED -- saving rejects to file src/backend/access/gin/ginvacuum.c.rej patching file src/test/modules/gin/Makefile Hunk #1 FAILED at 1. 1 out of 1 hunk FAILED -- saving rejects to file src/test/modules/gin/Makefile.rej patching file src/test/modules/gin/expected/gin_incomplete_splits.out Hunk #1 FAILED at 19. Hunk #2 FAILED at 192. 2 out of 2 hunks FAILED -- saving rejects to file src/test/modules/gin/expected/gin_incomplete_splits.out.rej patching file src/test/modules/gin/sql/gin_incomplete_splits.sql Hunk #1 FAILED at 17. Hunk #2 FAILED at 149. 2 out of 2 hunks FAILED -- saving rejects to file src/test/modules/gin/sql/gin_incomplete_splits.sql.rej Unstaged changes after reset: M src/backend/access/gin/ginvacuum.c Removing src/backend/access/gin/ginvacuum.c.rej Removing src/test/modules/gin/Makefile.rej Removing src/test/modules/gin/expected/gin_incomplete_splits.out.rej Removing src/test/modules/gin/sql/gin_incomplete_splits.sql.rej === using 'git apply' to apply patch ./v2-0001-Fix-GIN-VACUUM-unfinished-split-page-deletion-bug.patch === Applied patch to 'src/backend/access/gin/ginvacuum.c' with conflicts. Applied patch to 'src/test/modules/gin/Makefile' cleanly. Applied patch to 'src/test/modules/gin/expected/gin_incomplete_splits.out' with conflicts. Applied patch to 'src/test/modules/gin/sql/gin_incomplete_splits.sql' with conflicts. U src/backend/access/gin/ginvacuum.c U src/test/modules/gin/expected/gin_incomplete_splits.out U src/test/modules/gin/sql/gin_incomplete_splits.sql diff --cc src/backend/access/gin/ginvacuum.c index 2cd4e50aa61,7a1a1da7fb2..00000000000 --- a/src/backend/access/gin/ginvacuum.c +++ b/src/backend/access/gin/ginvacuum.c @@@ -339,13 -339,13 +339,23 @@@ ginScanPostingTreeToDelete(GinVacuumSta * Proceed to the ginDeletePostingPage() if target page is not the * leftmost or the rightmost page. * ++<<<<<<< ours + * leftBuffer is the target's left sibling according to the parent + * level, which is not necessarily its left sibling in the sibling + * link chain (the rightlinks stored on pages): the new right half of + * an incompletely split page is in the sibling chain, but has no + * downlink yet. ginDeletePostingPage isn't prepared to deal with + * that, so we must refuse to delete when either the target or its + * left sibling page is marked incompletely split. ++======= + * We cannot delete an empty target page whose left sibling is + * incompletely split; ginDeletePostingPage expects to find and remove + * such a target page's downlink, but there isn't any yet (there won't + * be until an inserter finishes the incomplete split). We also avoid + * deleting an empty target page that is itself incompletely split; + * allowing that case would make it impossible for us to detect that + * it's unsafe to delete the target's right sibling page later on. ++>>>>>>> theirs */ if (BufferIsValid(myStackItem->leftBuffer) && !GinPageRightMost(page) && !GinPageIsIncompleteSplit(page) && diff --cc src/test/modules/gin/expected/gin_incomplete_splits.out index c4bc09ac6ab,ef346b75fc7..00000000000 --- a/src/test/modules/gin/expected/gin_incomplete_splits.out +++ b/src/test/modules/gin/expected/gin_incomplete_splits.out @@@ -264,9 -264,9 +264,15 @@@ delete from gin_posting_tre where ctid in (select unnest(tids) from gin_leafpage_items( get_raw_page('gin_posting_tree_idx', :nextleaf))); vacuum (index_cleanup on) gin_posting_tree; ++<<<<<<< ours +-- Count the remaining rows through a bitmap scan +explain (costs off) +select count(*) as bitmapscan_count from gin_posting_tree where i @> '{1}'; ++======= + -- Verify that bitmap scan finds every remaining row + explain (costs off) + select count(*) as onecount from gin_posting_tree where i @> '{1}'; ++>>>>>>> theirs QUERY PLAN ------------------------------------------------------- Aggregate @@@ -276,13 -276,17 +282,27 @@@ Index Cond: (i @> '{1}'::integer[]) (5 rows) ++<<<<<<< ours +select count(*) as bitmapscan_count from gin_posting_tree where i @> '{1}' +\gset +-- Verify that a sequential scan finds the same rows +set enable_seqscan=on; +set enable_bitmapscan=off; +explain (costs off) +select count(*) from gin_posting_tree where i @> '{1}'; ++======= + select count(*) as onecount from gin_posting_tree where i @> '{1}'; + onecount + ---------- + 39879 + (1 row) + + -- Verify that a sequential scan gives the same result + set enable_seqscan=on; + set enable_bitmapscan=off; + explain (costs off) + select count(*) as onecount from gin_posting_tree where i @> '{1}'; ++>>>>>>> theirs QUERY PLAN ----------------------------------------- Aggregate @@@ -290,11 -294,10 +310,18 @@@ Filter: (i @> '{1}'::integer[]) (3 rows) ++<<<<<<< ours +select count(*) = :bitmapscan_count as seqscan_agrees + from gin_posting_tree where i @> '{1}'; + seqscan_agrees +---------------- + t ++======= + select count(*) as onecount from gin_posting_tree where i @> '{1}'; + onecount + ---------- + 39879 ++>>>>>>> theirs (1 row) drop table gin_posting_tree; diff --cc src/test/modules/gin/sql/gin_incomplete_splits.sql index 1a0c0055fe9,3b8a60affaf..00000000000 --- a/src/test/modules/gin/sql/gin_incomplete_splits.sql +++ b/src/test/modules/gin/sql/gin_incomplete_splits.sql @@@ -213,19 -213,17 +213,33 @@@ delete from gin_posting_tre get_raw_page('gin_posting_tree_idx', :nextleaf))); vacuum (index_cleanup on) gin_posting_tree; ++<<<<<<< ours +-- Count the remaining rows through a bitmap scan +explain (costs off) +select count(*) as bitmapscan_count from gin_posting_tree where i @> '{1}'; +select count(*) as bitmapscan_count from gin_posting_tree where i @> '{1}' +\gset + +-- Verify that a sequential scan finds the same rows +set enable_seqscan=on; +set enable_bitmapscan=off; +explain (costs off) +select count(*) from gin_posting_tree where i @> '{1}'; +select count(*) = :bitmapscan_count as seqscan_agrees + from gin_posting_tree where i @> '{1}'; ++======= + -- Verify that bitmap scan finds every remaining row + explain (costs off) + select count(*) as onecount from gin_posting_tree where i @> '{1}'; + select count(*) as onecount from gin_posting_tree where i @> '{1}'; + + -- Verify that a sequential scan gives the same result + set enable_seqscan=on; + set enable_bitmapscan=off; + explain (costs off) + select count(*) as onecount from gin_posting_tree where i @> '{1}'; + select count(*) as onecount from gin_posting_tree where i @> '{1}'; ++>>>>>>> theirs drop table gin_posting_tree;