]> granicus.if.org Git - postgresql/commitdiff
Remove the arbitrary (and undocumented) limit on the number of parameter=value
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 10 Aug 2010 23:02:00 +0000 (23:02 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 10 Aug 2010 23:02:00 +0000 (23:02 +0000)
pairs that can be handled by xslt_process().

There is much else to do here, but this patch seems useful in its own right
for as long as this code survives.

Pavel Stehule, reviewed by Mike Fowler

contrib/xml2/expected/xml2.out
contrib/xml2/expected/xml2_1.out
contrib/xml2/sql/xml2.sql
contrib/xml2/xslt_proc.c

index 74896b08020b2134e7f3d93a7035bb37bf909fb3..53b8064cc345474eb9d797e096753846769a0eb2 100644 (file)
@@ -145,3 +145,71 @@ values
 Value</attribute></attributes>');
 create index idx_xpath on t1 ( xpath_string
 ('/attributes/attribute[@name="attr_1"]/text()', xml_data::text));
+SELECT xslt_process('<employee><name>cim</name><age>30</age><pay>400</pay></employee>'::text, $$<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+  <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
+  <xsl:strip-space elements="*"/>
+  <xsl:param name="n1"/>
+  <xsl:param name="n2"/>
+  <xsl:param name="n3"/>
+  <xsl:param name="n4"/>
+  <xsl:param name="n5" select="'me'"/>
+  <xsl:template match="*">
+    <xsl:element name="samples">
+      <xsl:element name="sample">
+        <xsl:value-of select="$n1"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n2"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n3"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n4"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n5"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n6"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n7"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n8"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n9"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n10"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n11"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n12"/>
+      </xsl:element>
+    </xsl:element>
+  </xsl:template>
+</xsl:stylesheet>$$::text, 'n1="v1",n2="v2",n3="v3",n4="v4",n5="v5",n6="v6",n7="v7",n8="v8",n9="v9",n10="v10",n11="v11",n12="v12"'::text);
+      xslt_process      
+------------------------
+ <samples>             +
+   <sample>v1</sample> +
+   <sample>v2</sample> +
+   <sample>v3</sample> +
+   <sample>v4</sample> +
+   <sample>v5</sample> +
+   <sample>v6</sample> +
+   <sample>v7</sample> +
+   <sample>v8</sample> +
+   <sample>v9</sample> +
+   <sample>v10</sample>+
+   <sample>v11</sample>+
+   <sample>v12</sample>+
+ </samples>            +
+(1 row)
+
index 083fc3b2cac0810992c52a07faffa7d1ccd56373..b465ea27b631ee7ef0ce5863fc286dc4630e14c8 100644 (file)
@@ -107,3 +107,53 @@ values
 Value</attribute></attributes>');
 create index idx_xpath on t1 ( xpath_string
 ('/attributes/attribute[@name="attr_1"]/text()', xml_data::text));
+SELECT xslt_process('<employee><name>cim</name><age>30</age><pay>400</pay></employee>'::text, $$<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+  <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
+  <xsl:strip-space elements="*"/>
+  <xsl:param name="n1"/>
+  <xsl:param name="n2"/>
+  <xsl:param name="n3"/>
+  <xsl:param name="n4"/>
+  <xsl:param name="n5" select="'me'"/>
+  <xsl:template match="*">
+    <xsl:element name="samples">
+      <xsl:element name="sample">
+        <xsl:value-of select="$n1"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n2"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n3"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n4"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n5"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n6"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n7"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n8"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n9"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n10"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n11"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n12"/>
+      </xsl:element>
+    </xsl:element>
+  </xsl:template>
+</xsl:stylesheet>$$::text, 'n1="v1",n2="v2",n3="v3",n4="v4",n5="v5",n6="v6",n7="v7",n8="v8",n9="v9",n10="v10",n11="v11",n12="v12"'::text);
+ERROR:  xslt_process() is not available without libxslt
index 73723b6be1026a5c17c73baccbf10bb945a90716..202a72baedc4050d855f329c58cf75eb2bd79741 100644 (file)
@@ -80,3 +80,53 @@ Value</attribute></attributes>');
 
 create index idx_xpath on t1 ( xpath_string
 ('/attributes/attribute[@name="attr_1"]/text()', xml_data::text));
+
+SELECT xslt_process('<employee><name>cim</name><age>30</age><pay>400</pay></employee>'::text, $$<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+  <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
+  <xsl:strip-space elements="*"/>
+  <xsl:param name="n1"/>
+  <xsl:param name="n2"/>
+  <xsl:param name="n3"/>
+  <xsl:param name="n4"/>
+  <xsl:param name="n5" select="'me'"/>
+  <xsl:template match="*">
+    <xsl:element name="samples">
+      <xsl:element name="sample">
+        <xsl:value-of select="$n1"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n2"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n3"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n4"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n5"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n6"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n7"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n8"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n9"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n10"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n11"/>
+      </xsl:element>
+      <xsl:element name="sample">
+        <xsl:value-of select="$n12"/>
+      </xsl:element>
+    </xsl:element>
+  </xsl:template>
+</xsl:stylesheet>$$::text, 'n1="v1",n2="v2",n3="v3",n4="v4",n5="v5",n6="v6",n7="v7",n8="v8",n9="v9",n10="v10",n11="v11",n12="v12"'::text);
index 4c80732bb8bb5a119a6c8bb75dc881488e8c4337..158345b20b3720002dd1cc389526a7a5a753310e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/contrib/xml2/xslt_proc.c,v 1.21 2010/07/06 19:18:55 momjian Exp $
+ * $PostgreSQL: pgsql/contrib/xml2/xslt_proc.c,v 1.22 2010/08/10 23:02:00 tgl Exp $
  *
  * XSLT processing functions (requiring libxslt)
  *
@@ -41,9 +41,8 @@ Datum         xslt_process(PG_FUNCTION_ARGS);
 extern void pgxml_parser_init(void);
 
 /* local defs */
-static void parse_params(const char **params, text *paramstr);
+static const char **parse_params(text *paramstr);
 
-#define MAXPARAMS 20                   /* must be even, see parse_params() */
 #endif   /* USE_LIBXSLT */
 
 
@@ -57,7 +56,7 @@ xslt_process(PG_FUNCTION_ARGS)
        text       *doct = PG_GETARG_TEXT_P(0);
        text       *ssheet = PG_GETARG_TEXT_P(1);
        text       *paramstr;
-       const char *params[MAXPARAMS + 1];      /* +1 for the terminator */
+       const char **params;
        xsltStylesheetPtr stylesheet = NULL;
        xmlDocPtr       doctree;
        xmlDocPtr       restree;
@@ -69,11 +68,14 @@ xslt_process(PG_FUNCTION_ARGS)
        if (fcinfo->nargs == 3)
        {
                paramstr = PG_GETARG_TEXT_P(2);
-               parse_params(params, paramstr);
+               params = parse_params(paramstr);
        }
        else
+       {
                /* No parameters */
+               params = (const char **) palloc(sizeof(char *));
                params[0] = NULL;
+       }
 
        /* Setup parser */
        pgxml_parser_init();
@@ -139,22 +141,34 @@ xslt_process(PG_FUNCTION_ARGS)
 
 #ifdef USE_LIBXSLT
 
-static void
-parse_params(const char **params, text *paramstr)
+static const char **
+parse_params(text *paramstr)
 {
        char       *pos;
        char       *pstr;
-       int                     i;
        char       *nvsep = "=";
        char       *itsep = ",";
+       const char **params;
+       int                     max_params;
+       int                     nparams;
 
        pstr = text_to_cstring(paramstr);
 
+       max_params = 20;                        /* must be even! */
+       params = (const char **) palloc((max_params + 1) * sizeof(char *));
+       nparams = 0;
+
        pos = pstr;
 
-       for (i = 0; i < MAXPARAMS; i++)
+       while (*pos != '\0')
        {
-               params[i] = pos;
+               if (nparams >= max_params)
+               {
+                       max_params *= 2;
+                       params = (const char **) repalloc(params,
+                                                                                         (max_params + 1) * sizeof(char *));
+               }
+               params[nparams++] = pos;
                pos = strstr(pos, nvsep);
                if (pos != NULL)
                {
@@ -164,13 +178,12 @@ parse_params(const char **params, text *paramstr)
                else
                {
                        /* No equal sign, so ignore this "parameter" */
-                       /* We'll reset params[i] to NULL below the loop */
+                       nparams--;
                        break;
                }
-               /* Value */
-               i++;
-               /* since MAXPARAMS is even, we still have i < MAXPARAMS */
-               params[i] = pos;
+
+               /* since max_params is even, we still have nparams < max_params */
+               params[nparams++] = pos;
                pos = strstr(pos, itsep);
                if (pos != NULL)
                {
@@ -178,13 +191,13 @@ parse_params(const char **params, text *paramstr)
                        pos++;
                }
                else
-               {
-                       i++;
                        break;
-               }
        }
 
-       params[i] = NULL;
+       /* Add the terminator marker; we left room for it in the palloc's */
+       params[nparams] = NULL;
+
+       return params;
 }
 
 #endif   /* USE_LIBXSLT */