mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Add an xpath_exists() function. This is equivalent to XMLEXISTS except that
it offers support for namespace mapping. Mike Fowler, reviewed by David Fetter
This commit is contained in:
		@@ -1,4 +1,4 @@
 | 
				
			|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.524 2010/08/05 18:21:17 tgl Exp $ -->
 | 
					<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.525 2010/08/08 19:15:27 tgl Exp $ -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 <chapter id="functions">
 | 
					 <chapter id="functions">
 | 
				
			||||||
  <title>Functions and Operators</title>
 | 
					  <title>Functions and Operators</title>
 | 
				
			||||||
@@ -8175,7 +8175,7 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
 | 
				
			|||||||
   linkend="datatype-xml"> for information about the <type>xml</type>
 | 
					   linkend="datatype-xml"> for information about the <type>xml</type>
 | 
				
			||||||
   type.  The function-like expressions <function>xmlparse</function>
 | 
					   type.  The function-like expressions <function>xmlparse</function>
 | 
				
			||||||
   and <function>xmlserialize</function> for converting to and from
 | 
					   and <function>xmlserialize</function> for converting to and from
 | 
				
			||||||
   type <type>xml</type> are not repeated here.  Use of many of these
 | 
					   type <type>xml</type> are not repeated here.  Use of most of these
 | 
				
			||||||
   functions requires the installation to have been built
 | 
					   functions requires the installation to have been built
 | 
				
			||||||
   with <command>configure --with-libxml</>.
 | 
					   with <command>configure --with-libxml</>.
 | 
				
			||||||
  </para>
 | 
					  </para>
 | 
				
			||||||
@@ -8636,7 +8636,8 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Tor
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
   <para>
 | 
					   <para>
 | 
				
			||||||
    To process values of data type <type>xml</type>, PostgreSQL offers
 | 
					    To process values of data type <type>xml</type>, PostgreSQL offers
 | 
				
			||||||
    the function <function>xpath</function>, which evaluates XPath 1.0
 | 
					    the functions <function>xpath</function> and
 | 
				
			||||||
 | 
					    <function>xpath_exists</function>, which evaluate XPath 1.0
 | 
				
			||||||
    expressions.
 | 
					    expressions.
 | 
				
			||||||
   </para>
 | 
					   </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -8646,7 +8647,8 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Tor
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
   <para>
 | 
					   <para>
 | 
				
			||||||
    The function <function>xpath</function> evaluates the XPath
 | 
					    The function <function>xpath</function> evaluates the XPath
 | 
				
			||||||
    expression <replaceable>xpath</replaceable> against the XML value
 | 
					    expression <replaceable>xpath</replaceable> (a <type>text</> value)
 | 
				
			||||||
 | 
					    against the XML value
 | 
				
			||||||
    <replaceable>xml</replaceable>.  It returns an array of XML values
 | 
					    <replaceable>xml</replaceable>.  It returns an array of XML values
 | 
				
			||||||
    corresponding to the node set produced by the XPath expression.
 | 
					    corresponding to the node set produced by the XPath expression.
 | 
				
			||||||
   </para>
 | 
					   </para>
 | 
				
			||||||
@@ -8657,13 +8659,13 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Tor
 | 
				
			|||||||
  </para>
 | 
					  </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   <para>
 | 
					   <para>
 | 
				
			||||||
    The third argument of the function is an array of namespace
 | 
					    The optional third argument of the function is an array of namespace
 | 
				
			||||||
    mappings.  This array should be a two-dimensional array with the
 | 
					    mappings.  This array should be a two-dimensional <type>text</> array with
 | 
				
			||||||
    length of the second axis being equal to 2 (i.e., it should be an
 | 
					    the length of the second axis being equal to 2 (i.e., it should be an
 | 
				
			||||||
    array of arrays, each of which consists of exactly 2 elements).
 | 
					    array of arrays, each of which consists of exactly 2 elements).
 | 
				
			||||||
    The first element of each array entry is the namespace name (alias), the
 | 
					    The first element of each array entry is the namespace name (alias), the
 | 
				
			||||||
    second the namespace URI. It is not required that aliases provided in
 | 
					    second the namespace URI. It is not required that aliases provided in
 | 
				
			||||||
    this array are the same that those being used in the XML document itself (in
 | 
					    this array be the same as those being used in the XML document itself (in
 | 
				
			||||||
    other words, both in the XML document and in the <function>xpath</function>
 | 
					    other words, both in the XML document and in the <function>xpath</function>
 | 
				
			||||||
    function context, aliases are <emphasis>local</>).
 | 
					    function context, aliases are <emphasis>local</>).
 | 
				
			||||||
   </para>
 | 
					   </para>
 | 
				
			||||||
