Re: json/jsonb cleanup + FmgrInfo caching

From: jian he <jian(dot)universality(at)gmail(dot)com>
To: shihao zhong <zhong950419(at)gmail(dot)com>
Cc: Manu <manuelreyesbravo(at)gmail(dot)com>, Robert Haas <robertmhaas(at)gmail(dot)com>, pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: json/jsonb cleanup + FmgrInfo caching
Date: 2026-10-23 04:52:40
Message-ID: CACJufxER-VJzaH33HYzoU-Z4ZOd_iJCX9+3r5TLhcEEN=NS=fQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Fri, Oct 23, 2026 at 9:36 AM shihao zhong <zhong950419(at)gmail(dot)com> wrote:
>
> float8out is STABLE on master now, but v3 still lists FLOAT4OID
> and FLOAT8OID as immutable. So this is accepted:
>
> CREATE INDEX ON tf ((json_array(f returning jsonb))); -- f float8
>
> and gives wrong results after SET extra_float_digits = 0. Dropping
> those two case labels fixes it on master and changes nothing on 19.
>
Hi.

This issue is fixed.
Another old issue: indexes don't have dependency with CAST. Dropping a
user-defined cast will change the index definition.
Hopefully, the attached v4 fix should be bullet-proof.

Enums and composite types should be marked as mutable when casting to json or
jsonb. Because ALTER TYPE ... RENAME VALUE, ADD/DROP/RENAME ATTRIBUTE (and ALTER
TABLE on a table's row type) does not rebuilding dependent indexes.

user-defined range and multirange types as mutable too. Their conversion uses a
cast to json function if exists, looked up at runtime, so creating or dropping
such a cast after CREATE INDEX changes the output.
Built-in ranges are unaffected, see json_categorize_type DEFAULT branch code.

Below is a code demo for a user-defined range type.
-------------------------
DROP TABLE IF EXISTS tr;
DROP CAST IF EXISTS (myr AS json);
DROP FUNCTION IF EXISTS myr_json(myr);
DROP TYPE IF EXISTS myr;
CREATE TYPE myr AS RANGE (subtype = int);
CREATE TABLE tr (r myr) WITH (autovacuum_enabled = off);
INSERT INTO tr VALUES ('[1,3)');
-- no cast exists yet, so the index stores the range_out text
CREATE INDEX tr_idx ON tr ((json_array(r returning jsonb)));
CREATE FUNCTION myr_json(myr) RETURNS json IMMUTABLE LANGUAGE sql AS
$$ SELECT '{"1": "2"}'::json $$;
CREATE CAST (myr AS json) WITH FUNCTION myr_json(myr);
SET enable_seqscan = off;
SELECT count(*) FROM tr WHERE json_array(r returning jsonb) = '[{"1": "2"}]';
SET enable_indexscan = off;
SET enable_bitmapscan = off;
SELECT count(*) FROM tr WHERE json_array(r returning jsonb) = '[{"1": "2"}]';

Attachment Content-Type Size
v4-0001-Don-t-treat-record-json-b-conversions-as-immutable.txt text/plain 20.4 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Manu 2026-10-23 05:05:55 Re: [PG19] Promotion hangs behind a backend blocked on a stuck client
Previous Message Ziming Zhang 2026-10-23 04:15:25 [PATCH] Fix whole-row type errors in postgres_fdw UPDATE joins