Thread

  1. 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]