aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/executor/execQual.c4
-rw-r--r--src/backend/utils/adt/xml.c25
-rw-r--r--src/include/utils/xml.h4
-rw-r--r--src/test/regress/expected/xml.out6
-rw-r--r--src/test/regress/expected/xml_1.out4
-rw-r--r--src/test/regress/sql/xml.sql1
6 files changed, 32 insertions, 12 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index c7bfe7c76ca..65bf01c6a8e 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.247 2009/06/04 18:33:07 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.248 2009/06/09 22:00:57 petere Exp $
*
*-------------------------------------------------------------------------
*/
@@ -3243,7 +3243,7 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
{
appendStringInfo(&buf, "<%s>%s</%s>",
argname,
- map_sql_value_to_xml_value(value, exprType((Node *) e->expr)),
+ map_sql_value_to_xml_value(value, exprType((Node *) e->expr), true),
argname);
*isNull = false;
}
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index 57e9595af8d..fca92e867d0 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.89 2009/06/08 21:32:33 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.90 2009/06/09 22:00:57 petere Exp $
*
*-------------------------------------------------------------------------
*/
@@ -569,7 +569,7 @@ xmlelement(XmlExprState *xmlExpr, ExprContext *econtext)
if (isnull)
str = NULL;
else
- str = map_sql_value_to_xml_value(value, exprType((Node *) e->expr));
+ str = map_sql_value_to_xml_value(value, exprType((Node *) e->expr), false);
named_arg_strings = lappend(named_arg_strings, str);
i++;
}
@@ -587,7 +587,7 @@ xmlelement(XmlExprState *xmlExpr, ExprContext *econtext)
if (!isnull)
{
str = map_sql_value_to_xml_value(value,
- exprType((Node *) e->expr));
+ exprType((Node *) e->expr), true);
arg_strings = lappend(arg_strings, str);
}
}
@@ -1580,9 +1580,18 @@ map_xml_name_to_sql_identifier(char *name)
/*
* Map SQL value to XML value; see SQL/XML:2003 section 9.16.
+ *
+ * When xml_escape_strings is true, then certain characters in string
+ * values are replaced by entity references (&lt; etc.), as specified
+ * in SQL/XML:2003 section 9.16 GR 8) ii). This is normally what is
+ * wanted. The false case is mainly useful when the resulting value
+ * is used with xmlTextWriterWriteAttribute() to write out an
+ * attribute, because that function does the escaping itself. The SQL
+ * standard of 2003 is somewhat buggy in this regard, so we do our
+ * best to make sense.
*/
char *
-map_sql_value_to_xml_value(Datum value, Oid type)
+map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings)
{
StringInfoData buf;
@@ -1616,7 +1625,7 @@ map_sql_value_to_xml_value(Datum value, Oid type)
appendStringInfoString(&buf, "<element>");
appendStringInfoString(&buf,
map_sql_value_to_xml_value(elem_values[i],
- elmtype));
+ elmtype, true));
appendStringInfoString(&buf, "</element>");
}
@@ -1774,8 +1783,8 @@ map_sql_value_to_xml_value(Datum value, Oid type)
getTypeOutputInfo(type, &typeOut, &isvarlena);
str = OidOutputFunctionCall(typeOut, value);
- /* ... exactly as-is for XML */
- if (type == XMLOID)
+ /* ... exactly as-is for XML, and when escaping is not wanted */
+ if (type == XMLOID || !xml_escape_strings)
return str;
/* otherwise, translate special characters as needed */
@@ -3183,7 +3192,7 @@ SPI_sql_row_to_xmlelement(int rownum, StringInfo result, char *tablename,
appendStringInfo(result, " <%s>%s</%s>\n",
colname,
map_sql_value_to_xml_value(colval,
- SPI_gettypeid(SPI_tuptable->tupdesc, i)),
+ SPI_gettypeid(SPI_tuptable->tupdesc, i), true),
colname);
}
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index f11ec721c48..af953f2b350 100644
--- a/src/include/utils/xml.h
+++ b/src/include/utils/xml.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.26 2009/05/13 20:27:17 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.27 2009/06/09 22:00:57 petere Exp $
*
*-------------------------------------------------------------------------
*/
@@ -73,7 +73,7 @@ extern text *xmltotext_with_xmloption(xmltype *data, XmlOptionType xmloption_arg
extern char *map_sql_identifier_to_xml_name(char *ident, bool fully_escaped, bool escape_period);
extern char *map_xml_name_to_sql_identifier(char *name);
-extern char *map_sql_value_to_xml_value(Datum value, Oid type);
+extern char *map_sql_value_to_xml_value(Datum value, Oid type, bool xml_escape_strings);
typedef enum
{
diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out
index 30b332aecca..ecca5896a70 100644
--- a/src/test/regress/expected/xml.out
+++ b/src/test/regress/expected/xml.out
@@ -188,6 +188,12 @@ SELECT xmlelement(name foo, xmlattributes('2009-04-09 00:24:37'::timestamp as ba
SELECT xmlelement(name foo, xmlattributes('infinity'::timestamp as bar));
ERROR: timestamp out of range
DETAIL: XML does not support infinite timestamp values.
+SELECT xmlelement(name foo, xmlattributes('<>&"''' as funny, xml 'b<a/>r' as funnier));
+ xmlelement
+------------------------------------------------------------
+ <foo funny="&lt;&gt;&amp;&quot;'" funnier="b&lt;a/&gt;r"/>
+(1 row)
+
SELECT xmlparse(content 'abc');
xmlparse
----------
diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out
index c8eb1e425e2..d542b0689a9 100644
--- a/src/test/regress/expected/xml_1.out
+++ b/src/test/regress/expected/xml_1.out
@@ -160,6 +160,10 @@ SELECT xmlelement(name foo, xmlattributes('infinity'::timestamp as bar));
ERROR: unsupported XML feature
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
+SELECT xmlelement(name foo, xmlattributes('<>&"''' as funny, xml 'b<a/>r' as funnier));
+ERROR: unsupported XML feature
+DETAIL: This functionality requires the server to be built with libxml support.
+HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlparse(content 'abc');
ERROR: unsupported XML feature
DETAIL: This functionality requires the server to be built with libxml support.
diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sql
index 50550aaa358..086eedd2700 100644
--- a/src/test/regress/sql/xml.sql
+++ b/src/test/regress/sql/xml.sql
@@ -57,6 +57,7 @@ SELECT xmlelement(name foo, bytea 'bar');
SELECT xmlelement(name foo, xmlattributes(true as bar));
SELECT xmlelement(name foo, xmlattributes('2009-04-09 00:24:37'::timestamp as bar));
SELECT xmlelement(name foo, xmlattributes('infinity'::timestamp as bar));
+SELECT xmlelement(name foo, xmlattributes('<>&"''' as funny, xml 'b<a/>r' as funnier));
SELECT xmlparse(content 'abc');