aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/explain.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/explain.c')
-rw-r--r--src/backend/commands/explain.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 124743318d8..0a669d9b43a 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -3312,13 +3312,15 @@ ExplainSeparatePlans(ExplainState *es)
* Optionally, OR in X_NOWHITESPACE to suppress the whitespace we'd normally
* add.
*
- * XML tag names can't contain white space, so we replace any spaces in
- * "tagname" with dashes.
+ * XML restricts tag names more than our other output formats, eg they can't
+ * contain white space or slashes. Replace invalid characters with dashes,
+ * so that for example "I/O Read Time" becomes "I-O-Read-Time".
*/
static void
ExplainXMLTag(const char *tagname, int flags, ExplainState *es)
{
const char *s;
+ const char *valid = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.";
if ((flags & X_NOWHITESPACE) == 0)
appendStringInfoSpaces(es->str, 2 * es->indent);
@@ -3326,7 +3328,7 @@ ExplainXMLTag(const char *tagname, int flags, ExplainState *es)
if ((flags & X_CLOSING) != 0)
appendStringInfoCharMacro(es->str, '/');
for (s = tagname; *s; s++)
- appendStringInfoCharMacro(es->str, (*s == ' ') ? '-' : *s);
+ appendStringInfoChar(es->str, strchr(valid, *s) ? *s : '-');
if ((flags & X_CLOSE_IMMEDIATE) != 0)
appendStringInfoString(es->str, " /");
appendStringInfoCharMacro(es->str, '>');