Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c0e977c

Browse files
committed
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.
1 parent f21d5b6 commit c0e977c

File tree

3 files changed

+81
-54
lines changed

3 files changed

+81
-54
lines changed

src/backend/executor/execQual.c

Lines changed: 6 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.204 2007/01/07 22:49:55 petere Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.205 2007/01/10 20:33:54 petere Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -2654,7 +2654,6 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
26542654
char *str;
26552655
ListCell *arg;
26562656
ListCell *narg;
2657-
bool found_arg;
26582657
int i;
26592658

26602659
if (isDone)
@@ -2682,55 +2681,6 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
26822681
}
26832682
break;
26842683

2685-
case IS_XMLELEMENT:
2686-
initStringInfo(&buf);
2687-
*isNull = false;
2688-
appendStringInfo(&buf, "<%s", xexpr->name);
2689-
i = 0;
2690-
forboth(arg, xmlExpr->named_args, narg, xexpr->arg_names)
2691-
{
2692-
ExprState *e = (ExprState *) lfirst(arg);
2693-
char *argname = strVal(lfirst(narg));
2694-
2695-
value = ExecEvalExpr(e, econtext, &isnull, NULL);
2696-
if (!isnull)
2697-
{
2698-
str = OutputFunctionCall(&xmlExpr->named_outfuncs[i],
2699-
value);
2700-
appendStringInfo(&buf, " %s=\"%s\"", argname, str);
2701-
pfree(str);
2702-
}
2703-
i++;
2704-
}
2705-
2706-
found_arg = false;
2707-
foreach(arg, xmlExpr->args)
2708-
{
2709-
ExprState *e = (ExprState *) lfirst(arg);
2710-
2711-
value = ExecEvalExpr(e, econtext, &isnull, NULL);
2712-
if (!isnull)
2713-
{
2714-
if (!found_arg)
2715-
{
2716-
appendStringInfoChar(&buf, '>');
2717-
found_arg = true;
2718-
}
2719-
2720-
/* we know the value is XML type */
2721-
str = DatumGetCString(DirectFunctionCall1(xml_out,
2722-
value));
2723-
appendStringInfoString(&buf, str);
2724-
pfree(str);
2725-
}
2726-
}
2727-
2728-
if (!found_arg)
2729-
appendStringInfo(&buf, "/>");
2730-
else
2731-
appendStringInfo(&buf, "</%s>", xexpr->name);
2732-
break;
2733-
27342684
case IS_XMLFOREST:
27352685
initStringInfo(&buf);
27362686
i = 0;
@@ -2754,6 +2704,11 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
27542704
break;
27552705

27562706
/* The remaining cases don't need to set up buf */
2707+
case IS_XMLELEMENT:
2708+
*isNull = false;
2709+
return PointerGetDatum(xmlelement(xmlExpr, econtext));
2710+
break;
2711+
27572712
case IS_XMLPARSE:
27582713
{
27592714
ExprState *e;

src/backend/utils/adt/xml.c

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.13 2007/01/07 22:49:56 petere Exp $
10+
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.14 2007/01/10 20:33:54 petere Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -32,8 +32,10 @@
3232
#include <libxml/uri.h>
3333
#include <libxml/xmlerror.h>
3434
#include <libxml/xmlsave.h>
35+
#include <libxml/xmlwriter.h>
3536
#endif /* USE_LIBXML */
3637

38+
#include "executor/executor.h"
3739
#include "fmgr.h"
3840
#include "libpq/pqformat.h"
3941
#include "mb/pg_wchar.h"
@@ -239,6 +241,71 @@ texttoxml(PG_FUNCTION_ARGS)
239241
}
240242

241243

