1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-16 06:01:02 +03:00

Fix xmlconcat by properly merging the XML declarations. Add aggregate

function xmlagg.
This commit is contained in:
Peter Eisentraut
2007-01-20 09:27:20 +00:00
parent 9a83bd50b7
commit b4c8d49036
9 changed files with 171 additions and 19 deletions

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.19 2007/01/19 16:58:46 petere Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.20 2007/01/20 09:27:19 petere Exp $
*
*-------------------------------------------------------------------------
*/
@ -359,6 +359,102 @@ xmlcomment(PG_FUNCTION_ARGS)
}
/*
* TODO: xmlconcat needs to merge the notations and unparsed entities
* of the argument values. Not very important in practice, though.
*/
xmltype *
xmlconcat(List *args)
{
#ifdef USE_LIBXML
StringInfoData buf;
ListCell *v;
int global_standalone = 1;
xmlChar *global_version = NULL;
bool global_version_no_value = false;
initStringInfo(&buf);
foreach(v, args)
{
size_t len;
xmlChar *version;
int standalone;
xmltype *x = DatumGetXmlP(PointerGetDatum(lfirst(v)));
char *str;
len = VARSIZE(x) - VARHDRSZ;
str = palloc(len + 1);
memcpy(str, VARDATA(x), len);
str[len] = '\0';
parse_xml_decl((xmlChar *) str, &len, &version, NULL, &standalone);
if (standalone == 0 && global_standalone == 1)
global_standalone = 0;
if (standalone < 0)
global_standalone = -1;
if (!global_version)
global_version = xmlStrdup(version);
else if (version && xmlStrcmp(version, global_version) != 0)
global_version_no_value = true;
appendStringInfoString(&buf, str + len);
pfree(str);
}
if (!global_version_no_value || global_standalone >= 0)
{
StringInfoData buf2;
initStringInfo(&buf2);
if (!global_version_no_value && global_version)
appendStringInfo(&buf2, "<?xml version=\"%s\"", global_version);
else
appendStringInfo(&buf2, "<?xml version=\"%s\"", PG_XML_DEFAULT_VERSION);
if (global_standalone == 1)
appendStringInfoString(&buf2, " standalone=\"yes\"");
else if (global_standalone == 0)
appendStringInfoString(&buf2, " standalone=\"no\"");
appendStringInfoString(&buf2, "?>");
appendStringInfoString(&buf2, buf.data);
buf = buf2;
}
return stringinfo_to_xmltype(&buf);
#else
NO_XML_SUPPORT();
return NULL;
#endif
}
/*
* XMLAGG support
*/
Datum
xmlconcat2(PG_FUNCTION_ARGS)
{
if (PG_ARGISNULL(0))
{
if (PG_ARGISNULL(1))
PG_RETURN_NULL();
else
PG_RETURN_XML_P(PG_GETARG_XML_P(1));
}
else if (PG_ARGISNULL(1))
PG_RETURN_XML_P(PG_GETARG_XML_P(0));
else
PG_RETURN_XML_P(xmlconcat(list_make2(PG_GETARG_XML_P(0), PG_GETARG_XML_P(1))));
}
Datum
texttoxml(PG_FUNCTION_ARGS)
{