@@ -141,9 +141,10 @@ static bool print_xml_decl(StringInfo buf, const xmlChar *version,
141
141
pg_enc encoding , int standalone );
142
142
static xmlDocPtr xml_parse (text * data , XmlOptionType xmloption_arg ,
143
143
bool preserve_whitespace , int encoding );
144
- static text * xml_xmlnodetoxmltype (xmlNodePtr cur );
144
+ static text * xml_xmlnodetoxmltype (xmlNodePtr cur , PgXmlErrorContext * xmlerrcxt );
145
145
static int xml_xpathobjtoxmlarray (xmlXPathObjectPtr xpathobj ,
146
- ArrayBuildState * * astate );
146
+ ArrayBuildState * * astate ,
147
+ PgXmlErrorContext * xmlerrcxt );
147
148
#endif /* USE_LIBXML */
148
149
149
150
static StringInfo query_to_xml_internal (const char * query , char * tablename ,
@@ -3595,26 +3596,41 @@ SPI_sql_row_to_xmlelement(int rownum, StringInfo result, char *tablename,
3595
3596
* return value otherwise)
3596
3597
*/
3597
3598
static text *
3598
- xml_xmlnodetoxmltype (xmlNodePtr cur )
3599
+ xml_xmlnodetoxmltype (xmlNodePtr cur , PgXmlErrorContext * xmlerrcxt )
3599
3600
{
3600
3601
xmltype * result ;
3601
3602
3602
3603
if (cur -> type == XML_ELEMENT_NODE )
3603
3604
{
3604
3605
xmlBufferPtr buf ;
3606
+ xmlNodePtr cur_copy ;
3605
3607
3606
3608
buf = xmlBufferCreate ();
3609
+
3610
+ /*
3611
+ * The result of xmlNodeDump() won't contain namespace definitions
3612
+ * from parent nodes, but xmlCopyNode() duplicates a node along with
3613
+ * its required namespace definitions.
3614
+ */
3615
+ cur_copy = xmlCopyNode (cur , 1 );
3616
+
3617
+ if (cur_copy == NULL )
3618
+ xml_ereport (xmlerrcxt , ERROR , ERRCODE_OUT_OF_MEMORY ,
3619
+ "could not copy node" );
3620
+
3607
3621
PG_TRY ();
3608
3622
{
3609
- xmlNodeDump (buf , NULL , cur , 0 , 1 );
3623
+ xmlNodeDump (buf , NULL , cur_copy , 0 , 1 );
3610
3624
result = xmlBuffer_to_xmltype (buf );
3611
3625
}
3612
3626
PG_CATCH ();
3613
3627
{
3628
+ xmlFreeNode (cur_copy );
3614
3629
xmlBufferFree (buf );
3615
3630
PG_RE_THROW ();
3616
3631
}
3617
3632
PG_END_TRY ();
3633
+ xmlFreeNode (cur_copy );
3618
3634
xmlBufferFree (buf );
3619
3635
}
3620
3636
else
@@ -3656,7 +3672,8 @@ xml_xmlnodetoxmltype(xmlNodePtr cur)
3656
3672
*/
3657
3673
static int
3658
3674
xml_xpathobjtoxmlarray (xmlXPathObjectPtr xpathobj ,
3659
- ArrayBuildState * * astate )
3675
+ ArrayBuildState * * astate ,
3676
+ PgXmlErrorContext * xmlerrcxt )
3660
3677
{
3661
3678
int result = 0 ;
3662
3679
Datum datum ;
@@ -3678,7 +3695,8 @@ xml_xpathobjtoxmlarray(xmlXPathObjectPtr xpathobj,
3678
3695
3679
3696
for (i = 0 ; i < result ; i ++ )
3680
3697
{
3681
- datum = PointerGetDatum (xml_xmlnodetoxmltype (xpathobj -> nodesetval -> nodeTab [i ]));
3698
+ datum = PointerGetDatum (xml_xmlnodetoxmltype (xpathobj -> nodesetval -> nodeTab [i ],
3699
+ xmlerrcxt ));
3682
3700
* astate = accumArrayResult (* astate , datum ,
3683
3701
false, XMLOID ,
3684
3702
CurrentMemoryContext );
@@ -3882,9 +3900,9 @@ xpath_internal(text *xpath_expr_text, xmltype *data, ArrayType *namespaces,
3882
3900
* Extract the results as requested.
3883
3901
*/
3884
3902
if (res_nitems != NULL )
3885
- * res_nitems = xml_xpathobjtoxmlarray (xpathobj , astate );
3903
+ * res_nitems = xml_xpathobjtoxmlarray (xpathobj , astate , xmlerrcxt );
3886
3904
else
3887
- (void ) xml_xpathobjtoxmlarray (xpathobj , astate );
3905
+ (void ) xml_xpathobjtoxmlarray (xpathobj , astate , xmlerrcxt );
3888
3906
}
3889
3907
PG_CATCH ();
3890
3908
{
0 commit comments