@ -141,9 +141,10 @@ static bool print_xml_decl(StringInfo buf, const xmlChar *version,
pg_enc encoding , int standalone ) ;
static xmlDocPtr xml_parse ( text * data , XmlOptionType xmloption_arg ,
bool preserve_whitespace , int encoding ) ;
static text * xml_xmlnodetoxmltype ( xmlNodePtr cur ) ;
static text * xml_xmlnodetoxmltype ( xmlNodePtr cur , PgXmlErrorContext * xmlerrcxt ) ;
static int xml_xpathobjtoxmlarray ( xmlXPathObjectPtr xpathobj ,
ArrayBuildState * astate ) ;
ArrayBuildState * astate ,
PgXmlErrorContext * xmlerrcxt ) ;
# endif /* USE_LIBXML */
static StringInfo query_to_xml_internal ( const char * query , char * tablename ,
@ -3599,26 +3600,41 @@ SPI_sql_row_to_xmlelement(int rownum, StringInfo result, char *tablename,
* return value otherwise )
*/
static text *
xml_xmlnodetoxmltype ( xmlNodePtr cur )
xml_xmlnodetoxmltype ( xmlNodePtr cur , PgXmlErrorContext * xmlerrcxt )
{
xmltype * result ;
if ( cur - > type = = XML_ELEMENT_NODE )
{
xmlBufferPtr buf ;
xmlNodePtr cur_copy ;
buf = xmlBufferCreate ( ) ;
/*
* The result of xmlNodeDump ( ) won ' t contain namespace definitions
* from parent nodes , but xmlCopyNode ( ) duplicates a node along with
* its required namespace definitions .
*/
cur_copy = xmlCopyNode ( cur , 1 ) ;
if ( cur_copy = = NULL )
xml_ereport ( xmlerrcxt , ERROR , ERRCODE_OUT_OF_MEMORY ,
" could not copy node " ) ;
PG_TRY ( ) ;
{
xmlNodeDump ( buf , NULL , cur , 0 , 1 ) ;
xmlNodeDump ( buf , NULL , cur_copy , 0 , 1 ) ;
result = xmlBuffer_to_xmltype ( buf ) ;
}
PG_CATCH ( ) ;
{
xmlFreeNode ( cur_copy ) ;
xmlBufferFree ( buf ) ;
PG_RE_THROW ( ) ;
}
PG_END_TRY ( ) ;
xmlFreeNode ( cur_copy ) ;
xmlBufferFree ( buf ) ;
}
else
@ -3660,7 +3676,8 @@ xml_xmlnodetoxmltype(xmlNodePtr cur)
*/
static int
xml_xpathobjtoxmlarray ( xmlXPathObjectPtr xpathobj ,
ArrayBuildState * astate )
ArrayBuildState * astate ,
PgXmlErrorContext * xmlerrcxt )
{
int result = 0 ;
Datum datum ;
@ -3679,7 +3696,8 @@ xml_xpathobjtoxmlarray(xmlXPathObjectPtr xpathobj,
for ( i = 0 ; i < result ; i + + )
{
datum = PointerGetDatum ( xml_xmlnodetoxmltype ( xpathobj - > nodesetval - > nodeTab [ i ] ) ) ;
datum = PointerGetDatum ( xml_xmlnodetoxmltype ( xpathobj - > nodesetval - > nodeTab [ i ] ,
xmlerrcxt ) ) ;
( void ) accumArrayResult ( astate , datum , false ,
XMLOID , CurrentMemoryContext ) ;
}
@ -3881,9 +3899,9 @@ xpath_internal(text *xpath_expr_text, xmltype *data, ArrayType *namespaces,
* Extract the results as requested .
*/
if ( res_nitems ! = NULL )
* res_nitems = xml_xpathobjtoxmlarray ( xpathobj , astate ) ;
* res_nitems = xml_xpathobjtoxmlarray ( xpathobj , astate , xmlerrcxt ) ;
else
( void ) xml_xpathobjtoxmlarray ( xpathobj , astate ) ;
( void ) xml_xpathobjtoxmlarray ( xpathobj , astate , xmlerrcxt ) ;
}
PG_CATCH ( ) ;
{