1
1
/*
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 $
3
3
*
4
4
* Parser interface for DOM-based parser (libxml) rather than
5
5
* stream-based SAX-type parser
12
12
#include "lib/stringinfo.h"
13
13
#include "miscadmin.h"
14
14
#include "utils/builtins.h"
15
+ #include "utils/xml.h"
15
16
16
17
/* libxml includes */
17
18
@@ -35,15 +36,12 @@ Datum xpath_bool(PG_FUNCTION_ARGS);
35
36
Datum xpath_list (PG_FUNCTION_ARGS );
36
37
Datum xpath_table (PG_FUNCTION_ARGS );
37
38
38
- /* these are exported for use by xslt_proc.c */
39
+ /* exported for use by xslt_proc.c */
39
40
40
- void elog_error (const char * explain , bool force );
41
41
void pgxml_parser_init (void );
42
42
43
43
/* local declarations */
44
44
45
- static void pgxml_errorHandler (void * ctxt , const char * msg ,...);
46
-
47
45
static xmlChar * pgxmlNodeSetToText (xmlNodeSetPtr nodeset ,
48
46
xmlChar * toptagname , xmlChar * septagname ,
49
47
xmlChar * plainsep );
@@ -55,72 +53,15 @@ static xmlChar *pgxml_texttoxmlchar(text *textstring);
55
53
56
54
static xmlXPathObjectPtr pgxml_xpath (text * document , xmlChar * xpath );
57
55
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
- }
114
56
115
57
/*
116
58
* Initialize for xml parsing.
117
59
*/
118
60
void
119
61
pgxml_parser_init (void )
120
62
{
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 ();
124
65
125
66
/* Initialize libxml */
126
67
xmlInitParser ();
@@ -466,7 +407,8 @@ pgxml_xpath(text *document, xmlChar *xpath)
466
407
if (comppath == NULL )
467
408
{
468
409
xmlFreeDoc (doctree );
469
- elog_error ("XPath Syntax Error" , true);
410
+ xml_ereport (ERROR , ERRCODE_EXTERNAL_ROUTINE_EXCEPTION ,
411
+ "XPath Syntax Error" );
470
412
}
471
413
472
414
/* Now evaluate the path expression. */
@@ -519,8 +461,6 @@ pgxml_result_to_text(xmlXPathObjectPtr res,
519
461
/* Free various storage */
520
462
xmlFree (xpresstr );
521
463
522
- elog_error ("XPath error" , false);
523
-
524
464
return xpres ;
525
465
}
526
466
@@ -691,10 +631,8 @@ xpath_table(PG_FUNCTION_ARGS)
691
631
}
692
632
693
633
/*
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.
698
636
*/
699
637
pgxml_parser_init ();
700
638
@@ -751,14 +689,14 @@ xpath_table(PG_FUNCTION_ARGS)
751
689
{
752
690
ctxt = xmlXPathNewContext (doctree );
753
691
ctxt -> node = xmlDocGetRootElement (doctree );
754
- xmlSetGenericErrorFunc (ctxt , pgxml_errorHandler );
755
692
756
693
/* compile the path */
757
694
comppath = xmlXPathCompile (xpaths [j ]);
758
695
if (comppath == NULL )
759
696
{
760
697
xmlFreeDoc (doctree );
761
- elog_error ("XPath Syntax Error" , true);
698
+ xml_ereport (ERROR , ERRCODE_EXTERNAL_ROUTINE_EXCEPTION ,
699
+ "XPath Syntax Error" );
762
700
}
763
701
764
702
/* Now evaluate the path expression. */
0 commit comments