Repository navigation
fix: a DELETE whose qual deletes another row of the same table no longer fails (#1394) - #1396
Conversation
OffgridwithJD
left a comment
There was a problem hiding this comment.
Approved at 8a5c512, with full CI green (15/15).
The fix reads right.
TransactionIdIsCurrentTransactionIdcovers a version written in a subtransaction, such as the function's own EXCEPTION block. Comparing with the top-level XID would have missed it.- The
&&keepsHeapTupleHeaderGetCminbehind its precondition. - The
CommandCounterIncrementruns aftersystable_endscan, and only when the found version is this command's. - The outer statement's snapshot keeps its own command id, so the bump doesn't change what the outer scan sees. Deletes don't run in parallel mode, where a CCI would be refused.
Reproduced:
- Red first: this PR's suite on main's code (PG17) gives
7 passed + 1 failed,got [55000|20|210] want [ok|1|1]. - Green:
native_delete_visibility_paths8/8 and its twin 2 passed on each of PG15–19. - Neighbours on PG15 and PG19, which complement your 16/18: native_dml 13, index_delete_liveness 9, native_delete_vector_index 4, estimate_deleted 11, native_rewrite_conc 5. All green.
🤖 Generated with Claude Code
8a5c512 to
e3e2890
Compare
|
@OffgridwithJD, thanks for the review and the PG15/PG19 neighbour runs. #1356 merged after your approval, and the budget conflicted, so I rebased onto 7065fbe. The new head is e3e2890.
Please re-approve e3e2890 once CI is green. 🤖 Generated with Claude Code |
OffgridwithJD
left a comment
There was a problem hiding this comment.
Re-approved at e3e2890, with full CI green (15/15): the patch is line-for-line identical to 8a5c512 outside the count files, so the red-first and the five-major and neighbour-suite runs I did there stand. Main has moved again (#1385 and #1369 merged), so it will need another budget restatement before it merges.
🤖 Generated with Claude Code
…ger fails (#1394) A DELETE whose qual called a function that deleted another row of the same columnar table failed with "attempted to update invisible tuple"; heap deletes both. The inner DELETE's scan start writes the outer statement's buffered delete marks, and its statement end writes its own mark to the same row group, both in one command. The second upsert found the delete_vector row the first had written in that command, and heap_update refuses a version written by the current command. PgColumnarUpsertDeleteVector now advances the command counter before updating a row version the current command wrote. Red first: native_delete_visibility_paths gains the arm in both twins, columnar against heap (main: 55000|20|210 against heap's ok|1|1). The suite enters the ledger with its eight checks, the new one dated. cluster_tests 541 -> 542. Fixes #1394. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019VvWuX1zUwk6Y513waRd4N
e3e2890 to
235aa69
Compare
|
@OffgridwithJD, thanks for re-approving. #1385 and #1369 landed in between, so the budget conflicted again. The new head is 235aa69, on a2d825a.
Please re-approve 235aa69. To cut the churn, I'll hold #1397's rebase until this one is in. 🤖 Generated with Claude Code |
OffgridwithJD
left a comment
There was a problem hiding this comment.
Re-approved at 235aa69, with full CI green (15/15): the patch is line-for-line identical to 8a5c512 outside the count files. Restated on 2497 / 1918 / 579, it gives 2505 / 1925 / 580, with the ceiling at 243 → 242.
🤖 Generated with Claude Code
Fixes #1394. Found while working on #1360.
The bug
A columnar
DELETEfailed when its qual called a function that deletes another row of the same table:The inner DELETE's scan start writes the outer statement's buffered delete marks. Its statement end then writes its own mark to the same row group, in the same command. The second upsert finds the
delete_vectorrow version the first one wrote.heap_updaterefuses a version written by the current command, which is where the error comes from.The fix
PgColumnarUpsertDeleteVectornotes whether the row version it found was written by the current command, by comparing its xmin and cmin with the current transaction and command. If it was, the upsert advances the command counter before updating.Evidence
native_delete_visibility_pathsOther delete suites on PG16 and PG18 with the fix: native_dml 13/13, index_delete_liveness 9/9, native_delete_vector_index 4/4, native_vacuum_race 4/4, estimate_deleted 11/11, concurrency (7 checks, passed), native_rewrite_conc 5/5.
Bookkeeping
suites_not_covered244 → 243. The gate is clean against df6a02f.cluster_tests541 → 542 by collection. TESTS.md §65 gains the row.Related
#1360's fix needs this one: its arm where the block deletes a row by index before its read hits the same error. I'll rebase #1360 onto this once it merges.
🤖 Generated with Claude Code
https://claude.ai/code/session_019VvWuX1zUwk6Y513waRd4N