postgres.git / summary / log / commit / refs

commit    d673eefd410cd7f5f95e418990146189f44811af
Author:   Dean Rasheed <dean.a.rasheed@gmail.com>
Date:     Sun Jan 12 12:54:32 2025 +0000
First released in: 18.0, 13.19, 14.16, 15.11, 16.7, 17.3

    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


src/backend/utils/adt/ruleutils.c | 3 ++- src/test/regress/expected/xml.out | 10 +++++++--- src/test/regress/expected/xml_1.out | 8 +++++--- src/test/regress/expected/xml_2.out | 10 +++++++--- src/test/regress/sql/xml.sql | 8 +++++--- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 16d15f9efb9..b9358687164 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -11814,7 +11814,8 @@ get_xmltable(TableFunc *tf, deparse_context *context, bool showimplicit) if (ns_node != NULL) { get_rule_expr(expr, context, showimplicit); - appendStringInfo(buf, " AS %s", strVal(ns_node)); + appendStringInfo(buf, " AS %s", + quote_identifier(strVal(ns_node))); } else { diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out index fb5f345855c..2e9616acda1 100644 --- a/src/test/regress/expected/xml.out +++ b/src/test/regress/expected/xml.out @@ -1379,16 +1379,20 @@ SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz), 10 (1 row) -CREATE VIEW xmltableview2 AS SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz), - '/zz:rows/zz:row' +CREATE VIEW xmltableview2 AS SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS "Zz"), + '/Zz:rows/Zz:row' 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; a ---- 10 (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'), '/rows/row' PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>' diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out index ef7dc03c691..7505a140775 100644 --- a/src/test/regress/expected/xml_1.out +++ b/src/test/regress/expected/xml_1.out @@ -1046,10 +1046,10 @@ ERROR: unsupported XML feature LINE 3: PASSING '<rows xmlns="http://x.y"><row... ^ 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), - '/zz:rows/zz:row' +CREATE VIEW xmltableview2 AS SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS "Zz"), + '/Zz:rows/Zz:row' 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 LINE 3: PASSING '<rows xmlns="http://x.y"><row... ^ @@ -1058,6 +1058,8 @@ SELECT * FROM xmltableview2; ERROR: relation "xmltableview2" does not exist LINE 1: SELECT * FROM xmltableview2; ^ +\sv xmltableview2 +ERROR: relation "xmltableview2" does not exist SELECT * FROM XMLTABLE(XMLNAMESPACES(DEFAULT 'http://x.y'), '/rows/row' PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>' diff --git a/src/test/regress/expected/xml_2.out b/src/test/regress/expected/xml_2.out index 4a9cdd2afe4..c07ed2b269c 100644 --- a/src/test/regress/expected/xml_2.out +++ b/src/test/regress/expected/xml_2.out @@ -1365,16 +1365,20 @@ SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz), 10 (1 row) -CREATE VIEW xmltableview2 AS SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz), - '/zz:rows/zz:row' +CREATE VIEW xmltableview2 AS SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS "Zz"), + '/Zz:rows/Zz:row' 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; a ---- 10 (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'), '/rows/row' PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>' diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sql index f752ecb1421..bac0388ac11 100644 --- a/src/test/regress/sql/xml.sql +++ b/src/test/regress/sql/xml.sql @@ -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>' COLUMNS a int PATH 'zz:a'); -CREATE VIEW xmltableview2 AS SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS zz), - '/zz:rows/zz:row' +CREATE VIEW xmltableview2 AS SELECT * FROM XMLTABLE(XMLNAMESPACES('http://x.y' AS "Zz"), + '/Zz:rows/Zz:row' 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; +\sv xmltableview2 + SELECT * FROM XMLTABLE(XMLNAMESPACES(DEFAULT 'http://x.y'), '/rows/row' PASSING '<rows xmlns="http://x.y"><row><a>10</a></row></rows>' [parent: 29dfffae0a6d]