1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-20 00:42:27 +03:00

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

View File

@ -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

View File

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

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