diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index e7a37a2cfa62d906fd9bc2d7ee927c4fc755a416..8f34748f9987372ab03f8e52116d3bf428fc0592 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.210 2007/02/03 14:06:54 petere Exp $
+ *	  $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.211 2007/02/11 22:18:15 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1389,7 +1389,7 @@ transformXmlExpr(ParseState *pstate, XmlExpr *x)
 
 	newx->op = x->op;
 	if (x->name)
-		newx->name = map_sql_identifier_to_xml_name(x->name, false);
+		newx->name = map_sql_identifier_to_xml_name(x->name, false, false);
 	else
 		newx->name = NULL;
 
@@ -1411,10 +1411,10 @@ transformXmlExpr(ParseState *pstate, XmlExpr *x)
 		expr = transformExpr(pstate, r->val);
 
 		if (r->name)
-			argname = map_sql_identifier_to_xml_name(r->name, false);
+			argname = map_sql_identifier_to_xml_name(r->name, false, false);
 		else if (IsA(r->val, ColumnRef))
 			argname = map_sql_identifier_to_xml_name(FigureColname(r->val),
-													 true);
+													 true, false);
 		else
 		{
 			ereport(ERROR,
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index 32d26cf3ba7267dc4e3c790327e8e3fa096340d3..2d3a2d963f61ee196cedee577642a4ebde96c398 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.26 2007/02/10 18:47:41 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.27 2007/02/11 22:18:15 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1318,8 +1318,14 @@ is_valid_xml_namechar(pg_wchar c)
  * Map SQL identifier to XML name; see SQL/XML:2003 section 9.1.
  */
 char *
-map_sql_identifier_to_xml_name(char *ident, bool fully_escaped)
+map_sql_identifier_to_xml_name(char *ident, bool fully_escaped, bool escape_period)
 {
+	/*
+	 * SQL/XML doesn't make use of this case anywhere, so it's
+	 * probably a mistake.
+	 */
+	Assert(fully_escaped || !escape_period);
+
 #ifdef USE_LIBXML
 	StringInfoData buf;
 	char *p;
@@ -1340,6 +1346,8 @@ map_sql_identifier_to_xml_name(char *ident, bool fully_escaped)
 			else
 				appendStringInfo(&buf, "_x0058_");
 		}
+		else if (escape_period && *p == '.')
+			appendStringInfo(&buf, "_x002E_");
 		else
 		{
 			pg_wchar u = sqlchar_to_unicode(p);
diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h
index f207917ea85a1bf1dd088314af4b12e70607464e..99ec499c5c9552e13454f1f473308c9627feed40 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.14 2007/02/03 14:06:56 petere Exp $
+ * $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.15 2007/02/11 22:18:16 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,7 +53,7 @@ extern xmltype *xmlroot(xmltype *data, text *version, int standalone);
 extern bool xml_is_document(xmltype *arg);
 extern text *xmltotext_with_xmloption(xmltype *data, XmlOptionType xmloption_arg);
 
-extern char *map_sql_identifier_to_xml_name(char *ident, bool fully_escaped);
+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);