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++;
}
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);
}
}
/*
* 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 (< 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;
appendStringInfoString(&buf, "<element>");
appendStringInfoString(&buf,
map_sql_value_to_xml_value(elem_values[i],
- elmtype));
+ elmtype, true));
appendStringInfoString(&buf, "</element>");
}
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 */
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);
}
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="<>&"'" funnier="b<a/>r"/>
+(1 row)
+
SELECT xmlparse(content 'abc');
xmlparse
----------
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.