From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
---|---|
To: | Maxim Orlov <orlovmg(at)gmail(dot)com> |
Cc: | "David G(dot) Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com>, Maciek Sakrejda <maciek(at)pganalyze(dot)com>, "pgsql-hackers(at)lists(dot)postgresql(dot)org" <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
Subject: | Re: Casts from jsonb to other types should cope with json null |
Date: | 2025-01-24 19:20:34 |
Message-ID: | 516618.1737746434@sss.pgh.pa.us |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
I wrote:
> OK. Nobody has spoken against the 0001 patch (replace errors with
> return-a-null), so I think I'll go ahead and commit that one.
> Then I'll return to this thread with a fleshed-out patch for 0002.
0001 is pushed, and as promised, here's a version of 0002 extended
to cover all the string-category types.
However ... the more I play with 0002, the less enchanted I get.
The problem is that there are two different use-cases to serve:
1. General conversion of any jsonb value to string form.
2. Conversion of a jsonb scalar string to a SQL string.
For use-case #1, it makes sense that we do
regression=# select '"hello"'::jsonb::text;
text
---------
"hello"
(1 row)
but for use-case #2, you'd probably prefer that the quotes
weren't included. (We can't do that in use-case #1 because
the string contents might look too much like some other
sort of JSON value.) So it seems like two separate conversion
functions are needed to serve these two use-cases, and for
better or worse we've already decided that casting jsonb to text
is meant for use-case #1. (It was sort of a decision by default,
I suspect, but not deciding is still a decision.)
What I am realizing is that "JSON null becomes SQL NULL" is a rule
that is adapted to use-case #2 but not so much to use-case #1.
For example, the existing behavior
regression=# select null::jsonb::text;
text
------
(1 row)
regression=# select 'null'::jsonb::text;
text
------
null
(1 row)
actually makes plenty of sense if you hope to be able to round-trip
the result. It's only after rejecting non-scalar JSON values that
it makes sense to special-case a JSON null.
So here's the patch, just because I promised it, but I'm now
thinking about withdrawing it.
What would make more sense for use-case #2 is something that
produces NULL for JSON null, a de-quoted string for a JSON
string value, and an error otherwise. The ->> operator is
about halfway there (it won't throw an error for non-scalar
input), but of course that only works when the value you want
to extract is in a JSON object field. I guess what would
be wanted is a new function f(jsonb) returns text, but I'm
unsure about a good name.
regards, tom lane
Attachment | Content-Type | Size |
---|---|---|
v2-0002-Make-jsonb-cast-to-text-translate-JSON-null-to-SQ.patch | text/x-diff | 6.6 KB |
From | Date | Subject | |
---|---|---|---|
Next Message | Andres Freund | 2025-01-24 19:23:26 | Re: BF member drongo doesn't like 035_standby_logical_decoding.pl |
Previous Message | Masahiko Sawada | 2025-01-24 19:16:18 | Re: POC: enable logical decoding when wal_level = 'replica' without a server restart |