From 30ac6f0fe912a22e6ed01bea7842369a6575aed1 Mon Sep 17 00:00:00 2001 From: Hanefi Onaldi Date: Fri, 23 Sep 2022 15:21:53 +0300 Subject: [PATCH] Add tests for jsonpath changes on PG15 PostgreSQL 15 had some changes to jsonpath to conform with ECMA-262 referenced by SQL standard. This commit adds tests to make sure Citus also supports the same standards. Relevant pg commit: e26114c817b610424010cfbe91a743f591246ff1 --- src/test/regress/expected/pg15_jsonpath.out | 409 ++++++++++++++++++ src/test/regress/expected/pg15_jsonpath_0.out | 10 + src/test/regress/multi_schedule | 2 +- src/test/regress/sql/pg15_jsonpath.sql | 236 ++++++++++ 4 files changed, 656 insertions(+), 1 deletion(-) create mode 100644 src/test/regress/expected/pg15_jsonpath.out create mode 100644 src/test/regress/expected/pg15_jsonpath_0.out create mode 100644 src/test/regress/sql/pg15_jsonpath.sql diff --git a/src/test/regress/expected/pg15_jsonpath.out b/src/test/regress/expected/pg15_jsonpath.out new file mode 100644 index 000000000..335a7fbba --- /dev/null +++ b/src/test/regress/expected/pg15_jsonpath.out @@ -0,0 +1,409 @@ +-- +-- PG15 jsonpath tests +-- Relevant pg commit: e26114c817b610424010cfbe91a743f591246ff1 +-- +SHOW server_version \gset +SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15 +\gset +\if :server_version_ge_15 +\else +\q +\endif +CREATE SCHEMA jsonpath; +SET search_path TO jsonpath; +CREATE TABLE jsonpath_test (id serial, sample text); +SELECT create_distributed_table('jsonpath_test', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +\COPY jsonpath_test(sample) FROM STDIN +-- Cast the text into jsonpath on the worker nodes. +SELECT sample, sample::jsonpath FROM jsonpath_test ORDER BY id; + sample | sample +--------------------------------------------------------------------- + $ | $ + strict $ | strict $ + lax $ | $ + $.a | $."a" + $.a.v | $."a"."v" + $.a.* | $."a".* + $.*[*] | $.*[*] + $.a[*] | $."a"[*] + $.a[*][*] | $."a"[*][*] + $[*] | $[*] + $[0] | $[0] + $[*][0] | $[*][0] + $[*].a | $[*]."a" + $[*][0].a.b | $[*][0]."a"."b" + $.a.**.b | $."a".**."b" + $.a.**{2}.b | $."a".**{2}."b" + $.a.**{2 to 2}.b | $."a".**{2}."b" + $.a.**{2 to 5}.b | $."a".**{2 to 5}."b" + $.a.**{0 to 5}.b | $."a".**{0 to 5}."b" + $.a.**{5 to last}.b | $."a".**{5 to last}."b" + $.a.**{last}.b | $."a".**{last}."b" + $.a.**{last to 5}.b | $."a".**{last to 5}."b" + $+1 | ($ + 1) + $-1 | ($ - 1) + $--+1 | ($ - -1) + $.a/+-1 | ($."a" / -1) + 1 * 2 + 4 % -3 != false | (1 * 2 + 4 % -3 != false) + $.g ? ($.a == 1) | $."g"?($."a" == 1) + $.g ? (@ == 1) | $."g"?(@ == 1) + $.g ? (@.a == 1) | $."g"?(@."a" == 1) + $.g ? (@.a == 1 || @.a == 4) | $."g"?(@."a" == 1 || @."a" == 4) + $.g ? (@.a == 1 && @.a == 4) | $."g"?(@."a" == 1 && @."a" == 4) + $.g ? (@.a == 1 || @.a == 4 && @.b == 7) | $."g"?(@."a" == 1 || @."a" == 4 && @."b" == 7) + $.g ? (@.a == 1 || !(@.a == 4) && @.b == 7) | $."g"?(@."a" == 1 || !(@."a" == 4) && @."b" == 7) + $.g ? (@.a == 1 || !(@.x >= 123 || @.a == 4) && @.b == 7) | $."g"?(@."a" == 1 || !(@."x" >= 123 || @."a" == 4) && @."b" == 7) + $.g ? (@.x >= @[*]?(@.a > "abc")) | $."g"?(@."x" >= @[*]?(@."a" > "abc")) + $.g ? ((@.x >= 123 || @.a == 4) is unknown) | $."g"?((@."x" >= 123 || @."a" == 4) is unknown) + $.g ? (exists (@.x)) | $."g"?(exists (@."x")) + $.g ? (exists (@.x ? (@ == 14))) | $."g"?(exists (@."x"?(@ == 14))) + $.g ? ((@.x >= 123 || @.a == 4) && exists (@.x ? (@ == 14))) | $."g"?((@."x" >= 123 || @."a" == 4) && exists (@."x"?(@ == 14))) + $.g ? (+@.x >= +-(+@.a + 2)) | $."g"?(+@."x" >= +(-(+@."a" + 2))) + $a | $"a" + $a.b | $"a"."b" + $a[*] | $"a"[*] + $.g ? (@.zip == $zip) | $."g"?(@."zip" == $"zip") + $.a[1,2, 3 to 16] | $."a"[1,2,3 to 16] + $.a[$a + 1, ($b[*]) to -($[0] * 2)] | $."a"[$"a" + 1,$"b"[*] to -($[0] * 2)] + $.a[$.a.size() - 3] | $."a"[$."a".size() - 3] + "last" | "last" + $.last | $."last" + $[last] | $[last] + $[$[0] ? (last > 0)] | $[$[0]?(last > 0)] + null.type() | null.type() + (1).type() | (1).type() + 1.2.type() | (1.2).type() + "aaa".type() | "aaa".type() + true.type() | true.type() + $.double().floor().ceiling().abs() | $.double().floor().ceiling().abs() + $.keyvalue().key | $.keyvalue()."key" + $.datetime() | $.datetime() + $.datetime("datetime template") | $.datetime("datetime template") + $ ? (@ starts with "abc") | $?(@ starts with "abc") + $ ? (@ starts with $var) | $?(@ starts with $"var") + $ ? (@ like_regex "pattern") | $?(@ like_regex "pattern") + $ ? (@ like_regex "pattern" flag "") | $?(@ like_regex "pattern") + $ ? (@ like_regex "pattern" flag "i") | $?(@ like_regex "pattern" flag "i") + $ ? (@ like_regex "pattern" flag "is") | $?(@ like_regex "pattern" flag "is") + $ ? (@ like_regex "pattern" flag "isim") | $?(@ like_regex "pattern" flag "ism") + $ ? (@ like_regex "pattern" flag "q") | $?(@ like_regex "pattern" flag "q") + $ ? (@ like_regex "pattern" flag "iq") | $?(@ like_regex "pattern" flag "iq") + $ ? (@ like_regex "pattern" flag "smixq") | $?(@ like_regex "pattern" flag "ismxq") + $ < 1 | ($ < 1) + ($ < 1) || $.a.b <= $x | ($ < 1 || $."a"."b" <= $"x") + ($).a.b | $."a"."b" + ($.a.b).c.d | $."a"."b"."c"."d" + ($.a.b + -$.x.y).c.d | ($."a"."b" + -$."x"."y")."c"."d" + (-+$.a.b).c.d | (-(+$."a"."b"))."c"."d" + 1 + ($.a.b + 2).c.d | (1 + ($."a"."b" + 2)."c"."d") + 1 + ($.a.b > 2).c.d | (1 + ($."a"."b" > 2)."c"."d") + ($) | $ + (($)) | $ + ((($ + 1)).a + ((2)).b ? ((((@ > 1)) || (exists(@.c))))) | (($ + 1)."a" + (2)."b"?(@ > 1 || exists (@."c"))) + $ ? (@.a < 1) | $?(@."a" < 1) + $ ? (@.a < -1) | $?(@."a" < -1) + $ ? (@.a < +1) | $?(@."a" < 1) + $ ? (@.a < .1) | $?(@."a" < 0.1) + $ ? (@.a < -.1) | $?(@."a" < -0.1) + $ ? (@.a < +.1) | $?(@."a" < 0.1) + $ ? (@.a < 0.1) | $?(@."a" < 0.1) + $ ? (@.a < -0.1) | $?(@."a" < -0.1) + $ ? (@.a < +0.1) | $?(@."a" < 0.1) + $ ? (@.a < 10.1) | $?(@."a" < 10.1) + $ ? (@.a < -10.1) | $?(@."a" < -10.1) + $ ? (@.a < +10.1) | $?(@."a" < 10.1) + $ ? (@.a < 1e1) | $?(@."a" < 10) + $ ? (@.a < -1e1) | $?(@."a" < -10) + $ ? (@.a < +1e1) | $?(@."a" < 10) + $ ? (@.a < .1e1) | $?(@."a" < 1) + $ ? (@.a < -.1e1) | $?(@."a" < -1) + $ ? (@.a < +.1e1) | $?(@."a" < 1) + $ ? (@.a < 0.1e1) | $?(@."a" < 1) + $ ? (@.a < -0.1e1) | $?(@."a" < -1) + $ ? (@.a < +0.1e1) | $?(@."a" < 1) + $ ? (@.a < 10.1e1) | $?(@."a" < 101) + $ ? (@.a < -10.1e1) | $?(@."a" < -101) + $ ? (@.a < +10.1e1) | $?(@."a" < 101) + $ ? (@.a < 1e-1) | $?(@."a" < 0.1) + $ ? (@.a < -1e-1) | $?(@."a" < -0.1) + $ ? (@.a < +1e-1) | $?(@."a" < 0.1) + $ ? (@.a < .1e-1) | $?(@."a" < 0.01) + $ ? (@.a < -.1e-1) | $?(@."a" < -0.01) + $ ? (@.a < +.1e-1) | $?(@."a" < 0.01) + $ ? (@.a < 0.1e-1) | $?(@."a" < 0.01) + $ ? (@.a < -0.1e-1) | $?(@."a" < -0.01) + $ ? (@.a < +0.1e-1) | $?(@."a" < 0.01) + $ ? (@.a < 10.1e-1) | $?(@."a" < 1.01) + $ ? (@.a < -10.1e-1) | $?(@."a" < -1.01) + $ ? (@.a < +10.1e-1) | $?(@."a" < 1.01) + $ ? (@.a < 1e+1) | $?(@."a" < 10) + $ ? (@.a < -1e+1) | $?(@."a" < -10) + $ ? (@.a < +1e+1) | $?(@."a" < 10) + $ ? (@.a < .1e+1) | $?(@."a" < 1) + $ ? (@.a < -.1e+1) | $?(@."a" < -1) + $ ? (@.a < +.1e+1) | $?(@."a" < 1) + $ ? (@.a < 0.1e+1) | $?(@."a" < 1) + $ ? (@.a < -0.1e+1) | $?(@."a" < -1) + $ ? (@.a < +0.1e+1) | $?(@."a" < 1) + $ ? (@.a < 10.1e+1) | $?(@."a" < 101) + $ ? (@.a < -10.1e+1) | $?(@."a" < -101) + $ ? (@.a < +10.1e+1) | $?(@."a" < 101) + 0 | 0 + 0.0 | 0.0 + 0.000 | 0.000 + 0.000e1 | 0.00 + 0.000e2 | 0.0 + 0.000e3 | 0 + 0.0010 | 0.0010 + 0.0010e-1 | 0.00010 + 0.0010e+1 | 0.010 + 0.0010e+2 | 0.10 + .001 | 0.001 + .001e1 | 0.01 + 1. | 1 + 1.e1 | 10 + 1.2.e | (1.2)."e" + (1.2).e | (1.2)."e" + 1e3 | 1000 + 1.e3 | 1000 + 1.e3.e | (1000)."e" + 1.e3.e4 | (1000)."e4" + 1.2e3 | 1200 + 1.2.e3 | (1.2)."e3" + (1.2).e3 | (1.2)."e3" + 1..e | (1)."e" + 1..e3 | (1)."e3" + (1.).e | (1)."e" + (1.).e3 | (1)."e3" + 1?(2>3) | (1)?(2 > 3) +(158 rows) + +-- Pull the data, and cast on the coordinator node +WITH samples as (SELECT id, sample FROM jsonpath_test OFFSET 0) +SELECT sample, sample::jsonpath FROM samples ORDER BY id; + sample | sample +--------------------------------------------------------------------- + $ | $ + strict $ | strict $ + lax $ | $ + $.a | $."a" + $.a.v | $."a"."v" + $.a.* | $."a".* + $.*[*] | $.*[*] + $.a[*] | $."a"[*] + $.a[*][*] | $."a"[*][*] + $[*] | $[*] + $[0] | $[0] + $[*][0] | $[*][0] + $[*].a | $[*]."a" + $[*][0].a.b | $[*][0]."a"."b" + $.a.**.b | $."a".**."b" + $.a.**{2}.b | $."a".**{2}."b" + $.a.**{2 to 2}.b | $."a".**{2}."b" + $.a.**{2 to 5}.b | $."a".**{2 to 5}."b" + $.a.**{0 to 5}.b | $."a".**{0 to 5}."b" + $.a.**{5 to last}.b | $."a".**{5 to last}."b" + $.a.**{last}.b | $."a".**{last}."b" + $.a.**{last to 5}.b | $."a".**{last to 5}."b" + $+1 | ($ + 1) + $-1 | ($ - 1) + $--+1 | ($ - -1) + $.a/+-1 | ($."a" / -1) + 1 * 2 + 4 % -3 != false | (1 * 2 + 4 % -3 != false) + $.g ? ($.a == 1) | $."g"?($."a" == 1) + $.g ? (@ == 1) | $."g"?(@ == 1) + $.g ? (@.a == 1) | $."g"?(@."a" == 1) + $.g ? (@.a == 1 || @.a == 4) | $."g"?(@."a" == 1 || @."a" == 4) + $.g ? (@.a == 1 && @.a == 4) | $."g"?(@."a" == 1 && @."a" == 4) + $.g ? (@.a == 1 || @.a == 4 && @.b == 7) | $."g"?(@."a" == 1 || @."a" == 4 && @."b" == 7) + $.g ? (@.a == 1 || !(@.a == 4) && @.b == 7) | $."g"?(@."a" == 1 || !(@."a" == 4) && @."b" == 7) + $.g ? (@.a == 1 || !(@.x >= 123 || @.a == 4) && @.b == 7) | $."g"?(@."a" == 1 || !(@."x" >= 123 || @."a" == 4) && @."b" == 7) + $.g ? (@.x >= @[*]?(@.a > "abc")) | $."g"?(@."x" >= @[*]?(@."a" > "abc")) + $.g ? ((@.x >= 123 || @.a == 4) is unknown) | $."g"?((@."x" >= 123 || @."a" == 4) is unknown) + $.g ? (exists (@.x)) | $."g"?(exists (@."x")) + $.g ? (exists (@.x ? (@ == 14))) | $."g"?(exists (@."x"?(@ == 14))) + $.g ? ((@.x >= 123 || @.a == 4) && exists (@.x ? (@ == 14))) | $."g"?((@."x" >= 123 || @."a" == 4) && exists (@."x"?(@ == 14))) + $.g ? (+@.x >= +-(+@.a + 2)) | $."g"?(+@."x" >= +(-(+@."a" + 2))) + $a | $"a" + $a.b | $"a"."b" + $a[*] | $"a"[*] + $.g ? (@.zip == $zip) | $."g"?(@."zip" == $"zip") + $.a[1,2, 3 to 16] | $."a"[1,2,3 to 16] + $.a[$a + 1, ($b[*]) to -($[0] * 2)] | $."a"[$"a" + 1,$"b"[*] to -($[0] * 2)] + $.a[$.a.size() - 3] | $."a"[$."a".size() - 3] + "last" | "last" + $.last | $."last" + $[last] | $[last] + $[$[0] ? (last > 0)] | $[$[0]?(last > 0)] + null.type() | null.type() + (1).type() | (1).type() + 1.2.type() | (1.2).type() + "aaa".type() | "aaa".type() + true.type() | true.type() + $.double().floor().ceiling().abs() | $.double().floor().ceiling().abs() + $.keyvalue().key | $.keyvalue()."key" + $.datetime() | $.datetime() + $.datetime("datetime template") | $.datetime("datetime template") + $ ? (@ starts with "abc") | $?(@ starts with "abc") + $ ? (@ starts with $var) | $?(@ starts with $"var") + $ ? (@ like_regex "pattern") | $?(@ like_regex "pattern") + $ ? (@ like_regex "pattern" flag "") | $?(@ like_regex "pattern") + $ ? (@ like_regex "pattern" flag "i") | $?(@ like_regex "pattern" flag "i") + $ ? (@ like_regex "pattern" flag "is") | $?(@ like_regex "pattern" flag "is") + $ ? (@ like_regex "pattern" flag "isim") | $?(@ like_regex "pattern" flag "ism") + $ ? (@ like_regex "pattern" flag "q") | $?(@ like_regex "pattern" flag "q") + $ ? (@ like_regex "pattern" flag "iq") | $?(@ like_regex "pattern" flag "iq") + $ ? (@ like_regex "pattern" flag "smixq") | $?(@ like_regex "pattern" flag "ismxq") + $ < 1 | ($ < 1) + ($ < 1) || $.a.b <= $x | ($ < 1 || $."a"."b" <= $"x") + ($).a.b | $."a"."b" + ($.a.b).c.d | $."a"."b"."c"."d" + ($.a.b + -$.x.y).c.d | ($."a"."b" + -$."x"."y")."c"."d" + (-+$.a.b).c.d | (-(+$."a"."b"))."c"."d" + 1 + ($.a.b + 2).c.d | (1 + ($."a"."b" + 2)."c"."d") + 1 + ($.a.b > 2).c.d | (1 + ($."a"."b" > 2)."c"."d") + ($) | $ + (($)) | $ + ((($ + 1)).a + ((2)).b ? ((((@ > 1)) || (exists(@.c))))) | (($ + 1)."a" + (2)."b"?(@ > 1 || exists (@."c"))) + $ ? (@.a < 1) | $?(@."a" < 1) + $ ? (@.a < -1) | $?(@."a" < -1) + $ ? (@.a < +1) | $?(@."a" < 1) + $ ? (@.a < .1) | $?(@."a" < 0.1) + $ ? (@.a < -.1) | $?(@."a" < -0.1) + $ ? (@.a < +.1) | $?(@."a" < 0.1) + $ ? (@.a < 0.1) | $?(@."a" < 0.1) + $ ? (@.a < -0.1) | $?(@."a" < -0.1) + $ ? (@.a < +0.1) | $?(@."a" < 0.1) + $ ? (@.a < 10.1) | $?(@."a" < 10.1) + $ ? (@.a < -10.1) | $?(@."a" < -10.1) + $ ? (@.a < +10.1) | $?(@."a" < 10.1) + $ ? (@.a < 1e1) | $?(@."a" < 10) + $ ? (@.a < -1e1) | $?(@."a" < -10) + $ ? (@.a < +1e1) | $?(@."a" < 10) + $ ? (@.a < .1e1) | $?(@."a" < 1) + $ ? (@.a < -.1e1) | $?(@."a" < -1) + $ ? (@.a < +.1e1) | $?(@."a" < 1) + $ ? (@.a < 0.1e1) | $?(@."a" < 1) + $ ? (@.a < -0.1e1) | $?(@."a" < -1) + $ ? (@.a < +0.1e1) | $?(@."a" < 1) + $ ? (@.a < 10.1e1) | $?(@."a" < 101) + $ ? (@.a < -10.1e1) | $?(@."a" < -101) + $ ? (@.a < +10.1e1) | $?(@."a" < 101) + $ ? (@.a < 1e-1) | $?(@."a" < 0.1) + $ ? (@.a < -1e-1) | $?(@."a" < -0.1) + $ ? (@.a < +1e-1) | $?(@."a" < 0.1) + $ ? (@.a < .1e-1) | $?(@."a" < 0.01) + $ ? (@.a < -.1e-1) | $?(@."a" < -0.01) + $ ? (@.a < +.1e-1) | $?(@."a" < 0.01) + $ ? (@.a < 0.1e-1) | $?(@."a" < 0.01) + $ ? (@.a < -0.1e-1) | $?(@."a" < -0.01) + $ ? (@.a < +0.1e-1) | $?(@."a" < 0.01) + $ ? (@.a < 10.1e-1) | $?(@."a" < 1.01) + $ ? (@.a < -10.1e-1) | $?(@."a" < -1.01) + $ ? (@.a < +10.1e-1) | $?(@."a" < 1.01) + $ ? (@.a < 1e+1) | $?(@."a" < 10) + $ ? (@.a < -1e+1) | $?(@."a" < -10) + $ ? (@.a < +1e+1) | $?(@."a" < 10) + $ ? (@.a < .1e+1) | $?(@."a" < 1) + $ ? (@.a < -.1e+1) | $?(@."a" < -1) + $ ? (@.a < +.1e+1) | $?(@."a" < 1) + $ ? (@.a < 0.1e+1) | $?(@."a" < 1) + $ ? (@.a < -0.1e+1) | $?(@."a" < -1) + $ ? (@.a < +0.1e+1) | $?(@."a" < 1) + $ ? (@.a < 10.1e+1) | $?(@."a" < 101) + $ ? (@.a < -10.1e+1) | $?(@."a" < -101) + $ ? (@.a < +10.1e+1) | $?(@."a" < 101) + 0 | 0 + 0.0 | 0.0 + 0.000 | 0.000 + 0.000e1 | 0.00 + 0.000e2 | 0.0 + 0.000e3 | 0 + 0.0010 | 0.0010 + 0.0010e-1 | 0.00010 + 0.0010e+1 | 0.010 + 0.0010e+2 | 0.10 + .001 | 0.001 + .001e1 | 0.01 + 1. | 1 + 1.e1 | 10 + 1.2.e | (1.2)."e" + (1.2).e | (1.2)."e" + 1e3 | 1000 + 1.e3 | 1000 + 1.e3.e | (1000)."e" + 1.e3.e4 | (1000)."e4" + 1.2e3 | 1200 + 1.2.e3 | (1.2)."e3" + (1.2).e3 | (1.2)."e3" + 1..e | (1)."e" + 1..e3 | (1)."e3" + (1.).e | (1)."e" + (1.).e3 | (1)."e3" + 1?(2>3) | (1)?(2 > 3) +(158 rows) + +-- now test some cases where trailing junk causes errors +\COPY jsonpath_test(sample) FROM STDIN +-- the following tests try to evaluate type casting on worker, followed by coordinator +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = ''; +ERROR: invalid input syntax for type jsonpath: "" +CONTEXT: while executing command on localhost:xxxxx +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = '' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; +ERROR: invalid input syntax for type jsonpath: "" +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = 'last'; +ERROR: LAST is allowed only in array subscripts +CONTEXT: while executing command on localhost:xxxxx +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = 'last' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; +ERROR: LAST is allowed only in array subscripts +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = '1.type()'; +ERROR: trailing junk after numeric literal at or near "1.t" of jsonpath input +CONTEXT: while executing command on localhost:xxxxx +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = '1.type()' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; +ERROR: trailing junk after numeric literal at or near "1.t" of jsonpath input +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = '$ ? (@ like_regex "(invalid pattern")'; +ERROR: invalid regular expression: parentheses () not balanced +CONTEXT: while executing command on localhost:xxxxx +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = '$ ? (@ like_regex "(invalid pattern")' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; +ERROR: invalid regular expression: parentheses () not balanced +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = '$ ? (@ like_regex "pattern" flag "xsms")'; +ERROR: XQuery "x" flag (expanded regular expressions) is not implemented +CONTEXT: while executing command on localhost:xxxxx +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = '$ ? (@ like_regex "pattern" flag "xsms")' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; +ERROR: XQuery "x" flag (expanded regular expressions) is not implemented +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = '@ + 1'; +ERROR: @ is not allowed in root expressions +CONTEXT: while executing command on localhost:xxxxx +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = '@ + 1' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; +ERROR: @ is not allowed in root expressions +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = '00'; +ERROR: trailing junk after numeric literal at or near "00" of jsonpath input +CONTEXT: while executing command on localhost:xxxxx +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = '00' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; +ERROR: trailing junk after numeric literal at or near "00" of jsonpath input +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = '1.e'; +ERROR: trailing junk after numeric literal at or near "1.e" of jsonpath input +CONTEXT: while executing command on localhost:xxxxx +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = '1.e' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; +ERROR: trailing junk after numeric literal at or near "1.e" of jsonpath input +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = '1.2e3a'; +ERROR: trailing junk after numeric literal at or near "1.2e3a" of jsonpath input +CONTEXT: while executing command on localhost:xxxxx +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = '1.2e3a' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; +ERROR: trailing junk after numeric literal at or near "1.2e3a" of jsonpath input +DROP SCHEMA jsonpath CASCADE; +NOTICE: drop cascades to table jsonpath_test diff --git a/src/test/regress/expected/pg15_jsonpath_0.out b/src/test/regress/expected/pg15_jsonpath_0.out new file mode 100644 index 000000000..b496f64dc --- /dev/null +++ b/src/test/regress/expected/pg15_jsonpath_0.out @@ -0,0 +1,10 @@ +-- +-- PG15 jsonpath tests +-- Relevant pg commit: e26114c817b610424010cfbe91a743f591246ff1 +-- +SHOW server_version \gset +SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15 +\gset +\if :server_version_ge_15 +\else +\q diff --git a/src/test/regress/multi_schedule b/src/test/regress/multi_schedule index c8ad97d5a..9abab954c 100644 --- a/src/test/regress/multi_schedule +++ b/src/test/regress/multi_schedule @@ -58,7 +58,7 @@ test: cte_inline recursive_view_local_table values sequences_with_different_type test: pg13 pg12 # run pg14 sequentially as it syncs metadata test: pg14 -test: pg15 +test: pg15 pg15_jsonpath test: drop_column_partitioned_table test: tableam diff --git a/src/test/regress/sql/pg15_jsonpath.sql b/src/test/regress/sql/pg15_jsonpath.sql new file mode 100644 index 000000000..1f4077c11 --- /dev/null +++ b/src/test/regress/sql/pg15_jsonpath.sql @@ -0,0 +1,236 @@ +-- +-- PG15 jsonpath tests +-- Relevant pg commit: e26114c817b610424010cfbe91a743f591246ff1 +-- +SHOW server_version \gset +SELECT substring(:'server_version', '\d+')::int >= 15 AS server_version_ge_15 +\gset +\if :server_version_ge_15 +\else +\q +\endif + +CREATE SCHEMA jsonpath; +SET search_path TO jsonpath; + +CREATE TABLE jsonpath_test (id serial, sample text); +SELECT create_distributed_table('jsonpath_test', 'id'); +\COPY jsonpath_test(sample) FROM STDIN +$ +strict $ +lax $ +$.a +$.a.v +$.a.* +$.*[*] +$.a[*] +$.a[*][*] +$[*] +$[0] +$[*][0] +$[*].a +$[*][0].a.b +$.a.**.b +$.a.**{2}.b +$.a.**{2 to 2}.b +$.a.**{2 to 5}.b +$.a.**{0 to 5}.b +$.a.**{5 to last}.b +$.a.**{last}.b +$.a.**{last to 5}.b +$+1 +$-1 +$--+1 +$.a/+-1 +1 * 2 + 4 % -3 != false +$.g ? ($.a == 1) +$.g ? (@ == 1) +$.g ? (@.a == 1) +$.g ? (@.a == 1 || @.a == 4) +$.g ? (@.a == 1 && @.a == 4) +$.g ? (@.a == 1 || @.a == 4 && @.b == 7) +$.g ? (@.a == 1 || !(@.a == 4) && @.b == 7) +$.g ? (@.a == 1 || !(@.x >= 123 || @.a == 4) && @.b == 7) +$.g ? (@.x >= @[*]?(@.a > "abc")) +$.g ? ((@.x >= 123 || @.a == 4) is unknown) +$.g ? (exists (@.x)) +$.g ? (exists (@.x ? (@ == 14))) +$.g ? ((@.x >= 123 || @.a == 4) && exists (@.x ? (@ == 14))) +$.g ? (+@.x >= +-(+@.a + 2)) +$a +$a.b +$a[*] +$.g ? (@.zip == $zip) +$.a[1,2, 3 to 16] +$.a[$a + 1, ($b[*]) to -($[0] * 2)] +$.a[$.a.size() - 3] +"last" +$.last +$[last] +$[$[0] ? (last > 0)] +null.type() +(1).type() +1.2.type() +"aaa".type() +true.type() +$.double().floor().ceiling().abs() +$.keyvalue().key +$.datetime() +$.datetime("datetime template") +$ ? (@ starts with "abc") +$ ? (@ starts with $var) +$ ? (@ like_regex "pattern") +$ ? (@ like_regex "pattern" flag "") +$ ? (@ like_regex "pattern" flag "i") +$ ? (@ like_regex "pattern" flag "is") +$ ? (@ like_regex "pattern" flag "isim") +$ ? (@ like_regex "pattern" flag "q") +$ ? (@ like_regex "pattern" flag "iq") +$ ? (@ like_regex "pattern" flag "smixq") +$ < 1 +($ < 1) || $.a.b <= $x +($).a.b +($.a.b).c.d +($.a.b + -$.x.y).c.d +(-+$.a.b).c.d +1 + ($.a.b + 2).c.d +1 + ($.a.b > 2).c.d +($) +(($)) +((($ + 1)).a + ((2)).b ? ((((@ > 1)) || (exists(@.c))))) +$ ? (@.a < 1) +$ ? (@.a < -1) +$ ? (@.a < +1) +$ ? (@.a < .1) +$ ? (@.a < -.1) +$ ? (@.a < +.1) +$ ? (@.a < 0.1) +$ ? (@.a < -0.1) +$ ? (@.a < +0.1) +$ ? (@.a < 10.1) +$ ? (@.a < -10.1) +$ ? (@.a < +10.1) +$ ? (@.a < 1e1) +$ ? (@.a < -1e1) +$ ? (@.a < +1e1) +$ ? (@.a < .1e1) +$ ? (@.a < -.1e1) +$ ? (@.a < +.1e1) +$ ? (@.a < 0.1e1) +$ ? (@.a < -0.1e1) +$ ? (@.a < +0.1e1) +$ ? (@.a < 10.1e1) +$ ? (@.a < -10.1e1) +$ ? (@.a < +10.1e1) +$ ? (@.a < 1e-1) +$ ? (@.a < -1e-1) +$ ? (@.a < +1e-1) +$ ? (@.a < .1e-1) +$ ? (@.a < -.1e-1) +$ ? (@.a < +.1e-1) +$ ? (@.a < 0.1e-1) +$ ? (@.a < -0.1e-1) +$ ? (@.a < +0.1e-1) +$ ? (@.a < 10.1e-1) +$ ? (@.a < -10.1e-1) +$ ? (@.a < +10.1e-1) +$ ? (@.a < 1e+1) +$ ? (@.a < -1e+1) +$ ? (@.a < +1e+1) +$ ? (@.a < .1e+1) +$ ? (@.a < -.1e+1) +$ ? (@.a < +.1e+1) +$ ? (@.a < 0.1e+1) +$ ? (@.a < -0.1e+1) +$ ? (@.a < +0.1e+1) +$ ? (@.a < 10.1e+1) +$ ? (@.a < -10.1e+1) +$ ? (@.a < +10.1e+1) +0 +0.0 +0.000 +0.000e1 +0.000e2 +0.000e3 +0.0010 +0.0010e-1 +0.0010e+1 +0.0010e+2 +.001 +.001e1 +1. +1.e1 +1.2.e +(1.2).e +1e3 +1.e3 +1.e3.e +1.e3.e4 +1.2e3 +1.2.e3 +(1.2).e3 +1..e +1..e3 +(1.).e +(1.).e3 +1?(2>3) +\. + +-- Cast the text into jsonpath on the worker nodes. +SELECT sample, sample::jsonpath FROM jsonpath_test ORDER BY id; + +-- Pull the data, and cast on the coordinator node +WITH samples as (SELECT id, sample FROM jsonpath_test OFFSET 0) +SELECT sample, sample::jsonpath FROM samples ORDER BY id; + +-- now test some cases where trailing junk causes errors +\COPY jsonpath_test(sample) FROM STDIN + +last +1.type() +$ ? (@ like_regex "(invalid pattern") +$ ? (@ like_regex "pattern" flag "xsms") +@ + 1 +00 +1.e +1.2e3a +\. + +-- the following tests try to evaluate type casting on worker, followed by coordinator +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = ''; +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = '' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; + +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = 'last'; +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = 'last' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; + +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = '1.type()'; +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = '1.type()' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; + +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = '$ ? (@ like_regex "(invalid pattern")'; +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = '$ ? (@ like_regex "(invalid pattern")' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; + +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = '$ ? (@ like_regex "pattern" flag "xsms")'; +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = '$ ? (@ like_regex "pattern" flag "xsms")' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; + +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = '@ + 1'; +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = '@ + 1' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; + +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = '00'; +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = '00' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; + +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = '1.e'; +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = '1.e' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; + +SELECT sample, sample::jsonpath FROM jsonpath_test WHERE sample = '1.2e3a'; +WITH samples as (SELECT id, sample FROM jsonpath_test WHERE sample = '1.2e3a' OFFSET 0) +SELECT sample, sample::jsonpath FROM samples; + +DROP SCHEMA jsonpath CASCADE;