11/*
2- * $PostgreSQL: pgsql/contrib/xml2/xpath.c,v 1.28 2010/03/01 05:16:35 tgl Exp $
2+ * $PostgreSQL: pgsql/contrib/xml2/xpath.c,v 1.29 2010/03/03 19:10:22 tgl Exp $
33 *
44 * Parser interface for DOM-based parser (libxml) rather than
55 * stream-based SAX-type parser
1212#include "lib/stringinfo.h"
1313#include "miscadmin.h"
1414#include "utils/builtins.h"
15+ #include "utils/xml.h"
1516
1617/* libxml includes */
1718
@@ -35,15 +36,12 @@ Datumxpath_bool(PG_FUNCTION_ARGS);
3536Datum xpath_list (PG_FUNCTION_ARGS );
3637Datum xpath_table (PG_FUNCTION_ARGS );
3738
38- /*these are exported for use by xslt_proc.c */
39+ /* exported for use by xslt_proc.c */
3940
40- void elog_error (const char * explain ,bool force );
4141void pgxml_parser_init (void );
4242
4343/* local declarations */
4444
45- static void pgxml_errorHandler (void * ctxt ,const char * msg ,...);
46-
4745static xmlChar * pgxmlNodeSetToText (xmlNodeSetPtr nodeset ,
4846xmlChar * toptagname ,xmlChar * septagname ,
4947xmlChar * plainsep );
@@ -55,72 +53,15 @@ static xmlChar *pgxml_texttoxmlchar(text *textstring);
5553
5654static xmlXPathObjectPtr pgxml_xpath (text * document ,xmlChar * xpath );
5755
58- /* Global variables */
59- static char * pgxml_errorMsg = NULL ;/* overall error message */
60-
61-
62- /*
63- * The error handling function. This formats an error message and sets
64- * a flag - an ereport will be issued prior to return
65- */
66- static void
67- pgxml_errorHandler (void * ctxt ,const char * msg ,...)
68- {
69- char errbuf [1024 ];/* per line error buffer */
70- va_list args ;
71-
72- /* Format the message */
73- va_start (args ,msg );
74- vsnprintf (errbuf ,sizeof (errbuf ),msg ,args );
75- va_end (args );
76- /* Store in, or append to, pgxml_errorMsg */
77- if (pgxml_errorMsg == NULL )
78- pgxml_errorMsg = pstrdup (errbuf );
79- else
80- {
81- size_t oldsize = strlen (pgxml_errorMsg );
82- size_t newsize = strlen (errbuf );
83-
84- /*
85- * We intentionally discard the last char of the existing message,
86- * which should be a carriage return. (XXX wouldn't it be saner
87- * to keep it?)
88- */
89- pgxml_errorMsg = repalloc (pgxml_errorMsg ,oldsize + newsize );
90- memcpy (& pgxml_errorMsg [oldsize - 1 ],errbuf ,newsize );
91- pgxml_errorMsg [oldsize + newsize - 1 ]= '\0' ;
92- }
93- }
94-
95- /*
96- * This function ereports the current message if any. If force is true
97- * then an error is thrown even if pgxml_errorMsg hasn't been set.
98- */
99- void
100- elog_error (const char * explain ,bool force )
101- {
102- if (force || pgxml_errorMsg != NULL )
103- {
104- if (pgxml_errorMsg == NULL )
105- ereport (ERROR ,
106- (errcode (ERRCODE_EXTERNAL_ROUTINE_EXCEPTION ),
107- errmsg ("%s" ,explain )));
108- else
109- ereport (ERROR ,
110- (errcode (ERRCODE_EXTERNAL_ROUTINE_EXCEPTION ),
111- errmsg ("%s: %s" ,explain ,pgxml_errorMsg )));
112- }
113- }
11456
11557/*
11658 * Initialize for xml parsing.
11759 */
11860void
11961pgxml_parser_init (void )
12062{
121- /* Set up error handling */
122- pgxml_errorMsg = NULL ;
123- xmlSetGenericErrorFunc (NULL ,pgxml_errorHandler );
63+ /* Set up error handling (we share the core's error handler) */
64+ pg_xml_init ();
12465
12566/* Initialize libxml */
12667xmlInitParser ();
@@ -466,7 +407,8 @@ pgxml_xpath(text *document, xmlChar *xpath)
466407if (comppath == NULL )
467408{
468409xmlFreeDoc (doctree );
469- elog_error ("XPath Syntax Error" , true);
410+ xml_ereport (ERROR ,ERRCODE_EXTERNAL_ROUTINE_EXCEPTION ,
411+ "XPath Syntax Error" );
470412}
471413
472414/* Now evaluate the path expression. */
@@ -519,8 +461,6 @@ pgxml_result_to_text(xmlXPathObjectPtr res,
519461/* Free various storage */
520462xmlFree (xpresstr );
521463
522- elog_error ("XPath error" , false);
523-
524464return xpres ;
525465}
526466
@@ -691,10 +631,8 @@ xpath_table(PG_FUNCTION_ARGS)
691631}
692632
693633/*
694- * Setup the parser. Beware that this must happen in the same context as
695- * the cleanup - which means that any error from here on must do cleanup
696- * to ensure that the entity table doesn't get freed by being out of
697- * context.
634+ * Setup the parser. This should happen after we are done evaluating
635+ * the query, in case it calls functions that set up libxml differently.
698636 */
699637pgxml_parser_init ();
700638
@@ -751,14 +689,14 @@ xpath_table(PG_FUNCTION_ARGS)
751689{
752690ctxt = xmlXPathNewContext (doctree );
753691ctxt -> node = xmlDocGetRootElement (doctree );
754- xmlSetGenericErrorFunc (ctxt ,pgxml_errorHandler );
755692
756693/* compile the path */
757694comppath = xmlXPathCompile (xpaths [j ]);
758695if (comppath == NULL )
759696{
760697xmlFreeDoc (doctree );
761- elog_error ("XPath Syntax Error" , true);
698+ xml_ereport (ERROR ,ERRCODE_EXTERNAL_ROUTINE_EXCEPTION ,
699+ "XPath Syntax Error" );
762700}
763701
764702/* Now evaluate the path expression. */