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
pull/1/head
Tom Lane 15 years ago
parent 33f43725fb
commit c04fd1b9db
  1. 68
      contrib/xml2/expected/xml2.out
  2. 50
      contrib/xml2/expected/xml2_1.out
  3. 50
      contrib/xml2/sql/xml2.sql
  4. 51
      contrib/xml2/xslt_proc.c

@ -145,3 +145,71 @@ values
Value</attribute></attributes>'); Value</attribute></attributes>');
create index idx_xpath on t1 ( xpath_string create index idx_xpath on t1 ( xpath_string
('/attributes/attribute[@name="attr_1"]/text()', xml_data::text)); ('/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)

@ -107,3 +107,53 @@ values
Value</attribute></attributes>'); Value</attribute></attributes>');
create index idx_xpath on t1 ( xpath_string create index idx_xpath on t1 ( xpath_string
('/attributes/attribute[@name="attr_1"]/text()', xml_data::text)); ('/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

@ -80,3 +80,53 @@ Value</attribute></attributes>');
create index idx_xpath on t1 ( xpath_string create index idx_xpath on t1 ( xpath_string
('/attributes/attribute[@name="attr_1"]/text()', xml_data::text)); ('/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);

@ -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) * XSLT processing functions (requiring libxslt)
* *
@ -41,9 +41,8 @@ Datum xslt_process(PG_FUNCTION_ARGS);
extern void pgxml_parser_init(void); extern void pgxml_parser_init(void);
/* local defs */ /* 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 */ #endif /* USE_LIBXSLT */
@ -57,7 +56,7 @@ xslt_process(PG_FUNCTION_ARGS)
text *doct = PG_GETARG_TEXT_P(0); text *doct = PG_GETARG_TEXT_P(0);
text *ssheet = PG_GETARG_TEXT_P(1); text *ssheet = PG_GETARG_TEXT_P(1);
text *paramstr; text *paramstr;
const char *params[MAXPARAMS + 1]; /* +1 for the terminator */ const char **params;
xsltStylesheetPtr stylesheet = NULL; xsltStylesheetPtr stylesheet = NULL;
xmlDocPtr doctree; xmlDocPtr doctree;
xmlDocPtr restree; xmlDocPtr restree;
@ -69,11 +68,14 @@ xslt_process(PG_FUNCTION_ARGS)
if (fcinfo->nargs == 3) if (fcinfo->nargs == 3)
{ {
paramstr = PG_GETARG_TEXT_P(2); paramstr = PG_GETARG_TEXT_P(2);
parse_params(params, paramstr); params = parse_params(paramstr);
} }
else else
{
/* No parameters */ /* No parameters */
params = (const char **) palloc(sizeof(char *));
params[0] = NULL; params[0] = NULL;
}
/* Setup parser */ /* Setup parser */
pgxml_parser_init(); pgxml_parser_init();
@ -139,22 +141,34 @@ xslt_process(PG_FUNCTION_ARGS)
#ifdef USE_LIBXSLT #ifdef USE_LIBXSLT
static void static const char **
parse_params(const char **params, text *paramstr) parse_params(text *paramstr)
{ {
char *pos; char *pos;
char *pstr; char *pstr;
int i;
char *nvsep = "="; char *nvsep = "=";
char *itsep = ","; char *itsep = ",";
const char **params;
int max_params;
int nparams;
pstr = text_to_cstring(paramstr); pstr = text_to_cstring(paramstr);
max_params = 20; /* must be even! */
params = (const char **) palloc((max_params + 1) * sizeof(char *));
nparams = 0;
pos = pstr; 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); pos = strstr(pos, nvsep);
if (pos != NULL) if (pos != NULL)
{ {
@ -164,13 +178,12 @@ parse_params(const char **params, text *paramstr)
else else
{ {
/* No equal sign, so ignore this "parameter" */ /* No equal sign, so ignore this "parameter" */
/* We'll reset params[i] to NULL below the loop */ nparams--;
break; break;
} }
/* Value */
i++; /* since max_params is even, we still have nparams < max_params */
/* since MAXPARAMS is even, we still have i < MAXPARAMS */ params[nparams++] = pos;
params[i] = pos;
pos = strstr(pos, itsep); pos = strstr(pos, itsep);
if (pos != NULL) if (pos != NULL)
{ {
@ -178,13 +191,13 @@ parse_params(const char **params, text *paramstr)
pos++; pos++;
} }
else else
{
i++;
break; 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 */ #endif /* USE_LIBXSLT */

Loading…
Cancel
Save