Add XMLNamespaces to XMLElement

First seen: 2024-12-20 23:51:42+00:00 · Messages: 25 · Participants: 4

Latest Update

2026-06-01 · claude-opus-4-6

Add XMLNamespaces to XMLElement - Technical Analysis

Core Problem

PostgreSQL's xmlelement() function, which constructs XML elements per the SQL/XML standard, lacks support for the XMLNAMESPACES clause. This means users cannot declaratively attach XML namespace declarations to elements produced by xmlelement(). While PostgreSQL already supports XMLNAMESPACES in the context of XMLTABLE (for XPath evaluation), it does not support it in the element-construction context, which is a significant gap relative to the SQL/XML:2023 standard (Section 11.2, "XML lexically scoped options").

Without this feature, users who need namespace-qualified XML output must resort to workarounds like string manipulation or post-processing, which defeats the purpose of having structured XML construction functions.

Architectural Context

How XMLElement Currently Works

xmlelement() is implemented as a special expression node (XmlExpr) with op = IS_XMLELEMENT. The expression carries:

At execution time in xml.c, the element is constructed using libxml2's xmlTextWriter API. Attributes are written via xmlTextWriterWriteAttribute.

What the Patch Changes

The patch extends XmlExpr to carry namespace declarations alongside attributes. The implementation reuses the existing named_args/arg_names infrastructure pattern but adds a distinct mechanism for namespace declarations. Key changes span:

  1. Grammar (gram.y): Extends the xmlelement production rules to accept XMLNAMESPACES(...) as an optional clause. Pavel Stehule suggested consolidating the grammar to avoid multiplicative explosion of rules by treating xmlattributes and xml_namespaces as a list of "xml_element_options."

  2. Parse Analysis (parse_expr.c / transformXmlExpr): Validates namespace declarations per SQL/XML rules:

    • At most one DEFAULT namespace declaration
    • No prefix may be xml or xmlns
    • No URI may be http://www.w3.org/2000/xmlns/ or http://www.w3.org/XML/1998/namespace
    • Non-default namespace URIs cannot be zero-length strings
  3. Execution (xml.c): Uses xmlTextWriterWriteAttributeNS (instead of plain xmlTextWriterWriteAttribute) to properly register namespace declarations with libxml2, giving the library awareness of namespace semantics.

  4. Rule/View Deparse (ruleutils.c): Fixed a bug where namespace declarations in views were being incorrectly serialized as XMLATTRIBUTES instead of XMLNAMESPACES.

  5. XMLTABLE interaction: The shared xml_namespace_list grammar rule means NO DEFAULT also becomes available in XMLTABLE's XMLNAMESPACES clause. The patch handles this by translating NO DEFAULT to an empty string URI in transformRangeTableFunc.

Key Design Decisions and Tradeoffs

1. Expressions vs. String Constants for Namespace URIs

A significant design discussion centered on whether namespace URIs should be restricted to string constants (as DB2 and Oracle do) or allow arbitrary expressions including column references.

Arguments for expressions (adopted approach):

Arguments for constants only (raised by Umar Hayat):

The patch authors decided to allow expressions, accepting that runtime errors (e.g., zero-length URI for a prefixed namespace) are the user's responsibility to prevent via WHERE clauses.

2. NO DEFAULT Semantics

NO DEFAULT produces xmlns="", which in XML semantics undeclares a previously inherited default namespace. Umar Hayat initially suggested it should produce no output at all (like DEFAULT NULL), but Jim Jones correctly identified that per the XML specification, xmlns="" is the proper way to "undeclare" a default namespace in a child element scope. DB2 behaves similarly.

3. Libxml2 Namespace Management (v3 and beyond)

Starting in v3, the implementation switched from xmlTextWriterWriteAttribute (treating namespaces as plain attributes) to xmlTextWriterWriteAttributeNS, which properly informs libxml2 about namespace semantics. Jim noted that libxml2 is lenient (allowing duplicate default namespaces, allowing NO DEFAULT without prior DEFAULT), and the patch preserves user-declared namespaces even if redundant, respecting user intent.

4. Grammar Consolidation

Pavel's suggestion to avoid multiplying XMLELEMENT grammar rules by treating XMLNAMESPACES and XMLATTRIBUTES as options in a list was adopted in v3, producing cleaner grammar.

Current Status

The patch was marked "Ready for Committer" by Pavel Stehule after v3 (January 2025), then reverted to "Needs Review" by Umar Hayat who raised the XMLTABLE/NO DEFAULT interaction bug (fixed in v5). Since then, the patch has been repeatedly rebased (v6 through v11+) over 18 months without being committed, suggesting it awaits committer attention. No committer has engaged with the thread.

Outstanding Concerns