Skip to content

Commit cd838e2

Browse files
committed
Neaten up our choices of SQLSTATEs for XML-related errors.
When our XML-handling modules were first written, the SQL standard lacked any error codes that were particularly intended for XML error conditions. Unsurprisingly, this led to some rather random choices of errcodes in those modules. Now the standard has a whole SQLSTATE class, "Class 10 - XQuery Error", with a reasonably large selection of relevant-looking errcodes. In this patch I've chosen one fairly generic code defined by the standard, 10608 = invalid_argument_for_xquery, and used it where it seemed appropriate. I've also made an effort to replace ERRCODE_INTERNAL_ERROR everywhere it was not clearly reporting a coding problem; in particular, many of the existing uses look like they can fairly be reported as ERRCODE_OUT_OF_MEMORY. It might be interesting to try to map libxml2's error codes into the standard's new collection, but I've not undertaken that here. Discussion: https://postgr.es/m/417250.1726341268@sss.pgh.pa.us
1 parent 3da436e commit cd838e2

File tree

4 files changed

+27
-21
lines changed

4 files changed

+27
-21
lines changed

contrib/xml2/xpath.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ pgxml_xpath(text *document, xmlChar *xpath, xpath_workspace *workspace)
388388
/* compile the path */
389389
comppath = xmlXPathCtxtCompile(workspace->ctxt, xpath);
390390
if (comppath == NULL)
391-
xml_ereport(xmlerrcxt, ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
391+
xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
392392
"XPath Syntax Error");
393393

394394
/* Now evaluate the path expression. */
@@ -652,7 +652,7 @@ xpath_table(PG_FUNCTION_ARGS)
652652
comppath = xmlXPathCtxtCompile(ctxt, xpaths[j]);
653653
if (comppath == NULL)
654654
xml_ereport(xmlerrcxt, ERROR,
655-
ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
655+
ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
656656
"XPath Syntax Error");
657657

658658
/* Now evaluate the path expression. */

contrib/xml2/xslt_proc.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ xslt_process(PG_FUNCTION_ARGS)
9090
XML_PARSE_NOENT);
9191

9292
if (doctree == NULL)
93-
xml_ereport(xmlerrcxt, ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
93+
xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT,
9494
"error parsing XML document");
9595

9696
/* Same for stylesheet */
@@ -99,14 +99,14 @@ xslt_process(PG_FUNCTION_ARGS)
9999
XML_PARSE_NOENT);
100100

101101
if (ssdoc == NULL)
102-
xml_ereport(xmlerrcxt, ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
102+
xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT,
103103
"error parsing stylesheet as XML document");
104104

105105
/* After this call we need not free ssdoc separately */
106106
stylesheet = xsltParseStylesheetDoc(ssdoc);
107107

108108
if (stylesheet == NULL)
109-
xml_ereport(xmlerrcxt, ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
109+
xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
110110
"failed to parse stylesheet");
111111

112112
xslt_ctxt = xsltNewTransformContext(stylesheet, doctree);
@@ -141,7 +141,7 @@ xslt_process(PG_FUNCTION_ARGS)
141141
NULL, NULL, xslt_ctxt);
142142

143143
if (restree == NULL)
144-
xml_ereport(xmlerrcxt, ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
144+
xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
145145
"failed to apply stylesheet");
146146

147147
resstat = xsltSaveResultToString(&resstr, &reslen, restree, stylesheet);

src/backend/utils/adt/xml.c

+15-15
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ xml_out_internal(xmltype *x, pg_enc target_encoding)
344344
}
345345

346346
ereport(WARNING,
347-
errcode(ERRCODE_INTERNAL_ERROR),
347+
errcode(ERRCODE_DATA_CORRUPTED),
348348
errmsg_internal("could not parse XML declaration in stored value"),
349349
errdetail_for_xml_code(res_code));
350350
#endif
@@ -742,7 +742,7 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
742742
{
743743
/* If it's a document, saving is easy. */
744744
if (xmlSaveDoc(ctxt, doc) == -1 || xmlerrcxt->err_occurred)
745-
xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
745+
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
746746
"could not save document to xmlBuffer");
747747
}
748748
else if (content_nodes != NULL)
@@ -785,15 +785,15 @@ xmltotext_with_options(xmltype *data, XmlOptionType xmloption_arg, bool indent)
785785
if (xmlSaveTree(ctxt, newline) == -1 || xmlerrcxt->err_occurred)
786786
{
787787
xmlFreeNode(newline);
788-
xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
788+
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
789789
"could not save newline to xmlBuffer");
790790
}
791791
}
792792

793793
if (xmlSaveTree(ctxt, node) == -1 || xmlerrcxt->err_occurred)
794794
{
795795
xmlFreeNode(newline);
796-
xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
796+
xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY,
797797
"could not save content to xmlBuffer");
798798
}
799799
}
@@ -1004,7 +1004,7 @@ xmlpi(const char *target, text *arg, bool arg_is_null, bool *result_is_null)
10041004

