Remove the arbitrary (and undocumented) limit on the number of parameter=value
authorTom Lane
Tue, 10 Aug 2010 23:02:00 +0000 (23:02 +0000)
committerTom Lane
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');
 create index idx_xpath on t1 ( xpath_string
 ('/attributes/attribute[@name="attr_1"]/text()', xml_data::text));
+SELECT xslt_process('cim30400'::text, $$
+  
+  
+  
+  
+  
+  
+  
+  
+    
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+    
+  
+$$::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      
+------------------------
             +
+   v1 +
+   v2 +
+   v3 +
+   v4 +
+   v5 +
+   v6 +
+   v7 +
+   v8 +
+   v9 +
+   v10+
+   v11+
+   v12+
+             +
+(1 row)
+
index 083fc3b2cac0810992c52a07faffa7d1ccd56373..b465ea27b631ee7ef0ce5863fc286dc4630e14c8 100644 (file)
@@ -107,3 +107,53 @@ values
 Value');
 create index idx_xpath on t1 ( xpath_string
 ('/attributes/attribute[@name="attr_1"]/text()', xml_data::text));
+SELECT xslt_process('cim30400'::text, $$
+  
+  
+  
+  
+  
+  
+  
+  
+    
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+    
+  
+$$::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');
 
 create index idx_xpath on t1 ( xpath_string
 ('/attributes/attribute[@name="attr_1"]/text()', xml_data::text));
+
+SELECT xslt_process('cim30400'::text, $$
+  
+  
+  
+  
+  
+  
+  
+  
+    
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+      
+        
+      
+    
+  
+$$::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 */