diff options
Diffstat (limited to 'src/backend/utils/adt/xml.c')
-rw-r--r-- | src/backend/utils/adt/xml.c | 98 |
1 files changed, 97 insertions, 1 deletions
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c index 5f3fafe1e70..fdf7f8e0a91 100644 --- a/src/backend/utils/adt/xml.c +++ b/src/backend/utils/adt/xml.c @@ -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) { |