Re: crash in ltree_compare_distance() in 14.24

From: Chris St Denis <chris(at)ctgameinfo(dot)com>
To: David Geier <geidav(dot)pg(at)gmail(dot)com>, pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: crash in ltree_compare_distance() in 14.24
Date: 2026-10-27 19:04:55
Message-ID: 3527d5c4-0ce4-4412-b433-2e1d36517139@ctgameinfo.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

On 2026-10-27 2:24 a.m., David Geier wrote:
> Hi Chris!
>
>> I don't have it compiled with debug, and when I recompile and try the
>> old core I get corrupted stack, but hopefully you can make some use of
>> this data as is.
> Can you reproduce this and share the steps?
>
> In case you cannot reproduce it, can you share at least the query you
> were running and the relevant parts of the schema?

It happened in the middle of the night, has not happened since.

The ltree column id_tree contains a ltree of comment ID's showing the
tree of comment replies.

Logs show this

 2026-10-26 02:26:35.914 PDT [61206] LOG:  server process (PID
50023) was terminated by signal 11: Segmentation fault
 2026-10-26 02:26:35.914 PDT [61206] DETAIL:  Failed process was
running: INSERT INTO "story_comments" ("comment", "reply_to",
"deleted", "id_tree", "sid", "user_id", "ipaddr") VALUES ($1, $2,
$3, $4, $5, $6, $7)

Due to parameterised queries, I do not have the data values that were
inserted.

Here is the table structure.

   database=# \d story_comments
                                             Table
"public.story_comments"
    Column    |            Type             | Collation | Nullable
|                      Default
--------------+-----------------------------+-----------+----------+----------------------------------------------------
 comment_id   | integer                     |           | not null
| nextval('story_comments_comment_id_seq'::regclass)
 user_id      | integer                     |           | not null |
 comment      | text                        |           | not null
| ''::text
 comment_date | timestamp without time zone |           | not null
| now()
 ipaddr       | inet                        |           | not null |
 reply_to     | integer                     |           | not null | 0
 deleted      | smallint                    |           | not null | 0
 id_tree      | ltree                       |           | not null
| ''::ltree
 reply_date   | timestamp with time zone    |           |   | now()
 sid          | integer                     |           | not null |
 chapter      | integer                     |           | not null | 0
Indexes:
    "story_comments_pkey" PRIMARY KEY, btree (comment_id)
    "idx_story_comments_comment_date" btree (comment_date)
    "idx_story_comments_sid" btree (sid) CLUSTER
    "idx_story_comments_user_id" btree (user_id)
    "story_comments_undeleted" gist (id_tree, sid) WHERE deleted = 0
Foreign-key constraints:
    "story_comments_sid_fkey" FOREIGN KEY (sid) REFERENCES stories(sid)
    "story_comments_sid_fkey1" FOREIGN KEY (sid) REFERENCES
stories(sid)
    "story_comments_user_id_fkey" FOREIGN KEY (user_id) REFERENCES
users(user_id)
    "story_comments_user_id_fkey1" FOREIGN KEY (user_id) REFERENCES
users(user_id)
Triggers:
    update_story_comments_count BEFORE INSERT OR DELETE ON
story_comments FOR EACH ROW EXECUTE FUNCTION
update_story_comments_count()
    update_story_comments_ltree AFTER INSERT ON story_comments FOR
EACH ROW EXECUTE FUNCTION update_story_comment_ltrees()
    update_story_comments_reply_date AFTER INSERT ON story_comments
FOR EACH ROW EXECUTE FUNCTION update_comments_reply_date('story')
    update_user_comments_count BEFORE INSERT OR DELETE ON
story_comments FOR EACH ROW EXECUTE FUNCTION
update_user_comments_count()
Inherits: base_comments

database=# \d base_comments
                                             Table
"public.base_comments"
    Column    |            Type             | Collation | Nullable
|                      Default
--------------+-----------------------------+-----------+----------+---------------------------------------------------
 comment_id   | integer                     |           | not null
| nextval('base_comments_comment_id_seq'::regclass)
 user_id      | integer                     |           | not null |
 comment      | text                        |           | not null
| ''::text
 comment_date | timestamp without time zone |           | not null
| now()
 ipaddr       | inet                        |           | not null |
 reply_to     | integer                     |           | not null | 0
 deleted      | smallint                    |           | not null | 0
 id_tree      | ltree                       |           | not null
| ''::ltree
 reply_date   | timestamp with time zone    |           |   | now()
Indexes:
    "base_comments_pkey" PRIMARY KEY, btree (comment_id)
Foreign-key constraints:
    "base_comments_user_id_fkey" FOREIGN KEY (user_id) REFERENCES
users(user_id)
Number of child tables: 4 (Use \d+ to list them.)

database=# \sf update_story_comment_ltrees
CREATE OR REPLACE FUNCTION public.update_story_comment_ltrees()
 RETURNS trigger
 LANGUAGE plpgsql
AS $function$BEGIN
    PERFORM generate_story_comment_ltrees(NEW.comment_id);
    return NEW;
END;$function$

database=# \sf generate_story_comment_ltrees
CREATE OR REPLACE FUNCTION public.generate_story_comment_ltrees(c
integer)
 RETURNS character varying
 LANGUAGE plpgsql
AS $function$DECLARE
    id_hier text = '';
    myrec RECORD;
BEGIN
    SELECT INTO myrec reply_to, comment_id from story_comments
where comment_id = c;
    IF NOT FOUND THEN
        RAISE EXCEPTION 'comment % not found', c;
        return '';
    END IF;

    LOOP
        IF id_hier != '' THEN
            id_hier := myrec.comment_id || '.' || id_hier;
        ELSE
            id_hier := myrec.comment_id;
        END IF;

--      RAISE NOTICE 'id_hier %  reply_to %', id_hier, myrec.reply_to;

        EXIT WHEN myrec.reply_to = 0;
        SELECT INTO myrec reply_to, comment_id from story_comments
where comment_id = myrec.reply_to;
        IF NOT FOUND THEN
            RAISE NOTICE 'Comment % reply_to % not found', c,
myrec.reply_to;
            RAISE EXCEPTION '';
            return '';
        END IF;
    END LOOP;

--    RAISE NOTICE 'id_hier %', id_hier;
    update story_comments set id_tree=text2ltree(id_hier) where
comment_id = c and id_tree != text2ltree(id_hier);
    return id_hier;

    return null;
END;$function$

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message BHUVAN CHILUKUTI 2026-10-27 19:32:31 Assertion failure in dependencies_clauselist_selectivity with two clauses on the same statistics expression
Previous Message Kirill Reshke 2026-10-27 17:36:39 Re: BUG #19795: pgoutput: walsender crashes on START_REPLICATION option without a value