244+
xmltype *
245+
xmlelement(XmlExprState *xmlExpr, ExprContext *econtext)
246+
{
247+
#ifdef USE_LIBXML
248+
XmlExpr *xexpr = (XmlExpr *) xmlExpr->xprstate.expr;
249+
int i;
250+
ListCell *arg;
251+
ListCell *narg;
252+
bool isnull;
253+
xmltype *result;
254+
Datum value;
255+
char *str;
256+
257+
xmlBufferPtr buf;
258+
xmlTextWriterPtr writer;
259+
260+
buf = xmlBufferCreate();
261+
writer = xmlNewTextWriterMemory(buf, 0);
262+
263+
xmlTextWriterStartElement(writer, (xmlChar *) xexpr->name);
264+
265+
i = 0;
266+
forboth(arg, xmlExpr->named_args, narg, xexpr->arg_names)
267+
{
268+
ExprState *e = (ExprState *) lfirst(arg);
269+
char *argname = strVal(lfirst(narg));
270+
271+
value = ExecEvalExpr(e, econtext, &isnull, NULL);
272+
if (!isnull)
273+
{
274+
str = OutputFunctionCall(&xmlExpr->named_outfuncs[i], value);
275+
xmlTextWriterWriteAttribute(writer, (xmlChar *) argname, (xmlChar *) str);
276+
pfree(str);
277+
}
278+
i++;
279+
}
280+
281+
foreach(arg, xmlExpr->args)
282+
{
283+
ExprState *e = (ExprState *) lfirst(arg);
284+
285+
value = ExecEvalExpr(e, econtext, &isnull, NULL);
286+
if (!isnull)
287+
{
288+
/* we know the value is XML type */
289+
str = DatumGetCString(DirectFunctionCall1(xml_out,
290+
value));
291+
xmlTextWriterWriteRaw(writer, (xmlChar *) str);
292+
pfree(str);
293+
}
294+
}
295+
296+
xmlTextWriterEndElement(writer);
297+
xmlFreeTextWriter(writer);
298+
299+
result = xmlBuffer_to_xmltype(buf);
300+
xmlBufferFree(buf);
301+
return result;
302+
#else
303+
NO_XML_SUPPORT();
304+
return NULL;
305+
#endif
306+
}
307+
308+
242309
xmltype *
243310
xmlparse(text *data, bool is_document, bool preserve_whitespace)
244311
{
@@ -313,6 +380,7 @@ xmltype *
313380
xmlroot(xmltype *data, text *version, int standalone)
314381
{
315382
#ifdef USE_LIBXML
383+
xmltype *result;
316384
xmlDocPtr doc;
317385
xmlBufferPtr buffer;
318386
xmlSaveCtxtPtr save;
@@ -344,7 +412,9 @@ xmlroot(xmltype *data, text *version, int standalone)
344412

345413
xmlFreeDoc(doc);
346414

347-
return xmlBuffer_to_xmltype(buffer);
415+
result = xmlBuffer_to_xmltype(buffer);
416+
xmlBufferFree(buffer);
417+
return result;
348418
#else
349419
NO_XML_SUPPORT();
350420
return NULL;

src/include/utils/xml.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.7 2007/01/07 22:49:56 petere Exp $
10+
* $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.8 2007/01/10 20:33:54 petere Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -16,6 +16,7 @@
1616
#define XML_H
1717

1818
#include "fmgr.h"
19+
#include "nodes/execnodes.h"
1920

2021
typedef struct varlena xmltype;
2122

@@ -32,6 +33,7 @@ extern Datum xmlcomment(PG_FUNCTION_ARGS);
3233
extern Datum texttoxml(PG_FUNCTION_ARGS);
3334
extern Datum xmlvalidate(PG_FUNCTION_ARGS);
3435

36+
extern xmltype *xmlelement(XmlExprState *xmlExpr, ExprContext *econtext);
3537
extern xmltype *xmlparse(text *data, bool is_doc, bool preserve_whitespace);
3638
extern xmltype *xmlpi(char *target, text *arg, bool arg_is_null, bool *result_is_null);
3739
extern xmltype *xmlroot(xmltype *data, text *version, int standalone);

0 commit comments

Comments
 (0)