On 21.03.2019 16:58, Alexander Korotkov wrote:
On Tue, Mar 19, 2019 at 8:10 PM Alexander Korotkov <a.korot...@postgrespro.ru> wrote: Attaches patches improving jsonpath parser. First one introduces cosmetic changes, while second gets rid of backtracking. I'm also planning to add high-level comment for both grammar and lexer.
Parsing of integers now is wrong: neither JSON specification, nor our json[b] allow leading zeros in integers and floats starting with a dot. =# SELECT json '.1'; ERROR: invalid input syntax for type json LINE 1: SELECT jsonb '.1'; ^ DETAIL: Token "." is invalid. CONTEXT: JSON data, line 1: .... =# SELECT json '00'; ERROR: invalid input syntax for type json LINE 1: SELECT jsonb '00'; ^ DETAIL: Token "00" is invalid. CONTEXT: JSON data, line 1: 00 =# SELECT json '00.1'; ERROR: invalid input syntax for type json LINE 1: SELECT jsonb '00.1'; ^ DETAIL: Token "00" is invalid. CONTEXT: JSON data, line 1: 00... In JavaScript integers with leading zero are treated as octal numbers, but leading dot is a allowed: v8 > 0123 83 v8 > 000.1 Uncaught SyntaxError: Unexpected number v8> .1 0.1 Attached patch 0003 fixes this issue. -- Nikita Glukhov Postgres Professional: http://www.postgrespro.com The Russian Postgres Company
>From 5b0844d77f4fe65d666072356f7c0e42d13c9a63 Mon Sep 17 00:00:00 2001 From: Nikita Glukhov <n.glu...@postgrespro.ru> Date: Fri, 22 Mar 2019 14:38:46 +0300 Subject: [PATCH 3/3] Fix parsing of numbers in jsonpath --- src/backend/utils/adt/jsonpath_scan.l | 6 +- src/test/regress/expected/jsonpath.out | 117 +++++++++++++++------------------ 2 files changed, 55 insertions(+), 68 deletions(-) diff --git a/src/backend/utils/adt/jsonpath_scan.l b/src/backend/utils/adt/jsonpath_scan.l index 844ea5e..a6b67ea 100644 --- a/src/backend/utils/adt/jsonpath_scan.l +++ b/src/backend/utils/adt/jsonpath_scan.l @@ -77,9 +77,9 @@ any [^\?\%\$\.\[\]\{\}\(\)\|\&\!\=\<\>\@\#\,\*:\-\+\/\\\"\' \t\n\r\f] blank [ \t\n\r\f] digit [0-9] -integer {digit}+ -decimal {digit}*\.{digit}+ -decimalfail {digit}+\. +integer (0|[1-9]{digit}*) +decimal {integer}\.{digit}+ +decimalfail {integer}\. real ({integer}|{decimal})[Ee][-+]?{digit}+ realfail1 ({integer}|{decimal})[Ee] realfail2 ({integer}|{decimal})[Ee][-+] diff --git a/src/test/regress/expected/jsonpath.out b/src/test/regress/expected/jsonpath.out index b7de491..a99643f 100644 --- a/src/test/regress/expected/jsonpath.out +++ b/src/test/regress/expected/jsonpath.out @@ -547,23 +547,20 @@ select '$ ? (@.a < +1)'::jsonpath; (1 row) select '$ ? (@.a < .1)'::jsonpath; - jsonpath ------------------ - $?(@."a" < 0.1) -(1 row) - +ERROR: bad jsonpath representation +LINE 1: select '$ ? (@.a < .1)'::jsonpath; + ^ +DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < -.1)'::jsonpath; - jsonpath ------------------- - $?(@."a" < -0.1) -(1 row) - +ERROR: bad jsonpath representation +LINE 1: select '$ ? (@.a < -.1)'::jsonpath; + ^ +DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < +.1)'::jsonpath; - jsonpath ------------------ - $?(@."a" < 0.1) -(1 row) - +ERROR: bad jsonpath representation +LINE 1: select '$ ? (@.a < +.1)'::jsonpath; + ^ +DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < 0.1)'::jsonpath; jsonpath ----------------- @@ -619,23 +616,20 @@ select '$ ? (@.a < +1e1)'::jsonpath; (1 row) select '$ ? (@.a < .1e1)'::jsonpath; - jsonpath ---------------- - $?(@."a" < 1) -(1 row) - +ERROR: bad jsonpath representation +LINE 1: select '$ ? (@.a < .1e1)'::jsonpath; + ^ +DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < -.1e1)'::jsonpath; - jsonpath ----------------- - $?(@."a" < -1) -(1 row) - +ERROR: bad jsonpath representation +LINE 1: select '$ ? (@.a < -.1e1)'::jsonpath; + ^ +DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < +.1e1)'::jsonpath; - jsonpath ---------------- - $?(@."a" < 1) -(1 row) - +ERROR: bad jsonpath representation +LINE 1: select '$ ? (@.a < +.1e1)'::jsonpath; + ^ +DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < 0.1e1)'::jsonpath; jsonpath --------------- @@ -691,23 +685,20 @@ select '$ ? (@.a < +1e-1)'::jsonpath; (1 row) select '$ ? (@.a < .1e-1)'::jsonpath; - jsonpath ------------------- - $?(@."a" < 0.01) -(1 row) - +ERROR: bad jsonpath representation +LINE 1: select '$ ? (@.a < .1e-1)'::jsonpath; + ^ +DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < -.1e-1)'::jsonpath; - jsonpath -------------------- - $?(@."a" < -0.01) -(1 row) - +ERROR: bad jsonpath representation +LINE 1: select '$ ? (@.a < -.1e-1)'::jsonpath; + ^ +DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < +.1e-1)'::jsonpath; - jsonpath ------------------- - $?(@."a" < 0.01) -(1 row) - +ERROR: bad jsonpath representation +LINE 1: select '$ ? (@.a < +.1e-1)'::jsonpath; + ^ +DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < 0.1e-1)'::jsonpath; jsonpath ------------------ @@ -763,23 +754,20 @@ select '$ ? (@.a < +1e+1)'::jsonpath; (1 row) select '$ ? (@.a < .1e+1)'::jsonpath; - jsonpath ---------------- - $?(@."a" < 1) -(1 row) - +ERROR: bad jsonpath representation +LINE 1: select '$ ? (@.a < .1e+1)'::jsonpath; + ^ +DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < -.1e+1)'::jsonpath; - jsonpath ----------------- - $?(@."a" < -1) -(1 row) - +ERROR: bad jsonpath representation +LINE 1: select '$ ? (@.a < -.1e+1)'::jsonpath; + ^ +DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < +.1e+1)'::jsonpath; - jsonpath ---------------- - $?(@."a" < 1) -(1 row) - +ERROR: bad jsonpath representation +LINE 1: select '$ ? (@.a < +.1e+1)'::jsonpath; + ^ +DETAIL: syntax error, unexpected '.' at or near "." select '$ ? (@.a < 0.1e+1)'::jsonpath; jsonpath --------------- @@ -823,11 +811,10 @@ select '0'::jsonpath; (1 row) select '00'::jsonpath; - jsonpath ----------- - 0 -(1 row) - +ERROR: bad jsonpath representation +LINE 1: select '00'::jsonpath; + ^ +DETAIL: syntax error, unexpected IDENT_P at end of input select '0.0'::jsonpath; jsonpath ---------- -- 2.7.4