Make JSON_TABLE generated path names avoid collisions

generateJsonTablePathName() produced names of the form
"json_table_path_N" in the same namespace as user-supplied path and
column names, without checking whether the name was already in use.
When an unnamed NESTED path's generated name happened to match a
user-supplied path name that a PLAN clause referenced, two sibling paths
matched the same plan entry and one of them, together with its columns,
was silently dropped from the output.

Bump the counter until the generated name is unused, so a generated name
can no longer coincide with a user-supplied one.  The still-uncovered
path is then correctly reported as not found in the plan.

The row pattern (root) path is named before the user-supplied column and
path names are collected, so when it is left unnamed its generated name
could not avoid them either, and a user column or path named like a
generated name, e.g.

    SELECT * FROM JSON_TABLE(jsonb '1', '$'
                             COLUMNS (json_table_path_0 int PATH '$')) jt;

was rejected with a bogus "duplicate JSON_TABLE column or path name"
error.  Collect the user-supplied names first and generate the row
pattern path's name afterwards, so that it avoids all of them.  An
explicit root path name is still seeded into the namespace, so a column
duplicating it is still correctly rejected.

Reported-by: Thom Brown <[email protected]>
Discussion: 
https://postgr.es/m/caa-alv7azgsexnbjjrw8ekkoxbu34tdoklla2gpye3ahjo5...@mail.gmail.com
Discussion: 
https://postgr.es/m/CAA-aLv5U94KD4C%2BLhAPYcCeGvs1xBMngcS5oEkZHN9YWwXUHsA%40mail.gmail.com

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/cd5fd08be7ec1cef1a4c34791ce743954c2b2293

Modified Files
--------------
src/backend/parser/parse_jsontable.c            | 33 +++++++++++++++++++------
src/test/regress/expected/sqljson_jsontable.out | 25 +++++++++++++++++++
src/test/regress/sql/sqljson_jsontable.sql      | 18 ++++++++++++++
3 files changed, 68 insertions(+), 8 deletions(-)

Reply via email to