]> granicus.if.org Git - postgresql/commitdiff
De-escape XML names when reverse-compiling XML expressions.
authorPeter Eisentraut <peter_e@gmx.net>
Fri, 29 Dec 2006 10:50:22 +0000 (10:50 +0000)
committerPeter Eisentraut <peter_e@gmx.net>
Fri, 29 Dec 2006 10:50:22 +0000 (10:50 +0000)
src/backend/utils/adt/ruleutils.c
src/backend/utils/adt/xml.c
src/include/utils/xml.h

index 699b4a9370462431f72d0b6223fae151cf3da660..136f1386cfafe9710272630bf6b320242fe43e86 100644 (file)
@@ -2,7 +2,7 @@
  * ruleutils.c - Functions to convert stored expressions/querytrees
  *                             back to source text
  *
- *       $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.238 2006/12/24 00:29:19 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.239 2006/12/29 10:50:22 petere Exp $
  **********************************************************************/
 
 #include "postgres.h"
@@ -3810,11 +3810,8 @@ get_rule_expr(Node *node, deparse_context *context,
                                }
                                if (xexpr->name)
                                {
-                                       /*
-                                        * XXX need to de-escape the name
-                                        */
                                        appendStringInfo(buf, "NAME %s",
-                                                                        quote_identifier(xexpr->name));
+                                                                        quote_identifier(map_xml_name_to_sql_identifier(xexpr->name)));
                                        needcomma = true;
                                }
                                if (xexpr->named_args)
@@ -3834,11 +3831,8 @@ get_rule_expr(Node *node, deparse_context *context,
                                                if (needcomma)
                                                        appendStringInfoString(buf, ", ");
                                                get_rule_expr((Node *) e, context, true);
-                                               /*
-                                                * XXX need to de-escape the name
-                                                */
                                                appendStringInfo(buf, " AS %s",
-                                                                                quote_identifier(argname));
+                                                                                quote_identifier(map_xml_name_to_sql_identifier(argname)));
                                                needcomma = true;
                                        }
                                        if (xexpr->op != IS_XMLFOREST)
index 6cde8d6aa498cc08f8c6ec59e9612cc87ef0d03d..6f4c87f824fab1fb73ee4776a2a7298896a9947e 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.7 2006/12/28 14:28:36 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.8 2006/12/29 10:50:22 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -882,6 +882,42 @@ sqlchar_to_unicode(char *s)
 }
 
 
+static char *
+unicode_to_sqlchar(pg_wchar c)
+{
+       char utf8string[4] = { '\0', '\0', '\0', '\0' };
+
+       if (c <= 0x7F)
+       {
+               utf8string[0] = c;
+       }
+       else if (c <= 0x7FF)
+       {
+               utf8string[0] = 0xC0 | ((c >> 6) & 0x1F);
+               utf8string[1] = 0x80 | (c & 0x3F);
+       }
+       else if (c <= 0xFFFF)
+       {
+               utf8string[0] = 0xE0 | ((c >> 12) & 0x0F);
+               utf8string[1] = 0x80 | ((c >> 6) & 0x3F);
+               utf8string[2] = 0x80 | (c & 0x3F);
+       }
+       else
+       {
+               utf8string[0] = 0xF0 | ((c >> 18) & 0x07);
+               utf8string[1] = 0x80 | ((c >> 12) & 0x3F);
+               utf8string[2] = 0x80 | ((c >> 6) & 0x3F);
+               utf8string[3] = 0x80 | (c & 0x3F);
+
+       }
+
+       return  (char *) pg_do_encoding_conversion((unsigned char *) utf8string,
+                                                                                          pg_mblen(utf8string),
+                                                                                          PG_UTF8,
+                                                                                          GetDatabaseEncoding());
+}
+
+
 static bool
 is_valid_xml_namefirst(pg_wchar c)
 {
@@ -949,3 +985,37 @@ map_sql_identifier_to_xml_name(char *ident, bool fully_escaped)
        return NULL;
 #endif /* not USE_LIBXML */
 }
+
+
+/*
+ * The inverse; see SQL/XML:2003 section 9.17.
+ */
+char *
+map_xml_name_to_sql_identifier(char *name)
+{
+       StringInfoData buf;
+       char *p;
+
+       initStringInfo(&buf);
+
+       for (p = name; *p; p += pg_mblen(p))
+       {
+               if (*p == '_' && *(p+1) == 'x'
+                       && isxdigit((unsigned char) *(p+2))
+                       && isxdigit((unsigned char) *(p+3))
+                       && isxdigit((unsigned char) *(p+4))
+                       && isxdigit((unsigned char) *(p+5))
+                       && *(p+6) == '_')
+               {
+                       unsigned int u;
+
+                       sscanf(p + 2, "%X", &u);
+                       appendStringInfoString(&buf, unicode_to_sqlchar(u));
+                       p += 6;
+               }
+               else
+                       appendBinaryStringInfo(&buf, p, pg_mblen(p));
+       }
+
+       return buf.data;
+}
index ca501420326278c69468e39256521a1b71134a14..20666a48ccfbfc5b49b79e0cc74467fdb8029e16 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.4 2006/12/28 14:28:36 petere Exp $
+ * $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.5 2006/12/29 10:50:22 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -37,5 +37,6 @@ extern xmltype *xmlpi(char *target, text *arg);
 extern xmltype *xmlroot(xmltype *data, text *version, int standalone);
 
 extern char *map_sql_identifier_to_xml_name(char *ident, bool fully_escaped);
+extern char *map_xml_name_to_sql_identifier(char *name);
 
 #endif /* XML_H */