| From: | Tender Wang <tndrwang(at)gmail(dot)com> |
|---|---|
| To: | Jeff Davis <pgsql(at)j-davis(dot)com> |
| Cc: | pgsql-bugs(at)postgresql(dot)org, Dean Rasheed <dean(dot)a(dot)rasheed(at)gmail(dot)com> |
| Subject: | Re: wrong results: merge when not matched by source |
| Date: | 2026-09-18 02:02:42 |
| Message-ID: | CAHewXN=GhY6_McohLq5wV5GqqGVihCwnG6M3q42SUXTw5tqW1g@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
Jeff Davis <pgsql(at)j-davis(dot)com> 于2026年9月18日周五 03:18写道:
>
> -- Expected: only UPDATE of key=1; table is {(1, src)}.
> -- Actual: also INSERT of (NULL, NULL).
I think the problem is that the TM_Deleted case in
ExecMergeMatched() unconditionally sets *matched to false.
This is correct when the candidate row was originally a MATCHED row:
the source row still exists after the target row is concurrently
deleted, so it should be processed by the NOT MATCHED BY TARGET
actions.
However, it is not correct when processing an original NOT MATCHED BY
SOURCE row. In that case, the source row was already absent, and after
the concurrent deletion of the target row, there is no candidate row
left to process. Setting *matched to false causes ExecMerge() to
call ExecMergeNotMatched(), which executes the NOT MATCHED BY TARGET
INSERT using the null source side of the original join row.
A tentative fix is to set *matched to false only if the current
action is a MATCHED action, as in the attached patch.
There is another TM_Deleted case below, reached while handling
TM_Updated and following the update chain:
...
case TM_Deleted:
*matched = false;
goto out;
...
I think that case may need similar treatment. The existing
was_matched variable could perhaps be used there:
...
if (was_matched)
*matched = false;
...
I have left that case unchanged for now because I would like to
confirm whether the same state distinction applies to all paths
through that code.
The attached patch is intended to show the proposed fix and does not
yet include a regression test.
--
Thanks,
Tender Wang
| Attachment | Content-Type | Size |
|---|---|---|
| 0001-Fix-merge-issue.patch | text/plain | 1.4 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Tom Lane | 2026-09-18 02:07:26 | Re: BUG #19545: Integer truncation of `GinTuple.keylen` causes out-of-bounds read in parallel GIN index build |
| Previous Message | Manuel Reyes Bravo | 2026-09-17 22:40:44 | Re: BUG #19692: Generic partition-pruning plan delays statement_timeout cancellation |