Some fine-tuning of xmlpi in corner cases:
authorPeter Eisentraut <peter_e@gmx.net>
Sun, 7 Jan 2007 22:49:56 +0000 (22:49 +0000)
committerPeter Eisentraut <peter_e@gmx.net>
Sun, 7 Jan 2007 22:49:56 +0000 (22:49 +0000)
- correct error codes
- do syntax checks in correct order
- strip leading spaces of argument

src/backend/executor/execQual.c
src/backend/utils/adt/xml.c
src/include/utils/xml.h
src/test/regress/expected/xml.out
src/test/regress/expected/xml_1.out
src/test/regress/sql/xml.sql

index 1e11743b118e21bf6d567aed6ec6ec5ad455b700..300e5711d584418c7cb30a893f503aebdb904cf7 100644 (file)
@@ -2803,15 +2803,17 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
                                        e = (ExprState *) linitial(xmlExpr->args);
                                        value = ExecEvalExpr(e, econtext, &isnull, NULL);
                                        if (isnull)
-                                               return (Datum) 0;
-                                       arg = DatumGetTextP(value);
+                                               arg = NULL;
+                                       else
+                                               arg = DatumGetTextP(value);
                                }
                                else
+                               {
                                        arg = NULL;
+                                       isnull = false;
+                               }
 
-                               *isNull = false;
-
-                               return PointerGetDatum(xmlpi(xexpr->name, arg));
+                               return PointerGetDatum(xmlpi(xexpr->name, arg, isnull, isNull));
                        }
                        break;
 
index 01e54444d311b245189ef0415fb493d1fc464825..9207f38967bb0be69e91eda72c0c91d4786f417a 100644 (file)
@@ -257,7 +257,7 @@ xmlparse(text *data, bool is_document, bool preserve_whitespace)
 
 
 xmltype *
-xmlpi(char *target, text *arg)
+xmlpi(char *target, text *arg, bool arg_is_null, bool *result_is_null)
 {
 #ifdef USE_LIBXML
        xmltype *result;
@@ -265,10 +265,18 @@ xmlpi(char *target, text *arg)
 
        if (pg_strncasecmp(target, "xml", 3) == 0)
                ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION),
+                               (errcode(ERRCODE_SYNTAX_ERROR), /* really */
                                 errmsg("invalid XML processing instruction"),
                                 errdetail("XML processing instruction target name cannot start with \"xml\".")));
 
+       /*
+        * Following the SQL standard, the null check comes after the
+        * syntax check above.
+        */
+       *result_is_null = arg_is_null;
+       if (*result_is_null)
+               return NULL;            
+
        initStringInfo(&buf);
 
        appendStringInfo(&buf, "<?%s", target);
@@ -286,7 +294,7 @@ xmlpi(char *target, text *arg)
                                 errdetail("XML processing instruction cannot contain \"?>\".")));
 
                appendStringInfoChar(&buf, ' ');
-               appendStringInfoString(&buf, string);
+               appendStringInfoString(&buf, string + strspn(string, " "));
                pfree(string);
        }
        appendStringInfoString(&buf, "?>");
index 2576587b5fb2a8ff5bd799461328e8ec4f8b9e7d..e7ae8e7102c72d24930dd3d2d831c79e163a5e5e 100644 (file)
@@ -33,7 +33,7 @@ extern Datum texttoxml(PG_FUNCTION_ARGS);
 extern Datum xmlvalidate(PG_FUNCTION_ARGS);
 
 extern xmltype *xmlparse(text *data, bool is_doc, bool preserve_whitespace);
-extern xmltype *xmlpi(char *target, text *arg);
+extern xmltype *xmlpi(char *target, text *arg, bool arg_is_null, bool *result_is_null);
 extern xmltype *xmlroot(xmltype *data, text *version, int standalone);
 
 extern char *map_sql_identifier_to_xml_name(char *ident, bool fully_escaped);
index 9ebef1404b91cf32506508b586004d367432a4cc..c0ec868bf8998e2c05d9d89d0000ee3803f091ed 100644 (file)
@@ -124,6 +124,21 @@ SELECT xmlpi(name foo, 'bar');
 SELECT xmlpi(name foo, 'in?>valid');
 ERROR:  invalid XML processing instruction
 DETAIL:  XML processing instruction cannot contain "?>".
+SELECT xmlpi(name foo, null);
+ xmlpi 
+-------
+(1 row)
+
+SELECT xmlpi(name xmlstuff, null);
+ERROR:  invalid XML processing instruction
+DETAIL:  XML processing instruction target name cannot start with "xml".
+SELECT xmlpi(name foo, '   bar');
+    xmlpi    
+-------------
+ <?foo bar?>
+(1 row)
+
 SELECT xmlroot(xml '<foo/>', version no value, standalone no value);
         xmlroot        
 -----------------------
index 662c0e236a8113bd3003a648680ee33563696781..5a1a6ac03199002cae9025f4df9c73767b71c5ee 100644 (file)
@@ -62,6 +62,12 @@ SELECT xmlpi(name foo, 'bar');
 ERROR:  no XML support in this installation
 SELECT xmlpi(name foo, 'in?>valid');
 ERROR:  no XML support in this installation
+SELECT xmlpi(name foo, null);
+ERROR:  no XML support in this installation
+SELECT xmlpi(name xmlstuff, null);
+ERROR:  no XML support in this installation
+SELECT xmlpi(name foo, '   bar');
+ERROR:  no XML support in this installation
 SELECT xmlroot(xml '<foo/>', version no value, standalone no value);
 ERROR:  no XML support in this installation
 SELECT xmlroot(xml '<foo/>', version '2.0');
index cf96beab060729ee8b18f5e71778428d45d5561d..ae7d633c1c4c15f0bdeeefcb6d1e7a86c63bb5ad 100644 (file)
@@ -51,6 +51,9 @@ SELECT xmlpi(name foo);
 SELECT xmlpi(name xmlstuff);
 SELECT xmlpi(name foo, 'bar');
 SELECT xmlpi(name foo, 'in?>valid');
+SELECT xmlpi(name foo, null);
+SELECT xmlpi(name xmlstuff, null);
+SELECT xmlpi(name foo, '   bar');
 
 SELECT xmlroot(xml '<foo/>', version no value, standalone no value);
 SELECT xmlroot(xml '<foo/>', version '2.0');