Re: json/jsonb cleanup + FmgrInfo caching

From: shihao zhong <zhong950419(at)gmail(dot)com>
To: Manu <manuelreyesbravo(at)gmail(dot)com>
Cc: jian he <jian(dot)universality(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 01:36:20
Message-ID: CAGRkXqQz500QNGZrF36xu+VvoL9E3+FgyVvx8zW0f6jFnKM7iA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi Jian, Manu,

v3 with Manu's diff fixes my case, and all tests pass.

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.

Thanks,
Shihao

On Thu, Oct 22, 2026 at 11:51 AM Manu <manuelreyesbravo(at)gmail(dot)com> wrote:

> Hi Jian,
>
> On Thu, Oct 22, 2026 at 9:12 PM jian he
> <jian(dot)universality(at)gmail(dot)com> wrote:
> > The attached patch should resolve these issues.
>
> It does. v3 applies cleanly to master and REL_19_STABLE, and make
> check passes. Every case from my earlier matrix is now rejected at
> CREATE INDEX, as in 18: ADD / RENAME / DROP ATTRIBUTE, the table
> rowtype, nested composites, domains over composites, arrays of
> composites, JSON_OBJECT, RETURNING json, and the unique, partial,
> generated column and partition key forms. Anonymous ROW(), record[]
> and JSON_SCALAR are rejected too.
>
> One case still gets through, in the range branch. A range is printed
> by range_out, which calls the subtype's output function and never a
> cast to json. But when the range has no cast of its own,
> json_check_mutability() recurses into the subtype and judges the
> subtype's cast to json instead. So an immutable cast on an enum makes
> a range over that enum look immutable, while what actually prints it
> is enum_out:
>
> CREATE TYPE e AS ENUM ('a', 'b');
> CREATE FUNCTION e_json(e) RETURNS json IMMUTABLE LANGUAGE sql
> AS $$ SELECT '"x"'::json $$;
> CREATE CAST (e AS json) WITH FUNCTION e_json(e);
> CREATE TYPE er AS RANGE (subtype = e);
> CREATE TABLE t (v er);
> INSERT INTO t VALUES (er('a', 'b'));
> CREATE INDEX t_i ON t ((json_array(v returning jsonb)));
> ALTER TYPE e RENAME VALUE 'a' TO 'z';
> SELECT count(*) FROM t
> WHERE json_array(v returning jsonb) =
> json_array(er('z', 'b') returning jsonb);
>
> The index scan returns 0 and a seq scan returns 1; REINDEX restores 1.
> Without the cast on the enum the CREATE INDEX is rejected, and 18
> rejects it either way. The multirange behaves the same. Master has
> this without v3 as well.
>
> The attached diff, on top of v3, stops looking up casts once the
> recursion is below a range or multirange. With it both cases are
> rejected, nothing else in my matrix changes (int4range is still
> accepted), and make check passes. It's named .txt so it doesn't
> disturb the CF bot; feel free to fold it into v4 if you agree.
>
> regards,
> Manu
>

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Haibo Yan 2026-10-23 01:45:05 Re: [PATCH] Fix grouping-set nulling of variable-free grouping expressions
Previous Message shihao zhong 2026-10-23 01:33:14 Re: [PG19] Hash join writes null-keyed outer rows to temp files