BUG #18830: ExecInitMerge Segfault on MERGE

PG Bug reporting form <noreply@postgresql.org>

From: PG Bug reporting form <noreply@postgresql.org>
To: pgsql-bugs@lists.postgresql.org
Cc: tharakan@gmail.com
Date: 2025-03-02T21:00:30Z
Lists: pgsql-bugs
The following bug has been logged on the website:

Bug reference:      18830
Logged by:          Robins Tharakan
Email address:      tharakan@gmail.com
PostgreSQL version: Unsupported/Unknown
Operating system:   Ubuntu
Description:        

With this SQL (backtraces below), postgres starts to segfault starting at
cbc127917e.


SQL
===
CREATE AGGREGATE d(double precision ORDER BY anyelement) (
    SFUNC = ordered_set_transition_multi,
    STYPE = internal,
    FINALFUNC = rank_final);
CREATE TABLE e (
    a text,
    b integer
) PARTITION BY LIST (a);
CREATE TABLE f (
    a text,
    b integer
);
CREATE TABLE g (
    a text,
    b integer
);
CREATE VIEW h AS
 SELECT XMLSERIALIZE(DOCUMENT '<foo><bar>42</bar></foo>'AS text );
ALTER TABLE e ATTACH PARTITION f FOR VALUES IN ('a');
ALTER TABLE e ATTACH PARTITION g FOR VALUES IN ('b');

MERGE INTO e  USING h  ON a = xmlserialize WHEN NOT MATCHED THEN INSERT
VALUES (CAST(NULL AS text));


SQL Output
==========
$ psql -p 9999 postgres -f ../sqith/repro_final.sql
CREATE AGGREGATE
CREATE TABLE
CREATE TABLE
CREATE TABLE
CREATE VIEW
ALTER TABLE
ALTER TABLE
psql:../sqith/repro_final.sql:25: server closed the connection
unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
psql:../sqith/repro_final.sql:25: error: connection to server was lost



Error Log
=========
2025-03-03 06:55:54.014 ACDT [137463] LOG:  client backend (PID 137479) was
terminated by signal 11: Segmentation fault
2025-03-03 06:55:54.014 ACDT [137463] DETAIL:  Failed process was running:
MERGE INTO e  USING h  ON a = xmlserialize WHEN NOT MATCHED THEN INSERT
VALUES (CAST(NULL AS text));
2025-03-03 06:55:54.014 ACDT [137463] LOG:  terminating any other active
server processes


Commit
======
Checking (15a79c73111~0) - 15a79c7311 - fail
Checking (15a79c73111~10) - 424ededc58 - fail
Checking (15a79c73111~30) - 945a9e3832 - fail
Checking (15a79c73111~70) - a4e986ef5a - fail
Checking (15a79c73111~150) - 6a2275b895 - fail
Checking (15a79c73111~310) - 117f9f328e - Pass
Checking (15a79c73111~230) - c89525d57b - Pass
Checking (15a79c73111~190) - c366d2bdba - fail
Checking (15a79c73111~210) - fb056564ec - fail
Checking (15a79c73111~220) - 44ec095751 - Pass
Checking (15a79c73111~215) - cbc127917e - fail
Checking (15a79c73111~217) - 428fadb7e9 - Pass
Checking (15a79c73111~216) - 926c7fce03 - Pass
Offending Commit is cbc127917e - HEAD~215


BackTrace
=========
(gdb) bt
#0  ExecInitMerge (mtstate=0x599c6b260330, estate=0x599c6b260080) at
nodeModifyTable.c:3663
#1  0x0000599c2ca1ce11 in ExecInitModifyTable (node=0x599c6b282e08,
estate=0x599c6b260080, eflags=0) at nodeModifyTable.c:4889
#2  0x0000599c2c9d63a3 in ExecInitNode (node=0x599c6b282e08,
estate=0x599c6b260080, eflags=0) at execProcnode.c:177
#3  0x0000599c2c9cac66 in InitPlan (queryDesc=0x599c6b218ba0, eflags=0) at
execMain.c:985
#4  0x0000599c2c9c99f0 in standard_ExecutorStart (queryDesc=0x599c6b218ba0,
eflags=0) at execMain.c:259
#5  0x0000599c2c9c96fb in ExecutorStart (queryDesc=0x599c6b218ba0, eflags=0)
at execMain.c:135
#6  0x0000599c2ccb3925 in ProcessQuery (plan=0x599c6b284188,
    sourceText=0x599c6b16c4e0 "MERGE INTO e  USING h  ON a = xmlserialize
