pgindent run on xml.c in 8.3 branch, per request from Tom.

This commit is contained in:
Bruce Momjian 2010-03-03 00:32:49 +00:00
parent 881a97da86
commit 2193da28b1

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.68.2.12 2010/03/01 02:21:40 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.68.2.13 2010/03/03 00:32:49 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -100,14 +100,13 @@ static void *xml_palloc(size_t size);
static void *xml_repalloc(void *ptr, size_t size); static void *xml_repalloc(void *ptr, size_t size);
static void xml_pfree(void *ptr); static void xml_pfree(void *ptr);
static char *xml_pstrdup(const char *string); static char *xml_pstrdup(const char *string);
#endif /* USE_LIBXMLCONTEXT */
#endif /* USE_LIBXMLCONTEXT */
static void xml_init(void); static void xml_init(void);
static xmlChar *xml_text2xmlChar(text *in); static xmlChar *xml_text2xmlChar(text *in);
static int parse_xml_decl(const xmlChar * str, size_t *lenp, static int parse_xml_decl(const xmlChar *str, size_t *lenp,
xmlChar ** version, xmlChar ** encoding, int *standalone); xmlChar **version, xmlChar **encoding, int *standalone);
static bool print_xml_decl(StringInfo buf, const xmlChar * version, static bool print_xml_decl(StringInfo buf, const xmlChar *version,
pg_enc encoding, int standalone); pg_enc encoding, int standalone);
static xmlDocPtr xml_parse(text *data, XmlOptionType xmloption_arg, static xmlDocPtr xml_parse(text *data, XmlOptionType xmloption_arg,
bool preserve_whitespace, int encoding); bool preserve_whitespace, int encoding);
@ -636,45 +635,45 @@ xmlelement(XmlExprState *xmlExpr, ExprContext *econtext)
PG_TRY(); PG_TRY();
{ {
buf = xmlBufferCreate(); buf = xmlBufferCreate();
if (!buf) if (!buf)
xml_ereport(ERROR, ERRCODE_OUT_OF_MEMORY, xml_ereport(ERROR, ERRCODE_OUT_OF_MEMORY,
"could not allocate xmlBuffer"); "could not allocate xmlBuffer");
writer = xmlNewTextWriterMemory(buf, 0); writer = xmlNewTextWriterMemory(buf, 0);
if (!writer) if (!writer)
xml_ereport(ERROR, ERRCODE_OUT_OF_MEMORY, xml_ereport(ERROR, ERRCODE_OUT_OF_MEMORY,
"could not allocate xmlTextWriter"); "could not allocate xmlTextWriter");
xmlTextWriterStartElement(writer, (xmlChar *) xexpr->name); xmlTextWriterStartElement(writer, (xmlChar *) xexpr->name);
forboth(arg, named_arg_strings, narg, xexpr->arg_names) forboth(arg, named_arg_strings, narg, xexpr->arg_names)
{
char *str = (char *) lfirst(arg);
char *argname = strVal(lfirst(narg));
if (str)
{ {
xmlTextWriterWriteAttribute(writer, char *str = (char *) lfirst(arg);
(xmlChar *) argname, char *argname = strVal(lfirst(narg));
(xmlChar *) str);
pfree(str); if (str)
{
xmlTextWriterWriteAttribute(writer,
(xmlChar *) argname,
(xmlChar *) str);
pfree(str);
}
} }
}
foreach(arg, arg_strings) foreach(arg, arg_strings)
{ {
char *str = (char *) lfirst(arg); char *str = (char *) lfirst(arg);
xmlTextWriterWriteRaw(writer, (xmlChar *) str); xmlTextWriterWriteRaw(writer, (xmlChar *) str);
} }
xmlTextWriterEndElement(writer); xmlTextWriterEndElement(writer);
/* we MUST do this now to flush data out to the buffer ... */ /* we MUST do this now to flush data out to the buffer ... */
xmlFreeTextWriter(writer); xmlFreeTextWriter(writer);
writer = NULL; writer = NULL;
result = xmlBuffer_to_xmltype(buf); result = xmlBuffer_to_xmltype(buf);
} }
PG_CATCH(); PG_CATCH();
{ {
@ -934,7 +933,7 @@ xml_init(void)
resetStringInfo(xml_err_buf); resetStringInfo(xml_err_buf);
/* /*
* We re-establish the error callback function every time. This makes * We re-establish the error callback function every time. This makes
* it safe for other subsystems (PL/Perl, say) to also use libxml with * it safe for other subsystems (PL/Perl, say) to also use libxml with
* their own callbacks ... so long as they likewise set up the * their own callbacks ... so long as they likewise set up the
* callbacks on every use. It's cheap enough to not be worth worrying * callbacks on every use. It's cheap enough to not be worth worrying
@ -976,7 +975,7 @@ xml_init(void)
static xmlChar * static xmlChar *
xml_pnstrdup(const xmlChar *str, size_t len) xml_pnstrdup(const xmlChar *str, size_t len)
{ {
xmlChar *result; xmlChar *result;
result = (xmlChar *) palloc((len + 1) * sizeof(xmlChar)); result = (xmlChar *) palloc((len + 1) * sizeof(xmlChar));
memcpy(result, str, len * sizeof(xmlChar)); memcpy(result, str, len * sizeof(xmlChar));
@ -991,8 +990,8 @@ xml_pnstrdup(const xmlChar *str, size_t len)
* Result is 0 if OK, an error code if not. * Result is 0 if OK, an error code if not.
*/ */
static int static int
parse_xml_decl(const xmlChar * str, size_t *lenp, parse_xml_decl(const xmlChar *str, size_t *lenp,
xmlChar ** version, xmlChar ** encoding, int *standalone) xmlChar **version, xmlChar **encoding, int *standalone)
{ {
const xmlChar *p; const xmlChar *p;
const xmlChar *save_p; const xmlChar *save_p;
@ -1149,7 +1148,7 @@ finished:
* which is the default version specified in SQL:2003. * which is the default version specified in SQL:2003.
*/ */
static bool static bool
print_xml_decl(StringInfo buf, const xmlChar * version, print_xml_decl(StringInfo buf, const xmlChar *version,
pg_enc encoding, int standalone) pg_enc encoding, int standalone)
{ {
xml_init(); /* why is this here? */ xml_init(); /* why is this here? */
@ -1227,51 +1226,51 @@ xml_parse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace,
/* Use a TRY block to ensure the ctxt is released */ /* Use a TRY block to ensure the ctxt is released */
PG_TRY(); PG_TRY();
{ {
if (xmloption_arg == XMLOPTION_DOCUMENT) if (xmloption_arg == XMLOPTION_DOCUMENT)
{
/*
* Note, that here we try to apply DTD defaults
* (XML_PARSE_DTDATTR) according to SQL/XML:10.16.7.d: 'Default
* values defined by internal DTD are applied'. As for external
* DTDs, we try to support them too, (see SQL/XML:10.16.7.e)
*/
doc = xmlCtxtReadDoc(ctxt, utf8string,
NULL,
"UTF-8",
XML_PARSE_NOENT | XML_PARSE_DTDATTR
| (preserve_whitespace ? 0 : XML_PARSE_NOBLANKS));
if (doc == NULL)
xml_ereport(ERROR, ERRCODE_INVALID_XML_DOCUMENT,
"invalid XML document");
}
else
{
int res_code;
size_t count;
xmlChar *version = NULL;
int standalone = -1;
res_code = parse_xml_decl(utf8string,
&count, &version, NULL, &standalone);
if (res_code != 0)
xml_ereport_by_code(ERROR, ERRCODE_INVALID_XML_CONTENT,
"invalid XML content: invalid XML declaration",
res_code);
doc = xmlNewDoc(version);
Assert(doc->encoding == NULL);
doc->encoding = xmlStrdup((const xmlChar *) "UTF-8");
doc->standalone = standalone;
res_code = xmlParseBalancedChunkMemory(doc, NULL, NULL, 0,
utf8string + count, NULL);
if (res_code != 0)
{ {
xmlFreeDoc(doc); /*
xml_ereport(ERROR, ERRCODE_INVALID_XML_CONTENT, * Note, that here we try to apply DTD defaults
"invalid XML content"); * (XML_PARSE_DTDATTR) according to SQL/XML:10.16.7.d: 'Default
* values defined by internal DTD are applied'. As for external
* DTDs, we try to support them too, (see SQL/XML:10.16.7.e)
*/
doc = xmlCtxtReadDoc(ctxt, utf8string,
NULL,
"UTF-8",
XML_PARSE_NOENT | XML_PARSE_DTDATTR
| (preserve_whitespace ? 0 : XML_PARSE_NOBLANKS));
if (doc == NULL)
xml_ereport(ERROR, ERRCODE_INVALID_XML_DOCUMENT,
"invalid XML document");
}
else
{
int res_code;
size_t count;
xmlChar *version = NULL;
int standalone = -1;
res_code = parse_xml_decl(utf8string,
&count, &version, NULL, &standalone);
if (res_code != 0)
xml_ereport_by_code(ERROR, ERRCODE_INVALID_XML_CONTENT,
"invalid XML content: invalid XML declaration",
res_code);
doc = xmlNewDoc(version);
Assert(doc->encoding == NULL);
doc->encoding = xmlStrdup((const xmlChar *) "UTF-8");
doc->standalone = standalone;
res_code = xmlParseBalancedChunkMemory(doc, NULL, NULL, 0,
utf8string + count, NULL);
if (res_code != 0)
{
xmlFreeDoc(doc);
xml_ereport(ERROR, ERRCODE_INVALID_XML_CONTENT,
"invalid XML content");
}
} }
}
} }
PG_CATCH(); PG_CATCH();
{ {
@ -1355,8 +1354,7 @@ xml_pstrdup(const char *string)
{ {
return MemoryContextStrdup(LibxmlContext, string); return MemoryContextStrdup(LibxmlContext, string);
} }
#endif /* USE_LIBXMLCONTEXT */
#endif /* USE_LIBXMLCONTEXT */
/* /*
@ -1580,7 +1578,7 @@ map_sql_identifier_to_xml_name(char *ident, bool fully_escaped,
static char * static char *
unicode_to_sqlchar(pg_wchar c) unicode_to_sqlchar(pg_wchar c)
{ {
unsigned char utf8string[5]; /* need room for trailing zero */ unsigned char utf8string[5]; /* need room for trailing zero */
char *result; char *result;
memset(utf8string, 0, sizeof(utf8string)); memset(utf8string, 0, sizeof(utf8string));
@ -1610,7 +1608,7 @@ unicode_to_sqlchar(pg_wchar c)
result = (char *) pg_do_encoding_conversion(utf8string, result = (char *) pg_do_encoding_conversion(utf8string,
pg_encoding_mblen(PG_UTF8, pg_encoding_mblen(PG_UTF8,
(char *) utf8string), (char *) utf8string),
PG_UTF8, PG_UTF8,
GetDatabaseEncoding()); GetDatabaseEncoding());
/* if pg_do_encoding_conversion didn't strdup, we must */ /* if pg_do_encoding_conversion didn't strdup, we must */
@ -1806,10 +1804,10 @@ map_sql_value_to_xml_value(Datum value, Oid type)
if (xmlbinary == XMLBINARY_BASE64) if (xmlbinary == XMLBINARY_BASE64)
xmlTextWriterWriteBase64(writer, VARDATA_ANY(bstr), xmlTextWriterWriteBase64(writer, VARDATA_ANY(bstr),
0, VARSIZE_ANY_EXHDR(bstr)); 0, VARSIZE_ANY_EXHDR(bstr));
else else
xmlTextWriterWriteBinHex(writer, VARDATA_ANY(bstr), xmlTextWriterWriteBinHex(writer, VARDATA_ANY(bstr),
0, VARSIZE_ANY_EXHDR(bstr)); 0, VARSIZE_ANY_EXHDR(bstr));
/* we MUST do this now to flush data out to the buffer */ /* we MUST do this now to flush data out to the buffer */
xmlFreeTextWriter(writer); xmlFreeTextWriter(writer);
@ -3411,7 +3409,7 @@ xpath(PG_FUNCTION_ARGS)
xpath_expr = (xmlChar *) palloc((xpath_len + 5) * sizeof(xmlChar)); xpath_expr = (xmlChar *) palloc((xpath_len + 5) * sizeof(xmlChar));
memcpy (string, datastr, len); memcpy(string, datastr, len);
string[len] = '\0'; string[len] = '\0';
xml_init(); xml_init();
@ -3419,146 +3417,149 @@ xpath(PG_FUNCTION_ARGS)
PG_TRY(); PG_TRY();
{ {
/*
* redundant XML parsing (two parsings for the same value during one
* command execution are possible)
*/
ctxt = xmlNewParserCtxt();
if (ctxt == NULL)
xml_ereport(ERROR, ERRCODE_OUT_OF_MEMORY,
"could not allocate parser context");
doc = xmlCtxtReadMemory(ctxt, (char *) string, len, NULL, NULL, 0);
if (doc == NULL || xmlDocGetRootElement(doc) == NULL)
{
/* /*
* In case we have a fragment rather than a well-formed XML document, * redundant XML parsing (two parsings for the same value during one
* which has a single root (XML well-formedness), we try again after * command execution are possible)
* transforming the xml by stripping away the XML prolog, if any, and
* wrapping the remainder in a dummy element (<x>...</x>),
* and later extending the XPath expression accordingly.
*/ */
if (len >= 5 && ctxt = xmlNewParserCtxt();
xmlStrncmp((xmlChar *) datastr, (xmlChar *) "<?xml", 5) == 0) if (ctxt == NULL)
{ xml_ereport(ERROR, ERRCODE_OUT_OF_MEMORY,
i = 5; "could not allocate parser context");
while (i < len &&
!(datastr[i - 1] == '?' && datastr[i] == '>'))
i++;
if (i == len)
xml_ereport(ERROR, ERRCODE_INTERNAL_ERROR,
"could not parse XML data");
++i;
datastr += i;
len -= i;
}
memcpy(string, "<x>", 3);
memcpy(string + 3, datastr, len);
memcpy(string + 3 + len, "</x>", 5);
len += 7;
doc = xmlCtxtReadMemory(ctxt, (char *) string, len, NULL, NULL, 0); doc = xmlCtxtReadMemory(ctxt, (char *) string, len, NULL, NULL, 0);
if (doc == NULL) if (doc == NULL || xmlDocGetRootElement(doc) == NULL)
xml_ereport(ERROR, ERRCODE_INVALID_XML_DOCUMENT,
"could not parse XML data");
/* we already know xpath_len > 0 - see above , so this test is safe */
if (*VARDATA(xpath_expr_text) == '/')
{ {
memcpy(xpath_expr, "/x", 2); /*
memcpy(xpath_expr + 2, VARDATA(xpath_expr_text), xpath_len); * In case we have a fragment rather than a well-formed XML
xpath_expr[xpath_len + 2] = '\0'; * document, which has a single root (XML well-formedness), we try
xpath_len += 2; * again after transforming the xml by stripping away the XML
* prolog, if any, and wrapping the remainder in a dummy element
* (<x>...</x>), and later extending the XPath expression
* accordingly.
*/
if (len >= 5 &&
xmlStrncmp((xmlChar *) datastr, (xmlChar *) "<?xml", 5) == 0)
{
i = 5;
while (i < len &&
!(datastr[i - 1] == '?' && datastr[i] == '>'))
i++;
if (i == len)
xml_ereport(ERROR, ERRCODE_INTERNAL_ERROR,
"could not parse XML data");
++i;
datastr += i;
len -= i;
}
memcpy(string, "<x>", 3);
memcpy(string + 3, datastr, len);
memcpy(string + 3 + len, "</x>", 5);
len += 7;
doc = xmlCtxtReadMemory(ctxt, (char *) string, len, NULL, NULL, 0);
if (doc == NULL)
xml_ereport(ERROR, ERRCODE_INVALID_XML_DOCUMENT,
"could not parse XML data");
/*
* we already know xpath_len > 0 - see above , so this test is
* safe
*/
if (*VARDATA(xpath_expr_text) == '/')
{
memcpy(xpath_expr, "/x", 2);
memcpy(xpath_expr + 2, VARDATA(xpath_expr_text), xpath_len);
xpath_expr[xpath_len + 2] = '\0';
xpath_len += 2;
}
else
{
memcpy(xpath_expr, "/x//", 4);
memcpy(xpath_expr + 4, VARDATA(xpath_expr_text), xpath_len);
xpath_expr[xpath_len + 4] = '\0';
xpath_len += 4;
}
} }
else else
{ {
memcpy(xpath_expr, "/x//", 4); /*
memcpy(xpath_expr + 4, VARDATA(xpath_expr_text), xpath_len); * if we didn't need to mangle the XML, we don't need to mangle
xpath_expr[xpath_len + 4] = '\0'; * the xpath either.
xpath_len += 4; */
memcpy(xpath_expr, VARDATA(xpath_expr_text), xpath_len);
xpath_expr[xpath_len] = '\0';
} }
} xpathctx = xmlXPathNewContext(doc);
else if (xpathctx == NULL)
{ xml_ereport(ERROR, ERRCODE_OUT_OF_MEMORY,
/* "could not allocate XPath context");
* if we didn't need to mangle the XML, we don't need to mangle the xpathctx->node = xmlDocGetRootElement(doc);
* xpath either. if (xpathctx->node == NULL)
*/ xml_ereport(ERROR, ERRCODE_INTERNAL_ERROR,
memcpy(xpath_expr, VARDATA(xpath_expr_text), xpath_len); "could not find root XML element");
xpath_expr[xpath_len] = '\0';
}
xpathctx = xmlXPathNewContext(doc); /* register namespaces, if any */
if (xpathctx == NULL) if (ns_count > 0)
xml_ereport(ERROR, ERRCODE_OUT_OF_MEMORY,
"could not allocate XPath context");
xpathctx->node = xmlDocGetRootElement(doc);
if (xpathctx->node == NULL)
xml_ereport(ERROR, ERRCODE_INTERNAL_ERROR,
"could not find root XML element");
/* register namespaces, if any */
if (ns_count > 0)
{
for (i = 0; i < ns_count; i++)
{ {
char *ns_name; for (i = 0; i < ns_count; i++)
char *ns_uri; {
char *ns_name;
char *ns_uri;
if (ns_names_uris_nulls[i * 2] || if (ns_names_uris_nulls[i * 2] ||
ns_names_uris_nulls[i * 2 + 1]) ns_names_uris_nulls[i * 2 + 1])
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
errmsg("neither namespace name nor URI may be null"))); errmsg("neither namespace name nor URI may be null")));
ns_name = _textout(ns_names_uris[i * 2]); ns_name = _textout(ns_names_uris[i * 2]);
ns_uri = _textout(ns_names_uris[i * 2 + 1]); ns_uri = _textout(ns_names_uris[i * 2 + 1]);
if (xmlXPathRegisterNs(xpathctx, if (xmlXPathRegisterNs(xpathctx,
(xmlChar *) ns_name, (xmlChar *) ns_name,
(xmlChar *) ns_uri) != 0) (xmlChar *) ns_uri) != 0)
ereport(ERROR, /* is this an internal error??? */ ereport(ERROR, /* is this an internal error??? */
(errmsg("could not register XML namespace with name \"%s\" and URI \"%s\"", (errmsg("could not register XML namespace with name \"%s\" and URI \"%s\"",
ns_name, ns_uri))); ns_name, ns_uri)));
}
} }
}
xpathcomp = xmlXPathCompile(xpath_expr); xpathcomp = xmlXPathCompile(xpath_expr);
if (xpathcomp == NULL) /* TODO: show proper XPath error details */ if (xpathcomp == NULL) /* TODO: show proper XPath error details */
xml_ereport(ERROR, ERRCODE_INTERNAL_ERROR, xml_ereport(ERROR, ERRCODE_INTERNAL_ERROR,
"invalid XPath expression"); "invalid XPath expression");
xpathobj = xmlXPathCompiledEval(xpathcomp, xpathctx); xpathobj = xmlXPathCompiledEval(xpathcomp, xpathctx);
if (xpathobj == NULL) /* TODO: reason? */ if (xpathobj == NULL) /* TODO: reason? */
xml_ereport(ERROR, ERRCODE_INTERNAL_ERROR, xml_ereport(ERROR, ERRCODE_INTERNAL_ERROR,
"could not create XPath object"); "could not create XPath object");
/* return empty array in cases when nothing is found */ /* return empty array in cases when nothing is found */
if (xpathobj->nodesetval == NULL) if (xpathobj->nodesetval == NULL)
res_nitems = 0; res_nitems = 0;
else else
res_nitems = xpathobj->nodesetval->nodeNr; res_nitems = xpathobj->nodesetval->nodeNr;
if (res_nitems) if (res_nitems)
{
for (i = 0; i < xpathobj->nodesetval->nodeNr; i++)
{ {
Datum elem; for (i = 0; i < xpathobj->nodesetval->nodeNr; i++)
bool elemisnull = false; {
Datum elem;
bool elemisnull = false;
elem = PointerGetDatum(xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[i])); elem = PointerGetDatum(xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[i]));
astate = accumArrayResult(astate, elem, astate = accumArrayResult(astate, elem,
elemisnull, XMLOID, elemisnull, XMLOID,
CurrentMemoryContext); CurrentMemoryContext);
}
} }
} }
}
PG_CATCH(); PG_CATCH();
{ {
if (xpathobj) if (xpathobj)