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
This commit is contained in:
Tom Lane 2010-08-10 23:02:00 +00:00
parent 33f43725fb
commit c04fd1b9db
4 changed files with 200 additions and 19 deletions

View 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)

View 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

View 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);

View 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 */