summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2010-08-10 23:02:00 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2010-08-10 23:02:00 +0000
commitc04fd1b9dbdc56ea0b64939e6d62f685b28ecea3 (patch)
tree6b9cdd9357269b18369047cd6380182610e69b9b
parent33f43725fb5e133454a3e1d0a33bd7cbc75c3c59 (diff)
downloadpostgresql-c04fd1b9dbdc56ea0b64939e6d62f685b28ecea3.tar.gz
Remove the arbitrary (and undocumented) limit on the number of parameter=value
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
-rw-r--r--contrib/xml2/expected/xml2.out68
-rw-r--r--contrib/xml2/expected/xml2_1.out50
-rw-r--r--contrib/xml2/sql/xml2.sql50
-rw-r--r--contrib/xml2/xslt_proc.c51
4 files changed, 200 insertions, 19 deletions
diff --git a/contrib/xml2/expected/xml2.out b/contrib/xml2/expected/xml2.out
index 74896b0802..53b8064cc3 100644
--- a/contrib/xml2/expected/xml2.out
+++ b/contrib/xml2/expected/xml2.out
@@ -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)
+
diff --git a/contrib/xml2/expected/xml2_1.out b/contrib/xml2/expected/xml2_1.out
index 083fc3b2ca..b465ea27b6 100644
--- a/contrib/xml2/expected/xml2_1.out
+++ b/contrib/xml2/expected/xml2_1.out
@@ -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
diff --git a/contrib/xml2/sql/xml2.sql b/contrib/xml2/sql/xml2.sql
index 73723b6be1..202a72baed 100644
--- a/contrib/xml2/sql/xml2.sql
+++ b/contrib/xml2/sql/xml2.sql
@@ -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);
diff --git a/contrib/xml2/xslt_proc.c b/contrib/xml2/xslt_proc.c
index 4c80732bb8..158345b20b 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 */