-- -- PG15+ test -- 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 SET search_path TO "json table"; -- insert some data INSERT INTO jsonb_table_test (js) VALUES ( '[ {"a": 1, "b": [], "c": []}, {"a": 2, "b": [1, 2, 3], "c": [10, null, 20]}, {"a": 3, "b": [1, 2], "c": []}, {"x": "4", "b": [1, 2], "c": 123} ]' ), ( '[ {"a": 1, "d": [], "c": []}, {"a": 2, "d": [1, 2, 3], "c": [10, null, 20]}, {"a": 3, "d": [1, 2], "c": []}, {"x": "4", "d": [1, 2], "c": 123} ]' ), ( '[ {"a": 1, "b": [], "c": []}, {"a": 2, "b": [100, 200, 300], "c": [10, null, 20]}, {"a": 3, "b": [1, 2], "c": [null]}, {"x": "4", "b": [1, 2], "c": 2} ]' ), ( '[ {"y": 1, "b": [], "c": []}, {"a": 2, "b": [1, 2, 3], "c": [10, null, 20]}, {"a": 3, "t": [1, 2], "c": []}, {"x": "4", "b": [1, 200], "c": 96} ]' ), ( '[ {"a": 1, "b": [], "c": []}, {"a": 2, "b": [1, 2, 3], "c": [10, null, 20]}, {"a": 3, "b": [1, 2], "c": []}, {"x": "100", "b": [1, 2], "c": 123} ]' ), ( '[ {"t": 1, "b": [], "c": []}, {"t": 2, "b": [1, 2, 3], "x": [10, null, 20]}, {"t": 3, "b": [1, 2], "c": []}, {"x": "4", "b": [1, 2], "c": 123} ]' ), ( '[ {"a": 1, "b": [], "c": []}, {"a": 2, "b": [1, 2, 3], "c": [10, null, 20]}, {"a": 3, "b": [1, 2], "c": []}, {"U": "4", "b": [1, 2], "c": 123} ]' ), ( '[ {"a": 1, "b": [], "c": []}, {"a": 2, "b": [1, 2, 3], "c": [10, null, 20]}, {"a": 3, "b": [1, 2], "c": []}, {"x": "4", "b": [1, 2], "c": 123} ]' ), ( '[ {"a": 1, "b": [], "c": []}, {"a": 2, "b": [1, 2, 3], "c": [10, null, 20]}, {"a": 3, "b": [1, 2], "c": []}, {"x": "4", "b": [1, 2], "c": 123} ]' ), ( '[ {"a": 1, "b": [], "c": []}, {"a": 2, "b": [1000, 2, 3], "c": [10, null, 20]}, {"a": 3, "b": [1, 2], "c": []}, {"x": "4", "T": [1, 2], "c": 123} ]' ), ( '[ {"a": 1, "b": [], "c": []}, {"a": 2, "b": [1, 2, 3], "c": [10, null, 20]}, {"a": 3, "b": [1, 2], "c": []}, {"x": "4", "b": [1, 2], "c": 123} ]' ), ( '[ {"ffa": 1, "b": [], "c": []}, {"ffb": 2, "b": [1, 2, 3], "c": [10, null, 20]}, {"fffc": 3, "b": [1, 2], "c": []}, {"x": "4", "b": [1, 2], "c": 123} ]' ); -- unspecified plan (outer, union) select jt.* from jsonb_table_test jtt, json_table ( jtt.js,'strict $[*]' as p columns ( n for ordinality, a int path 'lax $.a' default -1 on empty, nested path 'strict $.b[*]' as pb columns ( b int path '$' ), nested path 'strict $.c[*]' as pc columns ( c int path '$' ) ) ) jt ORDER BY 1,2,3,4; n | a | b | c --------------------------------------------------------------------- 1 | -1 | | 1 | -1 | | 1 | -1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 2 | -1 | 1 | 2 | -1 | 1 | 2 | -1 | 2 | 2 | -1 | 2 | 2 | -1 | 3 | 2 | -1 | 3 | 2 | -1 | | 10 2 | -1 | | 20 2 | -1 | | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 100 | 2 | 2 | 200 | 2 | 2 | 300 | 2 | 2 | 1000 | 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 3 | -1 | 1 | 3 | -1 | 1 | 3 | -1 | 2 | 3 | -1 | 2 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | | 3 | 3 | | 3 | 3 | | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 200 | 4 | -1 | | 4 | -1 | | (123 rows) -- default plan (outer, union) select jt.* from jsonb_table_test jtt, json_table ( jtt.js,'strict $[*]' as p columns ( n for ordinality, a int path 'lax $.a' default -1 on empty, nested path 'strict $.b[*]' as pb columns ( b int path '$' ), nested path 'strict $.c[*]' as pc columns ( c int path '$' ) ) plan default (outer, union) ) jt ORDER BY 1,2,3,4; n | a | b | c --------------------------------------------------------------------- 1 | -1 | | 1 | -1 | | 1 | -1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 2 | -1 | 1 | 2 | -1 | 1 | 2 | -1 | 2 | 2 | -1 | 2 | 2 | -1 | 3 | 2 | -1 | 3 | 2 | -1 | | 10 2 | -1 | | 20 2 | -1 | | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 100 | 2 | 2 | 200 | 2 | 2 | 300 | 2 | 2 | 1000 | 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 3 | -1 | 1 | 3 | -1 | 1 | 3 | -1 | 2 | 3 | -1 | 2 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | | 3 | 3 | | 3 | 3 | | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 200 | 4 | -1 | | 4 | -1 | | (123 rows) -- specific plan (p outer (pb union pc)) select jt.* from jsonb_table_test jtt, json_table ( jtt.js,'strict $[*]' as p columns ( n for ordinality, a int path 'lax $.a' default -1 on empty, nested path 'strict $.b[*]' as pb columns ( b int path '$' ), nested path 'strict $.c[*]' as pc columns ( c int path '$' ) ) plan (p outer (pb union pc)) ) jt ORDER BY 1,2,3,4; n | a | b | c --------------------------------------------------------------------- 1 | -1 | | 1 | -1 | | 1 | -1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 2 | -1 | 1 | 2 | -1 | 1 | 2 | -1 | 2 | 2 | -1 | 2 | 2 | -1 | 3 | 2 | -1 | 3 | 2 | -1 | | 10 2 | -1 | | 20 2 | -1 | | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 100 | 2 | 2 | 200 | 2 | 2 | 300 | 2 | 2 | 1000 | 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 3 | -1 | 1 | 3 | -1 | 1 | 3 | -1 | 2 | 3 | -1 | 2 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | | 3 | 3 | | 3 | 3 | | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 200 | 4 | -1 | | 4 | -1 | | (123 rows) -- specific plan (p outer (pc union pb)) select jt.* from jsonb_table_test jtt, json_table ( jtt.js,'strict $[*]' as p columns ( n for ordinality, a int path 'lax $.a' default -1 on empty, nested path 'strict $.b[*]' as pb columns ( b int path '$' ), nested path 'strict $.c[*]' as pc columns ( c int path '$' ) ) plan (p outer (pc union pb)) ) jt ORDER BY 1,2,3,4; n | a | c | b --------------------------------------------------------------------- 1 | -1 | | 1 | -1 | | 1 | -1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 2 | -1 | 10 | 2 | -1 | 20 | 2 | -1 | | 1 2 | -1 | | 1 2 | -1 | | 2 2 | -1 | | 2 2 | -1 | | 3 2 | -1 | | 3 2 | -1 | | 2 | 2 | 10 | 2 | 2 | 10 | 2 | 2 | 10 | 2 | 2 | 10 | 2 | 2 | 10 | 2 | 2 | 10 | 2 | 2 | 10 | 2 | 2 | 10 | 2 | 2 | 10 | 2 | 2 | 10 | 2 | 2 | 20 | 2 | 2 | 20 | 2 | 2 | 20 | 2 | 2 | 20 | 2 | 2 | 20 | 2 | 2 | 20 | 2 | 2 | 20 | 2 | 2 | 20 | 2 | 2 | 20 | 2 | 2 | 20 | 2 | 2 | | 1 2 | 2 | | 1 2 | 2 | | 1 2 | 2 | | 1 2 | 2 | | 1 2 | 2 | | 1 2 | 2 | | 1 2 | 2 | | 2 2 | 2 | | 2 2 | 2 | | 2 2 | 2 | | 2 2 | 2 | | 2 2 | 2 | | 2 2 | 2 | | 2 2 | 2 | | 2 2 | 2 | | 3 2 | 2 | | 3 2 | 2 | | 3 2 | 2 | | 3 2 | 2 | | 3 2 | 2 | | 3 2 | 2 | | 3 2 | 2 | | 3 2 | 2 | | 100 2 | 2 | | 200 2 | 2 | | 300 2 | 2 | | 1000 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 3 | -1 | | 1 3 | -1 | | 1 3 | -1 | | 2 3 | -1 | | 2 3 | 3 | | 1 3 | 3 | | 1 3 | 3 | | 1 3 | 3 | | 1 3 | 3 | | 1 3 | 3 | | 1 3 | 3 | | 1 3 | 3 | | 1 3 | 3 | | 2 3 | 3 | | 2 3 | 3 | | 2 3 | 3 | | 2 3 | 3 | | 2 3 | 3 | | 2 3 | 3 | | 2 3 | 3 | | 2 3 | 3 | | 3 | 3 | | 3 | 3 | | 4 | -1 | | 1 4 | -1 | | 1 4 | -1 | | 1 4 | -1 | | 1 4 | -1 | | 1 4 | -1 | | 1 4 | -1 | | 1 4 | -1 | | 1 4 | -1 | | 1 4 | -1 | | 1 4 | -1 | | 2 4 | -1 | | 2 4 | -1 | | 2 4 | -1 | | 2 4 | -1 | | 2 4 | -1 | | 2 4 | -1 | | 2 4 | -1 | | 2 4 | -1 | | 2 4 | -1 | | 200 4 | -1 | | 4 | -1 | | (123 rows) -- default plan (inner, union) select jt.* from jsonb_table_test jtt, json_table ( jtt.js,'strict $[*]' as p columns ( n for ordinality, a int path 'lax $.a' default -1 on empty, nested path 'strict $.b[*]' as pb columns ( b int path '$' ), nested path 'strict $.c[*]' as pc columns ( c int path '$' ) ) plan default (inner) ) jt ORDER BY 1,2,3,4; n | a | b | c --------------------------------------------------------------------- 2 | -1 | 1 | 2 | -1 | 1 | 2 | -1 | 2 | 2 | -1 | 2 | 2 | -1 | 3 | 2 | -1 | 3 | 2 | -1 | | 10 2 | -1 | | 20 2 | -1 | | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 100 | 2 | 2 | 200 | 2 | 2 | 300 | 2 | 2 | 1000 | 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 3 | -1 | 1 | 3 | -1 | 1 | 3 | -1 | 2 | 3 | -1 | 2 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 200 | (107 rows) -- specific plan (p inner (pb union pc)) select jt.* from jsonb_table_test jtt, json_table ( jtt.js,'strict $[*]' as p columns ( n for ordinality, a int path 'lax $.a' default -1 on empty, nested path 'strict $.b[*]' as pb columns ( b int path '$' ), nested path 'strict $.c[*]' as pc columns ( c int path '$' ) ) plan (p inner (pb union pc)) ) jt ORDER BY 1,2,3,4; n | a | b | c --------------------------------------------------------------------- 2 | -1 | 1 | 2 | -1 | 1 | 2 | -1 | 2 | 2 | -1 | 2 | 2 | -1 | 3 | 2 | -1 | 3 | 2 | -1 | | 10 2 | -1 | | 20 2 | -1 | | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 100 | 2 | 2 | 200 | 2 | 2 | 300 | 2 | 2 | 1000 | 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 10 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 20 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 2 | 2 | | 3 | -1 | 1 | 3 | -1 | 1 | 3 | -1 | 2 | 3 | -1 | 2 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 1 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | 2 | 3 | 3 | | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 1 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 2 | 4 | -1 | 200 | (107 rows) -- default plan (inner, cross) select jt.* from jsonb_table_test jtt, json_table ( jtt.js,'strict $[*]' as p columns ( n for ordinality, a int path 'lax $.a' default -1 on empty, nested path 'strict $.b[*]' as pb columns ( b int path '$' ), nested path 'strict $.c[*]' as pc columns ( c int path '$' ) ) plan default (cross, inner) ) jt ORDER BY 1,2,3,4; n | a | b | c --------------------------------------------------------------------- 2 | -1 | 1 | 10 2 | -1 | 1 | 20 2 | -1 | 1 | 2 | -1 | 2 | 10 2 | -1 | 2 | 20 2 | -1 | 2 | 2 | -1 | 3 | 10 2 | -1 | 3 | 20 2 | -1 | 3 | 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 100 | 10 2 | 2 | 100 | 20 2 | 2 | 100 | 2 | 2 | 200 | 10 2 | 2 | 200 | 20 2 | 2 | 200 | 2 | 2 | 300 | 10 2 | 2 | 300 | 20 2 | 2 | 300 | 2 | 2 | 1000 | 10 2 | 2 | 1000 | 20 2 | 2 | 1000 | 3 | 3 | 1 | 3 | 3 | 2 | (92 rows) -- specific plan (p inner (pb cross pc)) select jt.* from jsonb_table_test jtt, json_table ( jtt.js,'strict $[*]' as p columns ( n for ordinality, a int path 'lax $.a' default -1 on empty, nested path 'strict $.b[*]' as pb columns ( b int path '$' ), nested path 'strict $.c[*]' as pc columns ( c int path '$' ) ) plan (p inner (pb cross pc)) ) jt ORDER BY 1,2,3,4; n | a | b | c --------------------------------------------------------------------- 2 | -1 | 1 | 10 2 | -1 | 1 | 20 2 | -1 | 1 | 2 | -1 | 2 | 10 2 | -1 | 2 | 20 2 | -1 | 2 | 2 | -1 | 3 | 10 2 | -1 | 3 | 20 2 | -1 | 3 | 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 100 | 10 2 | 2 | 100 | 20 2 | 2 | 100 | 2 | 2 | 200 | 10 2 | 2 | 200 | 20 2 | 2 | 200 | 2 | 2 | 300 | 10 2 | 2 | 300 | 20 2 | 2 | 300 | 2 | 2 | 1000 | 10 2 | 2 | 1000 | 20 2 | 2 | 1000 | 3 | 3 | 1 | 3 | 3 | 2 | (92 rows) -- default plan (outer, cross) select jt.* from jsonb_table_test jtt, json_table ( jtt.js,'strict $[*]' as p columns ( n for ordinality, a int path 'lax $.a' default -1 on empty, nested path 'strict $.b[*]' as pb columns ( b int path '$' ), nested path 'strict $.c[*]' as pc columns ( c int path '$' ) ) plan default (outer, cross) ) jt ORDER BY 1,2,3,4; n | a | b | c --------------------------------------------------------------------- 1 | -1 | | 1 | -1 | | 1 | -1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 2 | -1 | 1 | 10 2 | -1 | 1 | 20 2 | -1 | 1 | 2 | -1 | 2 | 10 2 | -1 | 2 | 20 2 | -1 | 2 | 2 | -1 | 3 | 10 2 | -1 | 3 | 20 2 | -1 | 3 | 2 | -1 | | 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 100 | 10 2 | 2 | 100 | 20 2 | 2 | 100 | 2 | 2 | 200 | 10 2 | 2 | 200 | 20 2 | 2 | 200 | 2 | 2 | 300 | 10 2 | 2 | 300 | 20 2 | 2 | 300 | 2 | 2 | 1000 | 10 2 | 2 | 1000 | 20 2 | 2 | 1000 | 2 | 2 | | 3 | -1 | | 3 | -1 | | 3 | 3 | 1 | 3 | 3 | 2 | 3 | 3 | | 3 | 3 | | 3 | 3 | | 3 | 3 | | 3 | 3 | | 3 | 3 | | 3 | 3 | | 3 | 3 | | 3 | 3 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | (129 rows) -- specific plan (p outer (pb cross pc)) select jt.* from jsonb_table_test jtt, json_table ( jtt.js,'strict $[*]' as p columns ( n for ordinality, a int path 'lax $.a' default -1 on empty, nested path 'strict $.b[*]' as pb columns ( b int path '$' ), nested path 'strict $.c[*]' as pc columns ( c int path '$' ) ) plan (p outer (pb cross pc)) ) jt ORDER BY 1,2,3,4; n | a | b | c --------------------------------------------------------------------- 1 | -1 | | 1 | -1 | | 1 | -1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 1 | 1 | | 2 | -1 | 1 | 10 2 | -1 | 1 | 20 2 | -1 | 1 | 2 | -1 | 2 | 10 2 | -1 | 2 | 20 2 | -1 | 2 | 2 | -1 | 3 | 10 2 | -1 | 3 | 20 2 | -1 | 3 | 2 | -1 | | 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 10 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 20 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 10 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 20 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 10 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 20 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 3 | 2 | 2 | 100 | 10 2 | 2 | 100 | 20 2 | 2 | 100 | 2 | 2 | 200 | 10 2 | 2 | 200 | 20 2 | 2 | 200 | 2 | 2 | 300 | 10 2 | 2 | 300 | 20 2 | 2 | 300 | 2 | 2 | 1000 | 10 2 | 2 | 1000 | 20 2 | 2 | 1000 | 2 | 2 | | 3 | -1 | | 3 | -1 | | 3 | 3 | 1 | 3 | 3 | 2 | 3 | 3 | | 3 | 3 | | 3 | 3 | | 3 | 3 | | 3 | 3 | | 3 | 3 | | 3 | 3 | | 3 | 3 | | 3 | 3 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | 4 | -1 | | (129 rows) select jt.*, b1 + 100 as b from json_table (jsonb '[ {"a": 1, "b": [[1, 10], [2], [3, 30, 300]], "c": [1, null, 2]}, {"a": 2, "b": [10, 20], "c": [1, null, 2]}, {"x": "3", "b": [11, 22, 33, 44]} ]', '$[*]' as p columns ( n for ordinality, a int path 'lax $.a' default -1 on error, nested path 'strict $.b[*]' as pb columns ( b text format json path '$', nested path 'strict $[*]' as pb1 columns ( b1 int path '$' ) ), nested path 'strict $.c[*]' as pc columns ( c text format json path '$', nested path 'strict $[*]' as pc1 columns ( c1 int path '$' ) ) ) --plan default(outer, cross) plan(p outer ((pb inner pb1) cross (pc outer pc1))) ) jt ORDER BY 1,2,3,4,5; n | a | b | b1 | c | c1 | b --------------------------------------------------------------------- 1 | 1 | [1, 10] | 1 | 1 | | 101 1 | 1 | [1, 10] | 1 | 2 | | 101 1 | 1 | [1, 10] | 1 | null | | 101 1 | 1 | [1, 10] | 10 | 1 | | 110 1 | 1 | [1, 10] | 10 | 2 | | 110 1 | 1 | [1, 10] | 10 | null | | 110 1 | 1 | [2] | 2 | 1 | | 102 1 | 1 | [2] | 2 | 2 | | 102 1 | 1 | [2] | 2 | null | | 102 1 | 1 | [3, 30, 300] | 3 | 1 | | 103 1 | 1 | [3, 30, 300] | 3 | 2 | | 103 1 | 1 | [3, 30, 300] | 3 | null | | 103 1 | 1 | [3, 30, 300] | 30 | 1 | | 130 1 | 1 | [3, 30, 300] | 30 | 2 | | 130 1 | 1 | [3, 30, 300] | 30 | null | | 130 1 | 1 | [3, 30, 300] | 300 | 1 | | 400 1 | 1 | [3, 30, 300] | 300 | 2 | | 400 1 | 1 | [3, 30, 300] | 300 | null | | 400 2 | 2 | | | | | 3 | | | | | | (20 rows) -- Should succeed (JSON arguments are passed to root and nested paths) SELECT * FROM generate_series(1, 4) x, generate_series(1, 3) y, JSON_TABLE(jsonb '[[1,2,3],[2,3,4,5],[3,4,5,6]]', 'strict $[*] ? (@[*] < $x)' PASSING x AS x, y AS y COLUMNS ( y text FORMAT JSON PATH '$', NESTED PATH 'strict $[*] ? (@ >= $y)' COLUMNS ( z int PATH '$' ) ) ) jt ORDER BY 4,1,2,3; x | y | y | z --------------------------------------------------------------------- 2 | 1 | [1, 2, 3] | 1 3 | 1 | [1, 2, 3] | 1 4 | 1 | [1, 2, 3] | 1 2 | 1 | [1, 2, 3] | 2 2 | 2 | [1, 2, 3] | 2 3 | 1 | [1, 2, 3] | 2 3 | 1 | [2, 3, 4, 5] | 2 3 | 2 | [1, 2, 3] | 2 3 | 2 | [2, 3, 4, 5] | 2 4 | 1 | [1, 2, 3] | 2 4 | 1 | [2, 3, 4, 5] | 2 4 | 2 | [1, 2, 3] | 2 4 | 2 | [2, 3, 4, 5] | 2 2 | 1 | [1, 2, 3] | 3 2 | 2 | [1, 2, 3] | 3 2 | 3 | [1, 2, 3] | 3 3 | 1 | [1, 2, 3] | 3 3 | 1 | [2, 3, 4, 5] | 3 3 | 2 | [1, 2, 3] | 3 3 | 2 | [2, 3, 4, 5] | 3 3 | 3 | [1, 2, 3] | 3 3 | 3 | [2, 3, 4, 5] | 3 4 | 1 | [1, 2, 3] | 3 4 | 1 | [2, 3, 4, 5] | 3 4 | 1 | [3, 4, 5, 6] | 3 4 | 2 | [1, 2, 3] | 3 4 | 2 | [2, 3, 4, 5] | 3 4 | 2 | [3, 4, 5, 6] | 3 4 | 3 | [1, 2, 3] | 3 4 | 3 | [2, 3, 4, 5] | 3 4 | 3 | [3, 4, 5, 6] | 3 3 | 1 | [2, 3, 4, 5] | 4 3 | 2 | [2, 3, 4, 5] | 4 3 | 3 | [2, 3, 4, 5] | 4 4 | 1 | [2, 3, 4, 5] | 4 4 | 1 | [3, 4, 5, 6] | 4 4 | 2 | [2, 3, 4, 5] | 4 4 | 2 | [3, 4, 5, 6] | 4 4 | 3 | [2, 3, 4, 5] | 4 4 | 3 | [3, 4, 5, 6] | 4 3 | 1 | [2, 3, 4, 5] | 5 3 | 2 | [2, 3, 4, 5] | 5 3 | 3 | [2, 3, 4, 5] | 5 4 | 1 | [2, 3, 4, 5] | 5 4 | 1 | [3, 4, 5, 6] | 5 4 | 2 | [2, 3, 4, 5] | 5 4 | 2 | [3, 4, 5, 6] | 5 4 | 3 | [2, 3, 4, 5] | 5 4 | 3 | [3, 4, 5, 6] | 5 4 | 1 | [3, 4, 5, 6] | 6 4 | 2 | [3, 4, 5, 6] | 6 4 | 3 | [3, 4, 5, 6] | 6 (52 rows)