10051005
if (pg_strcasecmp(target, "xml") == 0)
10061006
ereport(ERROR,
1007-
(errcode(ERRCODE_SYNTAX_ERROR), /* really */
1007+
(errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
10081008
errmsg("invalid XML processing instruction"),
10091009
errdetail("XML processing instruction target name cannot be \"%s\".", target)));
10101010

@@ -4383,7 +4383,7 @@ xpath_internal(text *xpath_expr_text, xmltype *data, ArrayType *namespaces,
43834383
xpath_len = VARSIZE_ANY_EXHDR(xpath_expr_text);
43844384
if (xpath_len == 0)
43854385
ereport(ERROR,
4386-
(errcode(ERRCODE_DATA_EXCEPTION),
4386+
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_XQUERY),
43874387
errmsg("empty XPath expression")));
43884388

43894389
string = pg_xmlCharStrndup(datastr, len);
@@ -4456,7 +4456,7 @@ xpath_internal(text *xpath_expr_text, xmltype *data, ArrayType *namespaces,
44564456
*/
44574457
xpathcomp = xmlXPathCtxtCompile(xpathctx, xpath_expr);
44584458
if (xpathcomp == NULL || xmlerrcxt->err_occurred)
4459-
xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
4459+
xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
44604460
"invalid XPath expression");
44614461

44624462
/*
@@ -4468,7 +4468,7 @@ xpath_internal(text *xpath_expr_text, xmltype *data, ArrayType *namespaces,
44684468
*/
44694469
xpathobj = xmlXPathCompiledEval(xpathcomp, xpathctx);
44704470
if (xpathobj == NULL || xmlerrcxt->err_occurred)
4471-
xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
4471+
xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
44724472
"could not create XPath object");
44734473

44744474
/*
@@ -4798,7 +4798,7 @@ XmlTableSetNamespace(TableFuncScanState *state, const char *name, const char *ur
47984798
if (xmlXPathRegisterNs(xtCxt->xpathcxt,
47994799
pg_xmlCharStrndup(name, strlen(name)),
48004800
pg_xmlCharStrndup(uri, strlen(uri))))
4801-
xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_DATA_EXCEPTION,
4801+
xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
48024802
"could not set XML namespace");
48034803
#else
48044804
NO_XML_SUPPORT();
@@ -4820,7 +4820,7 @@ XmlTableSetRowFilter(TableFuncScanState *state, const char *path)
48204820

48214821
if (*path == '\0')
48224822
ereport(ERROR,
4823-
(errcode(ERRCODE_DATA_EXCEPTION),
4823+
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_XQUERY),
48244824
errmsg("row path filter must not be empty string")));
48254825

48264826
xstr = pg_xmlCharStrndup(path, strlen(path));
@@ -4830,7 +4830,7 @@ XmlTableSetRowFilter(TableFuncScanState *state, const char *path)
48304830

48314831
xtCxt->xpathcomp = xmlXPathCtxtCompile(xtCxt->xpathcxt, xstr);
48324832
if (xtCxt->xpathcomp == NULL || xtCxt->xmlerrcxt->err_occurred)
4833-
xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_SYNTAX_ERROR,
4833+
xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
48344834
"invalid XPath expression");
48354835
#else
48364836
NO_XML_SUPPORT();
@@ -4854,7 +4854,7 @@ XmlTableSetColumnFilter(TableFuncScanState *state, const char *path, int colnum)
48544854

48554855
if (*path == '\0')
48564856
ereport(ERROR,
4857-
(errcode(ERRCODE_DATA_EXCEPTION),
4857+
(errcode(ERRCODE_INVALID_ARGUMENT_FOR_XQUERY),
48584858
errmsg("column path filter must not be empty string")));
48594859

48604860
xstr = pg_xmlCharStrndup(path, strlen(path));
@@ -4864,7 +4864,7 @@ XmlTableSetColumnFilter(TableFuncScanState *state, const char *path, int colnum)
48644864

48654865
xtCxt->xpathscomp[colnum] = xmlXPathCtxtCompile(xtCxt->xpathcxt, xstr);
48664866
if (xtCxt->xpathscomp[colnum] == NULL || xtCxt->xmlerrcxt->err_occurred)
4867-
xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_DATA_EXCEPTION,
4867+
xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
48684868
"invalid XPath expression");
48694869
#else
48704870
NO_XML_SUPPORT();
@@ -4891,7 +4891,7 @@ XmlTableFetchRow(TableFuncScanState *state)
48914891
{
48924892
xtCxt->xpathobj = xmlXPathCompiledEval(xtCxt->xpathcomp, xtCxt->xpathcxt);
48934893
if (xtCxt->xpathobj == NULL || xtCxt->xmlerrcxt->err_occurred)
4894-
xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
4894+
xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
48954895
"could not create XPath object");
48964896

48974897
xtCxt->row_count = 0;
@@ -4955,7 +4955,7 @@ XmlTableGetValue(TableFuncScanState *state, int colnum,
49554955
/* Evaluate column path */
49564956
xpathobj = xmlXPathCompiledEval(xtCxt->xpathscomp[colnum], xtCxt->xpathcxt);
49574957
if (xpathobj == NULL || xtCxt->xmlerrcxt->err_occurred)
4958-
xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR,
4958+
xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INVALID_ARGUMENT_FOR_XQUERY,
49594959
"could not create XPath object");
49604960

49614961
/*

src/backend/utils/errcodes.txt

+6
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ Section: Class 0Z - Diagnostics Exception
141141
0Z000 E ERRCODE_DIAGNOSTICS_EXCEPTION diagnostics_exception
142142
0Z002 E ERRCODE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER stacked_diagnostics_accessed_without_active_handler
143143

144+
Section: Class 10 - XQuery Error
145+
146+
# recent SQL versions define quite a few codes in this class, but for now
147+
# we are only using this generic one
148+
10608 E ERRCODE_INVALID_ARGUMENT_FOR_XQUERY invalid_argument_for_xquery
149+
144150
Section: Class 20 - Case Not Found
145151

146152
20000 E ERRCODE_CASE_NOT_FOUND case_not_found

0 commit comments

Comments
 (0)