| 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 |
| 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 |