aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2007-01-10 20:33:54 +0000
committerPeter Eisentraut <peter_e@gmx.net>2007-01-10 20:33:54 +0000
commitc0e977c18f1939cb0d948c51740aa8816d69c720 (patch)
tree71d15c5d3d7e793ff4beacfce21eb27b3d4c9d66 /src
parentf21d5b61ce4ecd60d4d671990f9c6b886e234809 (diff)
downloadpostgresql-c0e977c18f1939cb0d948c51740aa8816d69c720.tar.gz
postgresql-c0e977c18f1939cb0d948c51740aa8816d69c720.zip
Use libxml's xmlwriter API for producing XML elements, instead of doing
our own printing dance. This does a better job of quoting and escaping the values.
Diffstat (limited to 'src')
-rw-r--r--src/backend/executor/execQual.c57
-rw-r--r--src/backend/utils/adt/xml.c74
-rw-r--r--src/include/utils/xml.h4
3 files changed, 81 insertions, 54 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index c23680f11be..994f7d57ac4 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.204 2007/01/07 22:49:55 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.205 2007/01/10 20:33:54 petere Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2654,7 +2654,6 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
char *str;
ListCell *arg;
ListCell *narg;
- bool found_arg;
int i;
if (isDone)
@@ -2682,55 +2681,6 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
}
break;
- case IS_XMLELEMENT:
- initStringInfo(&buf);
- *isNull = false;
- appendStringInfo(&buf, "<%s", xexpr->name);
- i = 0;
- forboth(arg, xmlExpr->named_args, narg, xexpr->arg_names)
- {
- ExprState *e = (ExprState *) lfirst(arg);
- char *argname = strVal(lfirst(narg));
-
- value = ExecEvalExpr(e, econtext, &isnull, NULL);
- if (!isnull)
- {
- str = OutputFunctionCall(&xmlExpr->named_outfuncs[i],
- value);
- appendStringInfo(&buf, " %s=\"%s\"", argname, str);
- pfree(str);
- }
- i++;
- }
-
- found_arg = false;
- foreach(arg, xmlExpr->args)
- {
- ExprState *e = (ExprState *) lfirst(arg);
-
- value = ExecEvalExpr(e, econtext, &isnull, NULL);
- if (!isnull)
- {
- if (!found_arg)
- {
- appendStringInfoChar(&buf, '>');
- found_arg = true;
- }
-
- /* we know the value is XML type */
- str = DatumGetCString(DirectFunctionCall1(xml_out,
- value));
- appendStringInfoString(&buf, str);
- pfree(str);
- }
- }
-
- if (!found_arg)
- appendStringInfo(&buf, "/>");
- else
- appendStringInfo(&buf, "</%s>", xexpr->name);
- break;
-
case IS_XMLFOREST:
initStringInfo(&buf);
i = 0;
@@ -2754,6 +2704,11 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
break;
/* The remaining cases don't need to set up buf */
+ case IS_XMLELEMENT:
+ *isNull = false;
+ return PointerGetDatum(xmlelement(xmlExpr, econtext));
+ break;
+
case IS_XMLPARSE:
{
ExprState *e;
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index 5137834efb1..5616259b29e 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.13 2007/01/07 22:49:56 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.14 2007/01/10 20:33:54 petere Exp $
*
*-------------------------------------------------------------------------
*/
@@ -32,8 +32,10 @@
#include <libxml/uri.h>
#include <libxml/xmlerror.h>
#include <libxml/xmlsave.h>
+#include <libxml/xmlwriter.h>
#endif /* USE_LIBXML */
+#include "executor/executor.h"
#include "fmgr.h"
#include "libpq/pqformat.h"
#include "mb/pg_wchar.h"
@@ -240,6 +242,71 @@ texttoxml(PG_FUNCTION_ARGS)
xmltype *
+xmlelement(XmlExprState *xmlExpr, ExprContext *econtext)
+{
+#ifdef USE_LIBXML
+ XmlExpr *xexpr = (XmlExpr *) xmlExpr->xprstate.expr;
+ int i;
+ ListCell *arg;
+ ListCell *narg;
+ bool isnull;
+ xmltype *result;
+ Datum value;
+ char *str;
+
+ xmlBufferPtr buf;
+ xmlTextWriterPtr writer;
+
+ buf = xmlBufferCreate();
+ writer = xmlNewTextWriterMemory(buf, 0);
+
+ xmlTextWriterStartElement(writer, (xmlChar *) xexpr->name);
+
+ i = 0;
+ forboth(arg, xmlExpr->named_args, narg, xexpr->arg_names)
+ {
+ ExprState *e = (ExprState *) lfirst(arg);
+ char *argname = strVal(lfirst(narg));
+
+ value = ExecEvalExpr(e, econtext, &isnull, NULL);
+ if (!isnull)
+ {
+ str = OutputFunctionCall(&xmlExpr->named_outfuncs[i], value);
+ xmlTextWriterWriteAttribute(writer, (xmlChar *) argname, (xmlChar *) str);
+ pfree(str);
+ }
+ i++;
+ }
+
+ foreach(arg, xmlExpr->args)
+ {
+ ExprState *e = (ExprState *) lfirst(arg);
+
+ value = ExecEvalExpr(e, econtext, &isnull, NULL);
+ if (!isnull)
+ {
+ /* we know the value is XML type */
+ str = DatumGetCString(DirectFunctionCall1(xml_out,
+ value));
+ xmlTextWriterWriteRaw(writer, (xmlChar *) str);
+ pfree(str);
+ }
+ }
+
+ xmlTextWriterEndElement(writer);
+ xmlFreeTextWriter(writer);
+
+ result = xmlBuffer_to_xmltype(buf);
+ xmlBufferFree(buf);
+ return result;
+#else
+ NO_XML_SUPPORT();
+ return NULL;
+#endif
+}
+
+
+xmltype *
xmlparse(text *data, bool is_document, bool preserve_whitespace)
{
#ifdef USE_LIBXML
@@ -313,6 +380,7 @@ xmltype *
xmlroot(xmltype *data, text *version, int standalone)
{
#ifdef USE_LIBXML
+ xmltype *result;
xmlDocPtr doc;
xmlBufferPtr buffer;
xmlSaveCtxtPtr save;
@@ -344,7 +412,9 @@ xmlroot(xmltype *data, text *version, int standalone)
xmlFreeDoc(doc);
- return xmlBuffer_to_xmltype(buffer);
+ result = xmlBuffer_to_xmltype(buffer);
+ xmlBufferFree(buffer);
+ return result;
#else
NO_XML_SUPPORT();
return NULL;
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index 4d98f179124..c4e508c488d 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -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/include/utils/xml.h,v 1.7 2007/01/07 22:49:56 petere Exp $
+ * $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.8 2007/01/10 20:33:54 petere Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,6 +16,7 @@
#define XML_H
#include "fmgr.h"
+#include "nodes/execnodes.h"
typedef struct varlena xmltype;
@@ -32,6 +33,7 @@ extern Datum xmlcomment(PG_FUNCTION_ARGS);
extern Datum texttoxml(PG_FUNCTION_ARGS);
extern Datum xmlvalidate(PG_FUNCTION_ARGS);
+extern xmltype *xmlelement(XmlExprState *xmlExpr, ExprContext *econtext);
extern xmltype *xmlparse(text *data, bool is_doc, bool preserve_whitespace);
extern xmltype *xmlpi(char *target, text *arg, bool arg_is_null, bool *result_is_null);
extern xmltype *xmlroot(xmltype *data, text *version, int standalone);