1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-06 19:59:18 +03:00

Fix XMLTABLE() deparsing to quote namespace names if necessary.

When deparsing an XMLTABLE() expression, XML namespace names were not
quoted. However, since they are parsed as ColLabel tokens, some names
require double quotes to ensure that they are properly interpreted.
Fix by using quote_identifier() in the deparsing code.

Back-patch to all supported versions.

Dean Rasheed, reviewed by Tom Lane.

Discussion: https://postgr.es/m/CAEZATCXTpAS%3DncfLNTZ7YS6O5puHeLg_SUYAit%2Bcs7wsrd9Msg%40mail.gmail.com
This commit is contained in:
Dean Rasheed 2025-01-12 12:54:32 +00:00
parent 29dfffae0a
commit d673eefd41
5 changed files with 26 additions and 13 deletions

View File

@ -11814,7 +11814,8 @@ get_xmltable(TableFunc *tf, deparse_context *context, bool showimplicit)
if (ns_node != NULL) if (ns_node != NULL)
{ {
get_rule_expr(expr, context, showimplicit); get_rule_expr(expr, context, showimplicit);
appendStringInfo(buf, " AS %s", strVal(ns_node)); appendStringInfo(buf, " AS %s",
quote_identifier(strVal(ns_node)));
} }
else else
{ {

View File

@ -1379,16 +1379,20 @@ SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz),
10 10
(1 row) (1 row)
CREATE VIEW xmltableview2 AS SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz), CREATE VIEW xmltableview2 AS SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS "Zz"),
'/zz:rows/zz:row' '/Zz:rows/Zz:row'
PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>' PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>'
COLUMNS a int PATH 'zz:a'); COLUMNS a int PATH 'Zz:a');
SELECT * FROM xmltableview2; SELECT * FROM xmltableview2;
a a
---- ----
10 10
(1 row) (1 row)
\sv xmltableview2
CREATE OR REPLACE VIEW public.xmltableview2 AS
SELECT a
FROM XMLTABLE(XMLNAMESPACES ('http://x.y'::text AS "Zz"), ('/Zz:rows/Zz:row'::text) PASSING ('<rows xmlns="http://x.y"><row><a>10</a></row></rows>'::xml) COLUMNS a integer PATH ('Zz:a'::text))
SELECT * FROM XMLTABLE(XMLNAMESPACES(DEFAULT 'http://x.y'), SELECT * FROM XMLTABLE(XMLNAMESPACES(DEFAULT 'http://x.y'),
'/rows/row' '/rows/row'
PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>' PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>'

View File

@ -1046,10 +1046,10 @@ ERROR: unsupported XML feature
LINE 3: PASSING '<rows xmlns="http://x.y"><row... LINE 3: PASSING '<rows xmlns="http://x.y"><row...
^ ^
DETAIL: This functionality requires the server to be built with libxml support. DETAIL: This functionality requires the server to be built with libxml support.
CREATE VIEW xmltableview2 AS SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz), CREATE VIEW xmltableview2 AS SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS "Zz"),
'/zz:rows/zz:row' '/Zz:rows/Zz:row'
PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>' PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>'
COLUMNS a int PATH 'zz:a'); COLUMNS a int PATH 'Zz:a');
ERROR: unsupported XML feature ERROR: unsupported XML feature
LINE 3: PASSING '<rows xmlns="http://x.y"><row... LINE 3: PASSING '<rows xmlns="http://x.y"><row...
^ ^
@ -1058,6 +1058,8 @@ SELECT * FROM xmltableview2;
ERROR: relation "xmltableview2" does not exist ERROR: relation "xmltableview2" does not exist
LINE 1: SELECT * FROM xmltableview2; LINE 1: SELECT * FROM xmltableview2;
^ ^
\sv xmltableview2
ERROR: relation "xmltableview2" does not exist
SELECT * FROM XMLTABLE(XMLNAMESPACES(DEFAULT 'http://x.y'), SELECT * FROM XMLTABLE(XMLNAMESPACES(DEFAULT 'http://x.y'),
'/rows/row' '/rows/row'
PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>' PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>'

View File

@ -1365,16 +1365,20 @@ SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz),
10 10
(1 row) (1 row)
CREATE VIEW xmltableview2 AS SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz), CREATE VIEW xmltableview2 AS SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS "Zz"),
'/zz:rows/zz:row' '/Zz:rows/Zz:row'
PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>' PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>'
COLUMNS a int PATH 'zz:a'); COLUMNS a int PATH 'Zz:a');
SELECT * FROM xmltableview2; SELECT * FROM xmltableview2;
a a
---- ----
10 10
(1 row) (1 row)
\sv xmltableview2
CREATE OR REPLACE VIEW public.xmltableview2 AS
SELECT a
FROM XMLTABLE(XMLNAMESPACES ('http://x.y'::text AS "Zz"), ('/Zz:rows/Zz:row'::text) PASSING ('<rows xmlns="http://x.y"><row><a>10</a></row></rows>'::xml) COLUMNS a integer PATH ('Zz:a'::text))
SELECT * FROM XMLTABLE(XMLNAMESPACES(DEFAULT 'http://x.y'), SELECT * FROM XMLTABLE(XMLNAMESPACES(DEFAULT 'http://x.y'),
'/rows/row' '/rows/row'
PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>' PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>'

View File

@ -439,13 +439,15 @@ SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz),
PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>' PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>'
COLUMNS a int PATH 'zz:a'); COLUMNS a int PATH 'zz:a');
CREATE VIEW xmltableview2 AS SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz), CREATE VIEW xmltableview2 AS SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS "Zz"),
'/zz:rows/zz:row' '/Zz:rows/Zz:row'
PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>' PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>'
COLUMNS a int PATH 'zz:a'); COLUMNS a int PATH 'Zz:a');
SELECT * FROM xmltableview2; SELECT * FROM xmltableview2;
\sv xmltableview2
SELECT * FROM XMLTABLE(XMLNAMESPACES(DEFAULT 'http://x.y'), SELECT * FROM XMLTABLE(XMLNAMESPACES(DEFAULT 'http://x.y'),
'/rows/row' '/rows/row'
PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>' PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>'