diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2010-03-01 18:08:27 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2010-03-01 18:08:27 +0000 |
commit | 7af8e8d671c548f7ba43a5a9aba691ffa0fc1727 (patch) | |
tree | cdd903611a3f9d4cd7eabe710279745109c2c4e0 | |
parent | 057b5485e6d2fa3872838b013080fd85bbbc3d0a (diff) | |
download | postgresql-7af8e8d671c548f7ba43a5a9aba691ffa0fc1727.tar.gz postgresql-7af8e8d671c548f7ba43a5a9aba691ffa0fc1727.zip |
Fix contrib/xml2 so regression test still works when it's built without libxslt.
This involves modifying the module to have a stable ABI, that is, the
xslt_process() function still exists even without libxslt. It throws a
runtime error if called, but doesn't prevent executing the CREATE FUNCTION
call. This is a good thing anyway to simplify cross-version upgrades.
-rw-r--r-- | contrib/xml2/Makefile | 17 | ||||
-rw-r--r-- | contrib/xml2/expected/xml2_1.out | 102 | ||||
-rw-r--r-- | contrib/xml2/pgxml.sql.in | 9 | ||||
-rw-r--r-- | contrib/xml2/xslt_proc.c | 23 |
4 files changed, 135 insertions, 16 deletions
diff --git a/contrib/xml2/Makefile b/contrib/xml2/Makefile index c247fca3005..fdc66bdfc12 100644 --- a/contrib/xml2/Makefile +++ b/contrib/xml2/Makefile @@ -1,20 +1,28 @@ # This makefile will build the new XML and XSLT routines. +# This module will not work without libxml2, but it will work without libxslt. +# To build without libxslt, run "gmake USE_LIBXSLT=0", or comment out the +# following line: +USE_LIBXSLT = 1 + MODULE_big = pgxml -# Remove xslt_proc.o from the following line if you don't have libxslt OBJS = xpath.o xslt_proc.o -# Remove -lxslt from the following line if you don't have libxslt. +PG_CPPFLAGS := $(shell xml2-config --cflags) + +ifeq ($(USE_LIBXSLT),1) +PG_CPPFLAGS += -DUSE_LIBXSLT SHLIB_LINK = -lxslt -lxml2 +else +SHLIB_LINK = -lxml2 +endif DATA_built = pgxml.sql DATA = uninstall_pgxml.sql REGRESS = xml2 DOCS = README.xml2 -PG_CPPFLAGS := $(shell xml2-config --cflags) - ifdef USE_PGXS PGXS := $(shell pg_config --pgxs) include $(PGXS) @@ -24,4 +32,3 @@ top_builddir = ../.. include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif - diff --git a/contrib/xml2/expected/xml2_1.out b/contrib/xml2/expected/xml2_1.out new file mode 100644 index 00000000000..ef9332ffa62 --- /dev/null +++ b/contrib/xml2/expected/xml2_1.out @@ -0,0 +1,102 @@ +-- +-- first, define the functions. Turn off echoing so that expected file +-- does not depend on contents of pgxml.sql. +-- +SET client_min_messages = warning; +\set ECHO none +RESET client_min_messages; +select xslt_process( +'<table xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + +<row> + <x>1</x> +</row> + +<row> + <x>2</x> +</row> + +<row> + <x>3</x> +</row> + +<row> + <x>4</x> +</row> + +<row> + <x>5</x> +</row> + +</table>'::text, +$$<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> +<xsl:output method="xml" indent="yes" /> +<xsl:template match="*"> + <xsl:copy> + <xsl:copy-of select="@*" /> + <xsl:apply-templates /> + </xsl:copy> +</xsl:template> +<xsl:template match="comment()|processing-instruction()"> + <xsl:copy /> +</xsl:template> +</xsl:stylesheet> +$$::text); +ERROR: xslt_process() is not available without libxslt +CREATE TABLE xpath_test (id integer NOT NULL, t text); +INSERT INTO xpath_test VALUES (1, '<doc><int>1</int></doc>'); +SELECT * FROM xpath_table('id', 't', 'xpath_test', '/doc/int', 'true') +as t(id int4); + id +---- +(0 rows) + +SELECT * FROM xpath_table('id', 't', 'xpath_test', '/doc/int', 'true') +as t(id int4, doc int4); + id | doc +----+----- + 1 | 1 +(1 row) + +create table articles (article_id integer, article_xml text, date_entered date); +insert into articles (article_id, article_xml, date_entered) +values (2, '<article><author>test</author><pages>37</pages></article>', now()); +SELECT * FROM +xpath_table('article_id', + 'article_xml', + 'articles', + '/article/author|/article/pages|/article/title', + 'date_entered > ''2003-01-01'' ') +AS t(article_id integer, author text, page_count integer, title text); + article_id | author | page_count | title +------------+--------+------------+------- + 2 | test | 37 | +(1 row) + +-- this used to fail when invoked a second time +select xslt_process('<aaa/>',$$<xsl:stylesheet version="1.0" +xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> +<xsl:template match="@*|node()"> + <xsl:copy> + <xsl:apply-templates select="@*|node()"/> + </xsl:copy> + </xsl:template> +</xsl:stylesheet>$$); +ERROR: xslt_process() is not available without libxslt +select xslt_process('<aaa/>',$$<xsl:stylesheet version="1.0" +xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> +<xsl:template match="@*|node()"> + <xsl:copy> + <xsl:apply-templates select="@*|node()"/> + </xsl:copy> + </xsl:template> +</xsl:stylesheet>$$); +ERROR: xslt_process() is not available without libxslt +create table t1 (id integer, xml_data text); +insert into t1 (id, xml_data) +values +(1, '<attributes><attribute name="attr_1">Some +Value</attribute></attributes>'); +create index idx_xpath on t1 ( xpath_string +('/attributes/attribute[@name="attr_1"]/text()', xml_data)); diff --git a/contrib/xml2/pgxml.sql.in b/contrib/xml2/pgxml.sql.in index 4555cc83311..ecff53aea45 100644 --- a/contrib/xml2/pgxml.sql.in +++ b/contrib/xml2/pgxml.sql.in @@ -28,19 +28,14 @@ CREATE OR REPLACE FUNCTION xpath_list(text,text,text) RETURNS text AS 'MODULE_PATHNAME' LANGUAGE C STRICT IMMUTABLE; - CREATE OR REPLACE FUNCTION xpath_list(text,text) RETURNS text AS 'SELECT xpath_list($1,$2,'','')' LANGUAGE SQL STRICT IMMUTABLE; - - -- Wrapper functions for nodeset where no tags needed - CREATE OR REPLACE FUNCTION xpath_nodeset(text,text) RETURNS text AS 'SELECT xpath_nodeset($1,$2,'''','''')' LANGUAGE SQL STRICT IMMUTABLE; - CREATE OR REPLACE FUNCTION xpath_nodeset(text,text,text) RETURNS text AS 'SELECT xpath_nodeset($1,$2,'''',$3)' LANGUAGE SQL STRICT IMMUTABLE; @@ -51,14 +46,10 @@ CREATE OR REPLACE FUNCTION xpath_table(text,text,text,text,text) RETURNS setof r LANGUAGE C STRICT STABLE; -- XSLT functions --- Delete from here to the end of the file if you are not compiling with --- XSLT support. - CREATE OR REPLACE FUNCTION xslt_process(text,text,text) RETURNS text AS 'MODULE_PATHNAME' LANGUAGE C STRICT VOLATILE; -- the function checks for the correct argument count - CREATE OR REPLACE FUNCTION xslt_process(text,text) RETURNS text AS 'MODULE_PATHNAME' LANGUAGE C STRICT IMMUTABLE; diff --git a/contrib/xml2/xslt_proc.c b/contrib/xml2/xslt_proc.c index 4c45422b496..f955d4fe6ae 100644 --- a/contrib/xml2/xslt_proc.c +++ b/contrib/xml2/xslt_proc.c @@ -7,6 +7,8 @@ #include "funcapi.h" #include "miscadmin.h" +#ifdef USE_LIBXSLT + /* libxml includes */ #include <libxml/xpath.h> @@ -20,11 +22,15 @@ #include <libxslt/transform.h> #include <libxslt/xsltutils.h> +#endif /* USE_LIBXSLT */ + /* externally accessible functions */ Datum xslt_process(PG_FUNCTION_ARGS); +#ifdef USE_LIBXSLT + /* declarations to come from xpath.c */ extern void elog_error(const char *explain, bool force); extern void pgxml_parser_init(void); @@ -36,13 +42,15 @@ static void parse_params(const char **params, text *paramstr); #define GET_STR(textp) DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(textp))) +#endif /* USE_LIBXSLT */ + PG_FUNCTION_INFO_V1(xslt_process); Datum xslt_process(PG_FUNCTION_ARGS) { - +#ifdef USE_LIBXSLT const char *params[MAXPARAMS + 1]; /* +1 for the terminator */ xsltStylesheetPtr stylesheet = NULL; @@ -58,7 +66,6 @@ xslt_process(PG_FUNCTION_ARGS) text *paramstr; text *tres; - if (fcinfo->nargs == 3) { paramstr = PG_GETARG_TEXT_P(2); @@ -128,8 +135,18 @@ xslt_process(PG_FUNCTION_ARGS) VARATT_SIZEP(tres) = reslen + VARHDRSZ; PG_RETURN_TEXT_P(tres); + +#else /* !USE_LIBXSLT */ + + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("xslt_process() is not available without libxslt"))); + PG_RETURN_NULL(); + +#endif /* USE_LIBXSLT */ } +#ifdef USE_LIBXSLT static void parse_params(const char **params, text *paramstr) @@ -178,3 +195,5 @@ parse_params(const char **params, text *paramstr) params[i] = NULL; } + +#endif /* USE_LIBXSLT */ |