diff --git a/contrib/xml2/expected/xml2.out b/contrib/xml2/expected/xml2.out
index 74896b08020..53b8064cc34 100644
--- a/contrib/xml2/expected/xml2.out
+++ b/contrib/xml2/expected/xml2.out
@@ -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)
+
diff --git a/contrib/xml2/expected/xml2_1.out b/contrib/xml2/expected/xml2_1.out
index 083fc3b2cac..b465ea27b63 100644
--- a/contrib/xml2/expected/xml2_1.out
+++ b/contrib/xml2/expected/xml2_1.out
@@ -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
diff --git a/contrib/xml2/sql/xml2.sql b/contrib/xml2/sql/xml2.sql
index 73723b6be10..202a72baedc 100644
--- a/contrib/xml2/sql/xml2.sql
+++ b/contrib/xml2/sql/xml2.sql
@@ -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);
diff --git a/contrib/xml2/xslt_proc.c b/contrib/xml2/xslt_proc.c
index 4c80732bb8b..158345b20b3 100644
--- a/contrib/xml2/xslt_proc.c
+++ b/contrib/xml2/xslt_proc.c
@@ -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 */