Re: jsonpath versus NaN
Alexander Korotkov <a.korotkov@postgrespro.ru>
From: Alexander Korotkov <a.korotkov@postgrespro.ru>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2020-06-11T18:41:00Z
Lists: pgsql-hackers
Hi Tom,
Thank you for raising this issue.
On Thu, Jun 11, 2020 at 3:45 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Commit 72b646033 inserted this into convertJsonbScalar:
>
> break;
>
> case jbvNumeric:
> + /* replace numeric NaN with string "NaN" */
> + if (numeric_is_nan(scalarVal->val.numeric))
> + {
> + appendToBuffer(buffer, "NaN", 3);
> + *jentry = 3;
> + break;
> + }
> +
> numlen = VARSIZE_ANY(scalarVal->val.numeric);
> padlen = padBufferToInt(buffer);
>
> To characterize this as hack, slash, and burn programming would be
> charitable. It is entirely clear from the code, the documentation,
> and the relevant RFCs that JSONB does not allow NaNs as numeric
> values.
The JSONB itself doesn't store number NaNs. It stores the string "NaN".
I found the relevant part of the standard. Unfortunately, I can't
post the full standard here due to its license, but I think I can cite
the relevant part.
1) If JM specifies double, then For all j, 1 (one) ≤ j ≤ n,
Case:
a) If Ij is not a number or character string, then let ST be data
exception — non-numeric SQL/JSON item.
b) Otherwise, let X be an SQL variable whose value is Ij. Let Vj be
the result of
CAST (X AS DOUBLE PRECISION)
If this conversion results in an exception condition, then let ST be
that exception condition.
So, when we apply the .double() method to string, then the result
should be the same as if we cast string to double in SQL. In SQL we
convert string 'NaN' to numeric NaN. So, standard requires us to do
the same in SQL/JSON.
I didn't find yet what the standard says about serializing NaNs back
to JSON. I'll keep you posted.
------
Alexander Korotkov
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company
Commits
-
Forbid numeric NaN in jsonpath
- f4ae676e3178 12.4 landed
- 89a0b1a7ca0a 13.0 landed
- df646509f371 14.0 landed
-
Improve error reporting for jsonpath .double() method
- 3ec5f6b53dfb 12.4 landed
- b9a04a9bc665 13.0 landed
- 065718116746 14.0 landed
-
Partial implementation of SQL/JSON path language
- 72b6460336e8 12.0 cited