@@ -8682,7 +8684,7 @@ SELECT xpath('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>',
 | 
				
			|||||||
   </para>
 | 
					   </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   <para>
 | 
					   <para>
 | 
				
			||||||
    How to deal with default (anonymous) namespaces:
 | 
					    To deal with default (anonymous) namespaces, do something like this:
 | 
				
			||||||
<screen><![CDATA[
 | 
					<screen><![CDATA[
 | 
				
			||||||
SELECT xpath('//mydefns:b/text()', '<a xmlns="http://example.com"><b>test</b></a>',
 | 
					SELECT xpath('//mydefns:b/text()', '<a xmlns="http://example.com"><b>test</b></a>',
 | 
				
			||||||
             ARRAY[ARRAY['mydefns', 'http://example.com']]);
 | 
					             ARRAY[ARRAY['mydefns', 'http://example.com']]);
 | 
				
			||||||
@@ -8691,6 +8693,36 @@ SELECT xpath('//mydefns:b/text()', '<a xmlns="http://example.com"><b>test</b></a
 | 
				
			|||||||
--------
 | 
					--------
 | 
				
			||||||
 {test}
 | 
					 {test}
 | 
				
			||||||
(1 row)
 | 
					(1 row)
 | 
				
			||||||
 | 
					]]></screen>
 | 
				
			||||||
 | 
					   </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   <indexterm>
 | 
				
			||||||
 | 
					    <primary>xpath_exists</primary>
 | 
				
			||||||
 | 
					   </indexterm>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<synopsis>
 | 
				
			||||||
 | 
					<function>xpath_exists</function>(<replaceable>xpath</replaceable>, <replaceable>xml</replaceable> <optional>, <replaceable>nsarray</replaceable></optional>)
 | 
				
			||||||
 | 
					</synopsis>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   <para>
 | 
				
			||||||
 | 
					    The function <function>xpath_exists</function> is a specialized form
 | 
				
			||||||
 | 
					    of the <function>xpath</function> function.  Instead of returning the
 | 
				
			||||||
 | 
					    individual XML values that satisfy the XPath, this function returns a
 | 
				
			||||||
 | 
					    boolean indicating whether the query was satisfied or not.  This
 | 
				
			||||||
 | 
					    function is equivalent to the standard <literal>XMLEXISTS</> predicate,
 | 
				
			||||||
 | 
					    except that it also offers support for a namespace mapping argument.
 | 
				
			||||||
 | 
					   </para>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   <para>
 | 
				
			||||||
 | 
					    Example:
 | 
				
			||||||
 | 
					<screen><![CDATA[
 | 
				
			||||||
 | 
					SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>',
 | 
				
			||||||
 | 
					                     ARRAY[ARRAY['my', 'http://example.com']]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 xpath_exists  
 | 
				
			||||||
 | 
					--------------
 | 
				
			||||||
 | 
					 t
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
]]></screen>
 | 
					]]></screen>
 | 
				
			||||||
   </para>
 | 
					   </para>
 | 
				
			||||||
  </sect2>
 | 
					  </sect2>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
 | 
					 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
 | 
				
			||||||
 * Portions Copyright (c) 1994, Regents of the University of California
 | 
					 * Portions Copyright (c) 1994, Regents of the University of California
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.99 2010/08/05 04:21:54 petere Exp $
 | 
					 * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.100 2010/08/08 19:15:27 tgl Exp $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *-------------------------------------------------------------------------
 | 
					 *-------------------------------------------------------------------------
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -3541,3 +3541,27 @@ Datum xmlexists(PG_FUNCTION_ARGS)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Determines if the node specified by the supplied XPath exists
 | 
				
			||||||
 | 
					 * in a given XML document, returning a boolean. Differs from
 | 
				
			||||||
 | 
					 * xmlexists as it supports namespaces and is not defined in SQL/XML.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					Datum
 | 
				
			||||||
 | 
					xpath_exists(PG_FUNCTION_ARGS)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef USE_LIBXML
 | 
				
			||||||
 | 
						text	   *xpath_expr_text = PG_GETARG_TEXT_P(0);
 | 
				
			||||||
 | 
						xmltype    *data = PG_GETARG_XML_P(1);
 | 
				
			||||||
 | 
						ArrayType  *namespaces = PG_GETARG_ARRAYTYPE_P(2);
 | 
				
			||||||
 | 
						int			res_nitems;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						xpath_internal(xpath_expr_text, data, namespaces,
 | 
				
			||||||
 | 
									   &res_nitems, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PG_RETURN_BOOL(res_nitems > 0);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						NO_XML_SUPPORT();
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,7 +37,7 @@
 | 
				
			|||||||
 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
 | 
					 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
 | 
				
			||||||
 * Portions Copyright (c) 1994, Regents of the University of California
 | 
					 * Portions Copyright (c) 1994, Regents of the University of California
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.592 2010/08/08 16:27:04 tgl Exp $
 | 
					 * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.593 2010/08/08 19:15:27 tgl Exp $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *-------------------------------------------------------------------------
 | 
					 *-------------------------------------------------------------------------
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -53,6 +53,6 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*							yyyymmddN */
 | 
					/*							yyyymmddN */
 | 
				
			||||||
#define CATALOG_VERSION_NO	201008071
 | 
					#define CATALOG_VERSION_NO	201008081
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
 | 
					 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
 | 
				
			||||||
 * Portions Copyright (c) 1994, Regents of the University of California
 | 
					 * Portions Copyright (c) 1994, Regents of the University of California
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.576 2010/08/08 16:27:04 tgl Exp $
 | 
					 * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.577 2010/08/08 19:15:27 tgl Exp $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * NOTES
 | 
					 * NOTES
 | 
				
			||||||
 *	  The script catalog/genbki.pl reads this file and generates .bki
 | 
					 *	  The script catalog/genbki.pl reads this file and generates .bki
 | 
				
			||||||
@@ -4415,6 +4415,11 @@ DESCR("evaluate XPath expression");
 | 
				
			|||||||
DATA(insert OID = 2614 (  xmlexists	 PGNSP PGUID 12 1 0 0 f f f t f i 2 0 16 "25 142" _null_ _null_ _null_ _null_ xmlexists _null_ _null_ _null_ ));
 | 
					DATA(insert OID = 2614 (  xmlexists	 PGNSP PGUID 12 1 0 0 f f f t f i 2 0 16 "25 142" _null_ _null_ _null_ _null_ xmlexists _null_ _null_ _null_ ));
 | 
				
			||||||
DESCR("test XML value against XPath expression");
 | 
					DESCR("test XML value against XPath expression");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DATA(insert OID = 3049 (  xpath_exists	 PGNSP PGUID 12 1 0 0 f f f t f i 3 0 16 "25 142 1009" _null_ _null_ _null_ _null_ xpath_exists _null_ _null_ _null_ ));
 | 
				
			||||||
 | 
					DESCR("test XML value against XPath expression, with namespace support");
 | 
				
			||||||
 | 
					DATA(insert OID = 3050 (  xpath_exists	 PGNSP PGUID 14 1 0 0 f f f t f i 2 0 16 "25 142" _null_ _null_ _null_ _null_ "select pg_catalog.xpath_exists($1, $2, ''{}''::pg_catalog.text[])" _null_ _null_ _null_ ));
 | 
				
			||||||
 | 
					DESCR("test XML value against XPath expression");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* uuid */
 | 
					/* uuid */
 | 
				
			||||||
DATA(insert OID = 2952 (  uuid_in		   PGNSP PGUID 12 1 0 0 f f f t f i 1 0 2950 "2275" _null_ _null_ _null_ _null_ uuid_in _null_ _null_ _null_ ));
 | 
					DATA(insert OID = 2952 (  uuid_in		   PGNSP PGUID 12 1 0 0 f f f t f i 1 0 2950 "2275" _null_ _null_ _null_ _null_ uuid_in _null_ _null_ _null_ ));
 | 
				
			||||||
DESCR("I/O");
 | 
					DESCR("I/O");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
 | 
					 * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
 | 
				
			||||||
 * Portions Copyright (c) 1994, Regents of the University of California
 | 
					 * Portions Copyright (c) 1994, Regents of the University of California
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.32 2010/08/05 04:21:54 petere Exp $
 | 
					 * $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.33 2010/08/08 19:15:27 tgl Exp $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *-------------------------------------------------------------------------
 | 
					 *-------------------------------------------------------------------------
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -37,6 +37,7 @@ extern Datum texttoxml(PG_FUNCTION_ARGS);
 | 
				
			|||||||
extern Datum xmltotext(PG_FUNCTION_ARGS);
 | 
					extern Datum xmltotext(PG_FUNCTION_ARGS);
 | 
				
			||||||
extern Datum xmlvalidate(PG_FUNCTION_ARGS);
 | 
					extern Datum xmlvalidate(PG_FUNCTION_ARGS);
 | 
				
			||||||
extern Datum xpath(PG_FUNCTION_ARGS);
 | 
					extern Datum xpath(PG_FUNCTION_ARGS);
 | 
				
			||||||
 | 
					extern Datum xpath_exists(PG_FUNCTION_ARGS);
 | 
				
			||||||
extern Datum xmlexists(PG_FUNCTION_ARGS);
 | 
					extern Datum xmlexists(PG_FUNCTION_ARGS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern Datum table_to_xml(PG_FUNCTION_ARGS);
 | 
					extern Datum table_to_xml(PG_FUNCTION_ARGS);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -502,7 +502,7 @@ SELECT xpath('//b', '<a>one <b>two</b> three <b>etc</b></a>');
 | 
				
			|||||||
 {<b>two</b>,<b>etc</b>}
 | 
					 {<b>two</b>,<b>etc</b>}
 | 
				
			||||||
(1 row)
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- Test xmlexists evaluation
 | 
					-- Test xmlexists and xpath_exists
 | 
				
			||||||
SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Bidford-on-Avon</town><town>Cwmbran</town><town>Bristol</town></towns>');
 | 
					SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Bidford-on-Avon</town><town>Cwmbran</town><town>Bristol</town></towns>');
 | 
				
			||||||
 xmlexists 
 | 
					 xmlexists 
 | 
				
			||||||
-----------
 | 
					-----------
 | 
				
			||||||
@@ -515,6 +515,18 @@ SELECT xmlexists('//town[text() = ''Cwmbran'']' PASSING BY REF '<towns><town>Bid
 | 
				
			|||||||
 t
 | 
					 t
 | 
				
			||||||
(1 row)
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECT xpath_exists('//town[text() = ''Toronto'']','<towns><town>Bidford-on-Avon</town><town>Cwmbran</town><town>Bristol</town></towns>'::xml);
 | 
				
			||||||
 | 
					 xpath_exists 
 | 
				
			||||||
 | 
					--------------
 | 
				
			||||||
 | 
					 f
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECT xpath_exists('//town[text() = ''Cwmbran'']','<towns><town>Bidford-on-Avon</town><town>Cwmbran</town><town>Bristol</town></towns>'::xml);
 | 
				
			||||||
 | 
					 xpath_exists 
 | 
				
			||||||
 | 
					--------------
 | 
				
			||||||
 | 
					 t
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
INSERT INTO xmltest VALUES (4, '<menu><beers><name>Budvar</name><cost>free</cost><name>Carling</name><cost>lots</cost></beers></menu>'::xml);
 | 
					INSERT INTO xmltest VALUES (4, '<menu><beers><name>Budvar</name><cost>free</cost><name>Carling</name><cost>lots</cost></beers></menu>'::xml);
 | 
				
			||||||
INSERT INTO xmltest VALUES (5, '<menu><beers><name>Molson</name><cost>free</cost><name>Carling</name><cost>lots</cost></beers></menu>'::xml);
 | 
					INSERT INTO xmltest VALUES (5, '<menu><beers><name>Molson</name><cost>free</cost><name>Carling</name><cost>lots</cost></beers></menu>'::xml);
 | 
				
			||||||
INSERT INTO xmltest VALUES (6, '<myns:menu xmlns:myns="http://myns.com"><myns:beers><myns:name>Budvar</myns:name><myns:cost>free</myns:cost><myns:name>Carling</myns:name><myns:cost>lots</myns:cost></myns:beers></myns:menu>'::xml);
 | 
					INSERT INTO xmltest VALUES (6, '<myns:menu xmlns:myns="http://myns.com"><myns:beers><myns:name>Budvar</myns:name><myns:cost>free</myns:cost><myns:name>Carling</myns:name><myns:cost>lots</myns:cost></myns:beers></myns:menu>'::xml);
 | 
				
			||||||
@@ -543,6 +555,42 @@ SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beers/name[text() = ''Molso
 | 
				
			|||||||
     1
 | 
					     1
 | 
				
			||||||
(1 row)
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beer',data);
 | 
				
			||||||
 | 
					 count 
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					     0
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beers',data);
 | 
				
			||||||
 | 
					 count 
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					     2
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beers/name[text() = ''Molson'']',data);
 | 
				
			||||||
 | 
					 count 
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					     1
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beer',data,ARRAY[ARRAY['myns','http://myns.com']]);
 | 
				
			||||||
 | 
					 count 
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					     0
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beers',data,ARRAY[ARRAY['myns','http://myns.com']]);
 | 
				
			||||||
 | 
					 count 
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					     2
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beers/myns:name[text() = ''Molson'']',data,ARRAY[ARRAY['myns','http://myns.com']]);
 | 
				
			||||||
 | 
					 count 
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					     1
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CREATE TABLE query ( expr TEXT );
 | 
					CREATE TABLE query ( expr TEXT );
 | 
				
			||||||
INSERT INTO query VALUES ('/menu/beers/cost[text() = ''lots'']');
 | 
					INSERT INTO query VALUES ('/menu/beers/cost[text() = ''lots'']');
 | 
				
			||||||
SELECT COUNT(id) FROM xmltest, query WHERE xmlexists(expr PASSING BY REF data);
 | 
					SELECT COUNT(id) FROM xmltest, query WHERE xmlexists(expr PASSING BY REF data);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -456,7 +456,7 @@ LINE 1: SELECT xpath('//b', '<a>one <b>two</b> three <b>etc</b></a>'...
 | 
				
			|||||||
                            ^
 | 
					                            ^
 | 
				
			||||||
DETAIL:  This functionality requires the server to be built with libxml support.
 | 
					DETAIL:  This functionality requires the server to be built with libxml support.
 | 
				
			||||||
HINT:  You need to rebuild PostgreSQL using --with-libxml.
 | 
					HINT:  You need to rebuild PostgreSQL using --with-libxml.
 | 
				
			||||||
-- Test xmlexists evaluation
 | 
					-- Test xmlexists and xpath_exists
 | 
				
			||||||
SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Bidford-on-Avon</town><town>Cwmbran</town><town>Bristol</town></towns>');
 | 
					SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Bidford-on-Avon</town><town>Cwmbran</town><town>Bristol</town></towns>');
 | 
				
			||||||
ERROR:  unsupported XML feature
 | 
					ERROR:  unsupported XML feature
 | 
				
			||||||
LINE 1: ...sts('//town[text() = ''Toronto'']' PASSING BY REF '<towns><t...
 | 
					LINE 1: ...sts('//town[text() = ''Toronto'']' PASSING BY REF '<towns><t...
 | 
				
			||||||
@@ -469,6 +469,18 @@ LINE 1: ...sts('//town[text() = ''Cwmbran'']' PASSING BY REF '<towns><t...
 | 
				
			|||||||
                                                             ^
 | 
					                                                             ^
 | 
				
			||||||
DETAIL:  This functionality requires the server to be built with libxml support.
 | 
					DETAIL:  This functionality requires the server to be built with libxml support.
 | 
				
			||||||
HINT:  You need to rebuild PostgreSQL using --with-libxml.
 | 
					HINT:  You need to rebuild PostgreSQL using --with-libxml.
 | 
				
			||||||
 | 
					SELECT xpath_exists('//town[text() = ''Toronto'']','<towns><town>Bidford-on-Avon</town><town>Cwmbran</town><town>Bristol</town></towns>'::xml);
 | 
				
			||||||
 | 
					ERROR:  unsupported XML feature
 | 
				
			||||||
 | 
					LINE 1: ...ELECT xpath_exists('//town[text() = ''Toronto'']','<towns><t...
 | 
				
			||||||
 | 
					                                                             ^
 | 
				
			||||||
 | 
					DETAIL:  This functionality requires the server to be built with libxml support.
 | 
				
			||||||
 | 
					HINT:  You need to rebuild PostgreSQL using --with-libxml.
 | 
				
			||||||
 | 
					SELECT xpath_exists('//town[text() = ''Cwmbran'']','<towns><town>Bidford-on-Avon</town><town>Cwmbran</town><town>Bristol</town></towns>'::xml);
 | 
				
			||||||
 | 
					ERROR:  unsupported XML feature
 | 
				
			||||||
 | 
					LINE 1: ...ELECT xpath_exists('//town[text() = ''Cwmbran'']','<towns><t...
 | 
				
			||||||
 | 
					                                                             ^
 | 
				
			||||||
 | 
					DETAIL:  This functionality requires the server to be built with libxml support.
 | 
				
			||||||
 | 
					HINT:  You need to rebuild PostgreSQL using --with-libxml.
 | 
				
			||||||
INSERT INTO xmltest VALUES (4, '<menu><beers><name>Budvar</name><cost>free</cost><name>Carling</name><cost>lots</cost></beers></menu>'::xml);
 | 
					INSERT INTO xmltest VALUES (4, '<menu><beers><name>Budvar</name><cost>free</cost><name>Carling</name><cost>lots</cost></beers></menu>'::xml);
 | 
				
			||||||
ERROR:  unsupported XML feature
 | 
					ERROR:  unsupported XML feature
 | 
				
			||||||
LINE 1: INSERT INTO xmltest VALUES (4, '<menu><beers><name>Budvar</n...
 | 
					LINE 1: INSERT INTO xmltest VALUES (4, '<menu><beers><name>Budvar</n...
 | 
				
			||||||
@@ -517,6 +529,42 @@ SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beers/name[text() = ''Molso
 | 
				
			|||||||
     0
 | 
					     0
 | 
				
			||||||
(1 row)
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beer',data);
 | 
				
			||||||
 | 
					 count 
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					     0
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beers',data);
 | 
				
			||||||
 | 
					 count 
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					     0
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beers/name[text() = ''Molson'']',data);
 | 
				
			||||||
 | 
					 count 
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					     0
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beer',data,ARRAY[ARRAY['myns','http://myns.com']]);
 | 
				
			||||||
 | 
					 count 
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					     0
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beers',data,ARRAY[ARRAY['myns','http://myns.com']]);
 | 
				
			||||||
 | 
					 count 
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					     0
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beers/myns:name[text() = ''Molson'']',data,ARRAY[ARRAY['myns','http://myns.com']]);
 | 
				
			||||||
 | 
					 count 
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					     0
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CREATE TABLE query ( expr TEXT );
 | 
					CREATE TABLE query ( expr TEXT );
 | 
				
			||||||
INSERT INTO query VALUES ('/menu/beers/cost[text() = ''lots'']');
 | 
					INSERT INTO query VALUES ('/menu/beers/cost[text() = ''lots'']');
 | 
				
			||||||
SELECT COUNT(id) FROM xmltest, query WHERE xmlexists(expr PASSING BY REF data);
 | 
					SELECT COUNT(id) FROM xmltest, query WHERE xmlexists(expr PASSING BY REF data);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -164,21 +164,29 @@ SELECT xpath('//text()', '<local:data xmlns:local="http://127.0.0.1"><local:piec
 | 
				
			|||||||
SELECT xpath('//loc:piece/@id', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc', 'http://127.0.0.1']]);
 | 
					SELECT xpath('//loc:piece/@id', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc', 'http://127.0.0.1']]);
 | 
				
			||||||
SELECT xpath('//b', '<a>one <b>two</b> three <b>etc</b></a>');
 | 
					SELECT xpath('//b', '<a>one <b>two</b> three <b>etc</b></a>');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- Test xmlexists evaluation
 | 
					-- Test xmlexists and xpath_exists
 | 
				
			||||||
SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Bidford-on-Avon</town><town>Cwmbran</town><town>Bristol</town></towns>');
 | 
					SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Bidford-on-Avon</town><town>Cwmbran</town><town>Bristol</town></towns>');
 | 
				
			||||||
SELECT xmlexists('//town[text() = ''Cwmbran'']' PASSING BY REF '<towns><town>Bidford-on-Avon</town><town>Cwmbran</town><town>Bristol</town></towns>');
 | 
					SELECT xmlexists('//town[text() = ''Cwmbran'']' PASSING BY REF '<towns><town>Bidford-on-Avon</town><town>Cwmbran</town><town>Bristol</town></towns>');
 | 
				
			||||||
 | 
					SELECT xpath_exists('//town[text() = ''Toronto'']','<towns><town>Bidford-on-Avon</town><town>Cwmbran</town><town>Bristol</town></towns>'::xml);
 | 
				
			||||||
 | 
					SELECT xpath_exists('//town[text() = ''Cwmbran'']','<towns><town>Bidford-on-Avon</town><town>Cwmbran</town><town>Bristol</town></towns>'::xml);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
INSERT INTO xmltest VALUES (4, '<menu><beers><name>Budvar</name><cost>free</cost><name>Carling</name><cost>lots</cost></beers></menu>'::xml);
 | 
					INSERT INTO xmltest VALUES (4, '<menu><beers><name>Budvar</name><cost>free</cost><name>Carling</name><cost>lots</cost></beers></menu>'::xml);
 | 
				
			||||||
INSERT INTO xmltest VALUES (5, '<menu><beers><name>Molson</name><cost>free</cost><name>Carling</name><cost>lots</cost></beers></menu>'::xml);
 | 
					INSERT INTO xmltest VALUES (5, '<menu><beers><name>Molson</name><cost>free</cost><name>Carling</name><cost>lots</cost></beers></menu>'::xml);
 | 
				
			||||||
INSERT INTO xmltest VALUES (6, '<myns:menu xmlns:myns="http://myns.com"><myns:beers><myns:name>Budvar</myns:name><myns:cost>free</myns:cost><myns:name>Carling</myns:name><myns:cost>lots</myns:cost></myns:beers></myns:menu>'::xml);
 | 
					INSERT INTO xmltest VALUES (6, '<myns:menu xmlns:myns="http://myns.com"><myns:beers><myns:name>Budvar</myns:name><myns:cost>free</myns:cost><myns:name>Carling</myns:name><myns:cost>lots</myns:cost></myns:beers></myns:menu>'::xml);
 | 
				
			||||||
INSERT INTO xmltest VALUES (7, '<myns:menu xmlns:myns="http://myns.com"><myns:beers><myns:name>Molson</myns:name><myns:cost>free</myns:cost><myns:name>Carling</myns:name><myns:cost>lots</myns:cost></myns:beers></myns:menu>'::xml);
 | 
					INSERT INTO xmltest VALUES (7, '<myns:menu xmlns:myns="http://myns.com"><myns:beers><myns:name>Molson</myns:name><myns:cost>free</myns:cost><myns:name>Carling</myns:name><myns:cost>lots</myns:cost></myns:beers></myns:menu>'::xml);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beer' PASSING data);
 | 
					SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beer' PASSING data);
 | 
				
			||||||
SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beer' PASSING BY REF data BY REF);
 | 
					SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beer' PASSING BY REF data BY REF);
 | 
				
			||||||
SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beers' PASSING BY REF data);
 | 
					SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beers' PASSING BY REF data);
 | 
				
			||||||
SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beers/name[text() = ''Molson'']' PASSING BY REF data);
 | 
					SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beers/name[text() = ''Molson'']' PASSING BY REF data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beer',data);
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beers',data);
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/menu/beers/name[text() = ''Molson'']',data);
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beer',data,ARRAY[ARRAY['myns','http://myns.com']]);
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beers',data,ARRAY[ARRAY['myns','http://myns.com']]);
 | 
				
			||||||
 | 
					SELECT COUNT(id) FROM xmltest WHERE xpath_exists('/myns:menu/myns:beers/myns:name[text() = ''Molson'']',data,ARRAY[ARRAY['myns','http://myns.com']]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CREATE TABLE query ( expr TEXT );
 | 
					CREATE TABLE query ( expr TEXT );
 | 
				
			||||||
INSERT INTO query VALUES ('/menu/beers/cost[text() = ''lots'']');
 | 
					INSERT INTO query VALUES ('/menu/beers/cost[text() = ''lots'']');
 | 
				
			||||||
SELECT COUNT(id) FROM xmltest, query WHERE xmlexists(expr PASSING BY REF data);
 | 
					SELECT COUNT(id) FROM xmltest, query WHERE xmlexists(expr PASSING BY REF data);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user