WHEN NOT MATCHED THEN INSERT VALUES (CAST(NULL AS text));", params=0x0,
queryEnv=0x0, dest=0x599c6b284308,
    qc=0x7ffc8bc1aaf0) at pquery.c:155
#7  0x0000599c2ccb546e in PortalRunMulti (portal=0x599c6b1ef0a0,
isTopLevel=true, setHoldSnapshot=false, dest=0x599c6b284308,
altdest=0x599c6b284308, qc=0x7ffc8bc1aaf0)
    at pquery.c:1271
#8  0x0000599c2ccb497a in PortalRun (portal=0x599c6b1ef0a0,
count=9223372036854775807, isTopLevel=true, dest=0x599c6b284308,
altdest=0x599c6b284308, qc=0x7ffc8bc1aaf0) at pquery.c:787
#9  0x0000599c2ccad440 in exec_simple_query (query_string=0x599c6b16c4e0
"MERGE INTO e  USING h  ON a = xmlserialize WHEN NOT MATCHED THEN INSERT
VALUES (CAST(NULL AS text));")
    at postgres.c:1271
#10 0x0000599c2ccb27ef in PostgresMain (dbname=0x599c6b1a6680 "smithreduce",
username=0x599c6b1a6668 "smith") at postgres.c:4691



BackTrace Full
==============
#0  ExecInitMerge (mtstate=0x599c6b260330, estate=0x599c6b260080) at
nodeModifyTable.c:3663
        mergeActionList = 0x599c6b281b70
        joinCondition = 0x0
        relationDesc = 0x599c2c9df7cb <ExecTypeFromTL+33>
        l = 0x100000000
        lc__state = {l = 0x599c6b281bc0, i = 0}
        node = 0x599c6b282e08
        rootRelInfo = 0x599c6b260f98
        resultRelInfo = 0x599c6b260f80
        econtext = 0x599c6b2695f8
        lc = 0x599c6b281bd8
        i = 1
        __func__ = "ExecInitMerge"
#1  0x0000599c2ca1ce11 in ExecInitModifyTable (node=0x599c6b282e08,
estate=0x599c6b260080, eflags=0) at nodeModifyTable.c:4889
        mtstate = 0x599c6b260330
        subplan = 0x599c6b282d78
        operation = CMD_MERGE
        nrels = 0
        resultRelations = 0x0
        withCheckOptionLists = 0x0
        returningLists = 0x0
        updateColnosLists = 0x0
        resultRelInfo = 0x599c6b260f80
        arowmarks = 0x0
        l = 0x0
        i = 0
        rel = 0x7be2ba49e368
        __func__ = "ExecInitModifyTable"
#2  0x0000599c2c9d63a3 in ExecInitNode (node=0x599c6b282e08,
estate=0x599c6b260080, eflags=0) at execProcnode.c:177
        result = 0x0
        subps = 0x599c6b282760
        l = 0x599c6b2608c0
        __func__ = "ExecInitNode"
#3  0x0000599c2c9cac66 in InitPlan (queryDesc=0x599c6b218ba0, eflags=0) at
execMain.c:985
        operation = CMD_MERGE
        plannedstmt = 0x599c6b284188
        plan = 0x599c6b282e08
        rangeTable = 0x599c6b283228
        estate = 0x599c6b260080
        planstate = 0x599c6b1ab310
        tupType = 0x599c6b2011f0
        l = 0x0
        i = 1
        __func__ = "InitPlan"


This (and bug #18828) found using SQLSmith / SQLReduce / creduce.

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Ensure first ModifyTable rel initialized if all are pruned

  2. Don't lock partitions pruned by initial pruning

  3. Fix an oversight in cbc127917 to handle MERGE correctly

  4. Remove some unnecessary fields from Plan trees.