Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jjMab-00020d-B8 for pgsql-hackers@arkaria.postgresql.org; Thu, 11 Jun 2020 12:45:49 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1jjMaY-0004xD-Pz for pgsql-hackers@arkaria.postgresql.org; Thu, 11 Jun 2020 12:45:46 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jjMaY-0004x6-JE for pgsql-hackers@lists.postgresql.org; Thu, 11 Jun 2020 12:45:46 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jjMaW-0002Dj-G4 for pgsql-hackers@lists.postgresql.org; Thu, 11 Jun 2020 12:45:45 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 05BCjgeP203950; Thu, 11 Jun 2020 08:45:43 -0400 From: Tom Lane To: Alexander Korotkov cc: pgsql-hackers@lists.postgresql.org Subject: jsonpath versus NaN MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <203948.1591879542.1@sss.pgh.pa.us> Content-Transfer-Encoding: quoted-printable Date: Thu, 11 Jun 2020 08:45:42 -0400 Message-ID: <203949.1591879542@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk 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 =3D 3; + break; + } + numlen =3D VARSIZE_ANY(scalarVal->val.numeric); padlen =3D 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. So it should be impossible for this code to do anything. I tried taking it out, and found that this test case from the same commit fails: +select jsonb_path_query('"nan"', '$.double()'); + jsonb_path_query = +------------------ + "NaN" +(1 row) However, seeing that the JSON RFC disallows NaNs, I do not understand why it's important to accept this. The adjacent test case showing that 'inf' isn't accepted: +select jsonb_path_query('"inf"', '$.double()'); +ERROR: non-numeric SQL/JSON item +DETAIL: jsonpath item method .double() can only be applied to a numeric = value seems like a saner approach. In short, I think we should rip out the above code snippet and adjust executeItemOptUnwrapTarget, at about line jsonpath_exec.c:1076 as of HEAD, to reject NaNs the same way it already rejects infinities. Can you explain why it was done like this? (The reason I came across this was that I'm working on extending type numeric to allow infinities, and it was not clear what to do here. But allowing a jsonb to contain a numeric NaN, even transiently, seems like a completely horrid idea.) regards, tom lane