Thread
-
BUG #19111: Using EXPLAIN ANALYZE with MERGE causes failed assert
PG Bug reporting form <noreply@postgresql.org> — 2025-11-13T10:04:08Z
The following bug has been logged on the website: Bug reference: 19111 Logged by: Oleg Tselebrovskiy Email address: o.tselebrovskiy@postgrespro.ru PostgreSQL version: 17.6 Operating system: Ubuntu 22.04 Description: On PostgreSQL 17+ if you do the following: -- first psql CREATE TABLE target (key int primary key, val text); INSERT INTO target VALUES (1, 'setup1'); CREATE TABLE pa_target (key integer, val text) PARTITION BY LIST (key); CREATE TABLE part1 (key integer, val text); CREATE TABLE part2 (val text, key integer); CREATE TABLE part3 (key integer, val text); ALTER TABLE pa_target ATTACH PARTITION part1 FOR VALUES IN (1,4); ALTER TABLE pa_target ATTACH PARTITION part2 FOR VALUES IN (2,5,6); ALTER TABLE pa_target ATTACH PARTITION part3 DEFAULT; INSERT INTO pa_target VALUES (1, 'initial'); INSERT INTO pa_target VALUES (2, 'initial'); BEGIN ISOLATION LEVEL READ COMMITTED; MERGE INTO target t USING (SELECT 1 as key, 'merge1' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; -- second psql BEGIN ISOLATION LEVEL READ COMMITTED; EXPLAIN ANALYZE MERGE INTO target t USING (SELECT 1 as key, 'merge2a' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val WHEN NOT MATCHED BY SOURCE THEN UPDATE set key = t.key + 1, val = t.val || ' source not matched by merge2a' RETURNING merge_action(), t.*; -- first psql again COMMIT; Then the backend for the second psql crashes. With asserts turned on: TRAP: failed Assert("skipped_path >= 0"), File: "explain.c", Line: 4732, PID: 66557 postgres: postgres postgres [local] EXPLAIN(ExceptionalCondition+0xbb)[0x5cd80c4ea887] postgres: postgres postgres [local] EXPLAIN(+0x34feb6)[0x5cd80bf13eb6] postgres: postgres postgres [local] EXPLAIN(+0x349ceb)[0x5cd80bf0dceb] postgres: postgres postgres [local] EXPLAIN(ExplainPrintPlan+0x1f5)[0x5cd80bf09804] postgres: postgres postgres [local] EXPLAIN(ExplainOnePlan+0x43f)[0x5cd80bf0907d] postgres: postgres postgres [local] EXPLAIN(standard_ExplainOneQuery+0x30f)[0x5cd80bf08845] postgres: postgres postgres [local] EXPLAIN(+0x344530)[0x5cd80bf08530] postgres: postgres postgres [local] EXPLAIN(ExplainQuery+0x15e)[0x5cd80bf08198] postgres: postgres postgres [local] EXPLAIN(standard_ProcessUtility+0xa8a)[0x5cd80c2ec462] postgres: postgres postgres [local] EXPLAIN(ProcessUtility+0x13a)[0x5cd80c2eb9d1] postgres: postgres postgres [local] EXPLAIN(+0x72628a)[0x5cd80c2ea28a] postgres: postgres postgres [local] EXPLAIN(+0x725fc7)[0x5cd80c2e9fc7] postgres: postgres postgres [local] EXPLAIN(PortalRun+0x249)[0x5cd80c2e9890] postgres: postgres postgres [local] EXPLAIN(+0x71e04c)[0x5cd80c2e204c] postgres: postgres postgres [local] EXPLAIN(PostgresMain+0xb43)[0x5cd80c2e7843] postgres: postgres postgres [local] EXPLAIN(+0x719525)[0x5cd80c2dd525] postgres: postgres postgres [local] EXPLAIN(postmaster_child_launch+0x174)[0x5cd80c1d8676] postgres: postgres postgres [local] EXPLAIN(+0x61b1d7)[0x5cd80c1df1d7] postgres: postgres postgres [local] EXPLAIN(+0x6186cd)[0x5cd80c1dc6cd] postgres: postgres postgres [local] EXPLAIN(PostmasterMain+0x159e)[0x5cd80c1dbf97] postgres: postgres postgres [local] EXPLAIN(main+0x38c)[0x5cd80c072cca] /lib/x86_64-linux-gnu/libc.so.6(+0x29d90)[0x77c287829d90] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80)[0x77c287829e40] postgres: postgres postgres [local] EXPLAIN(_start+0x25)[0x5cd80bcaa2c5]