Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
641459f2
Commit
641459f2
authored
Aug 05, 2010
by
Peter Eisentraut
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add xmlexists function
by Mike Fowler, reviewed by Peter Eisentraut
parent
26e47efb
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
312 additions
and
31 deletions
+312
-31
doc/src/sgml/func.sgml
doc/src/sgml/func.sgml
+53
-2
src/backend/parser/gram.y
src/backend/parser/gram.y
+44
-4
src/backend/utils/adt/xml.c
src/backend/utils/adt/xml.c
+66
-20
src/include/catalog/catversion.h
src/include/catalog/catversion.h
+2
-2
src/include/catalog/pg_proc.h
src/include/catalog/pg_proc.h
+4
-1
src/include/parser/kwlist.h
src/include/parser/kwlist.h
+4
-1
src/include/utils/xml.h
src/include/utils/xml.h
+2
-1
src/test/regress/expected/xml.out
src/test/regress/expected/xml.out
+49
-0
src/test/regress/expected/xml_1.out
src/test/regress/expected/xml_1.out
+69
-0
src/test/regress/sql/xml.sql
src/test/regress/sql/xml.sql
+19
-0
No files found.
doc/src/sgml/func.sgml
View file @
641459f2
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.52
2 2010/07/29 19:34:40
petere Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.52
3 2010/08/05 04:21:53
petere Exp $ -->
<chapter
id=
"functions"
>
<title>
Functions and Operators
</title>
...
...
@@ -8554,10 +8554,19 @@ SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
]]>
</screen>
</para>
</sect3>
</sect2>
<sect
3
>
<sect
2
>
<title>
XML Predicates
</title>
<para>
The expressions described in this section check properties
of
<type>
xml
</type>
values.
</para>
<sect3>
<title>
IS DOCUMENT
</title>
<indexterm>
<primary>
IS DOCUMENT
</primary>
</indexterm>
...
...
@@ -8574,6 +8583,48 @@ SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
between documents and content fragments.
</para>
</sect3>
<sect3>
<title>
XMLEXISTS
</title>
<indexterm>
<primary>
XMLEXISTS
</primary>
</indexterm>
<synopsis>
<function>
XMLEXISTS
</function>
(
<replaceable>
text
</replaceable>
PASSING
<optional>
BY REF
</optional>
<replaceable>
xml
</replaceable>
<optional>
BY REF
</optional>
)
</synopsis>
<para>
The function
<function>
xmlexists
</function>
returns true if the
XPath expression in the first argument returns any nodes, and
false otherwise. (If either argument is null, the result is
null.)
</para>
<para>
Example:
<screen>
<![CDATA[
SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Toronto</town><town>Ottawa</town></towns>');
xmlexists
------------
t
(1 row)
]]>
</screen>
</para>
<para>
The
<literal>
BY REF
</literal>
clauses have no effect in
PostgreSQL, but are allowed for SQL conformance and compatibility
with other implementations. Per SQL standard, the
first
<literal>
BY REF
</literal>
is required, the second is
optional. Also note that the SQL standard specifies
the
<function>
xmlexists
</function>
construct to take an XQuery
expression as first argument, but PostgreSQL currently only
supports XPath, which is a subset of XQuery.
</para>
</sect3>
</sect2>
<sect2
id=
"functions-xml-processing"
>
...
...
src/backend/parser/gram.y
View file @
641459f2
...
...
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.71
4 2010/07/25 23:21:21 rhaas
Exp $
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.71
5 2010/08/05 04:21:53 petere
Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
...
...
@@ -425,6 +425,7 @@ static TypeName *TableFuncTypeName(List *columns);
%type <target> xml_attribute_el
%type <list> xml_attribute_list xml_attributes
%type <node> xml_root_version opt_xml_root_standalone
%type <node> xmlexists_argument
%type <ival> document_or_content
%type <boolean> xml_whitespace_option
...
...
@@ -511,13 +512,13 @@ static TypeName *TableFuncTypeName(List *columns);
OBJECT_P OF OFF OFFSET OIDS ON ONLY OPERATOR OPTION OPTIONS OR
ORDER OUT_P OUTER_P OVER OVERLAPS OVERLAY OWNED OWNER
PARSER PARTIAL PARTITION PASSWORD PLACING PLANS POSITION
PARSER PARTIAL PARTITION PASS
ING PASS
WORD PLACING PLANS POSITION
PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY
PRIOR PRIVILEGES PROCEDURAL PROCEDURE
QUOTE
RANGE READ REAL REASSIGN RECHECK RECURSIVE REFERENCES REINDEX
RANGE READ REAL REASSIGN RECHECK RECURSIVE REF
REF
ERENCES REINDEX
RELATIVE_P RELEASE RENAME REPEATABLE REPLACE REPLICA RESET RESTART
RESTRICT RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROW ROWS RULE
...
...
@@ -539,7 +540,7 @@ static TypeName *TableFuncTypeName(List *columns);
WHEN WHERE WHITESPACE_P WINDOW WITH WITHOUT WORK WRAPPER WRITE
XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLFOREST XMLPARSE
XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XML
EXISTS XML
FOREST XMLPARSE
XMLPI XMLROOT XMLSERIALIZE
YEAR_P YES_P
...
...
@@ -9839,6 +9840,21 @@ func_expr: func_name '(' ')' over_clause
{
$$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, $8, @1);
}
| XMLEXISTS '(' c_expr xmlexists_argument ')'
{
/* xmlexists(A PASSING [BY REF] B [BY REF]) is
* converted to xmlexists(A, B)*/
FuncCall *n = makeNode(FuncCall);
n->funcname = SystemFuncName("xmlexists");
n->args = list_make2($3, $4);
n->agg_order = NIL;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
n->location = @1;
$$ = (Node *)n;
}
| XMLFOREST '(' xml_attribute_list ')'
{
$$ = makeXmlExpr(IS_XMLFOREST, NULL, $3, NIL, @1);
...
...
@@ -9929,6 +9945,27 @@ xml_whitespace_option: PRESERVE WHITESPACE_P { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; }
;
/* We allow several variants for SQL and other compatibility. */
xmlexists_argument:
PASSING c_expr
{
$$ = $2;
}
| PASSING c_expr BY REF
{
$$ = $2;
}
| PASSING BY REF c_expr
{
$$ = $4;
}
| PASSING BY REF c_expr BY REF
{
$$ = $4;
}
;
/*
* Window Definitions
*/
...
...
@@ -10999,6 +11036,7 @@ unreserved_keyword:
| PARSER
| PARTIAL
| PARTITION
| PASSING
| PASSWORD
| PLANS
| PRECEDING
...
...
@@ -11015,6 +11053,7 @@ unreserved_keyword:
| REASSIGN
| RECHECK
| RECURSIVE
| REF
| REINDEX
| RELATIVE_P
| RELEASE
...
...
@@ -11148,6 +11187,7 @@ col_name_keyword:
| XMLATTRIBUTES
| XMLCONCAT
| XMLELEMENT
| XMLEXISTS
| XMLFOREST
| XMLPARSE
| XMLPI
...
...
src/backend/utils/adt/xml.c
View file @
641459f2
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.9
8 2010/07/06 19:18:58 momjian
Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.9
9 2010/08/05 04:21:54 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -3295,24 +3295,20 @@ xml_xmlnodetoxmltype(xmlNodePtr cur)
/*
*
Evaluate XPath expression and return array of XML values.
*
Common code for xpath() and xmlexists()
*
* As we have no support of XQuery sequences yet, this function seems
* to be the most useful one (array of XML functions plays a role of
* some kind of substitution for XQuery sequences).
* Evaluate XPath expression and return number of nodes in res_items
* and array of XML values in astate.
*
* It is up to the user to ensure that the XML passed is in fact
* an XML document - XPath doesn't work easily on fragments without
* a context node being known.
*/
Datum
xpath
(
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
);
ArrayBuildState
*
astate
=
NULL
;
static
void
xpath_internal
(
text
*
xpath_expr_text
,
xmltype
*
data
,
ArrayType
*
namespaces
,
int
*
res_nitems
,
ArrayBuildState
**
astate
)
{
xmlParserCtxtPtr
ctxt
=
NULL
;
xmlDocPtr
doc
=
NULL
;
xmlXPathContextPtr
xpathctx
=
NULL
;
...
...
@@ -3324,7 +3320,6 @@ xpath(PG_FUNCTION_ARGS)
xmlChar
*
string
;
xmlChar
*
xpath_expr
;
int
i
;
int
res_nitems
;
int
ndim
;
Datum
*
ns_names_uris
;
bool
*
ns_names_uris_nulls
;
...
...
@@ -3339,7 +3334,7 @@ xpath(PG_FUNCTION_ARGS)
* ARRAY[ARRAY['myns', 'http://example.com'], ARRAY['myns2',
* 'http://example2.com']].
*/
ndim
=
ARR_NDIM
(
namespaces
)
;
ndim
=
namespaces
?
ARR_NDIM
(
namespaces
)
:
0
;
if
(
ndim
!=
0
)
{
int
*
dims
;
...
...
@@ -3439,6 +3434,13 @@ xpath(PG_FUNCTION_ARGS)
xml_ereport
(
ERROR
,
ERRCODE_INTERNAL_ERROR
,
"invalid XPath expression"
);
/*
* Version 2.6.27 introduces a function named
* xmlXPathCompiledEvalToBoolean, which would be enough for
* xmlexists, but we can derive the existence by whether any
* nodes are returned, thereby preventing a library version
* upgrade and keeping the code the same.
*/
xpathobj
=
xmlXPathCompiledEval
(
xpathcomp
,
xpathctx
);
if
(
xpathobj
==
NULL
)
/* TODO: reason? */
xml_ereport
(
ERROR
,
ERRCODE_INTERNAL_ERROR
,
...
...
@@ -3446,21 +3448,22 @@ xpath(PG_FUNCTION_ARGS)
/* return empty array in cases when nothing is found */
if
(
xpathobj
->
nodesetval
==
NULL
)
res_nitems
=
0
;
*
res_nitems
=
0
;
else
res_nitems
=
xpathobj
->
nodesetval
->
nodeNr
;
*
res_nitems
=
xpathobj
->
nodesetval
->
nodeNr
;
if
(
res_nitems
)
if
(
*
res_nitems
&&
astate
)
{
*
astate
=
NULL
;
for
(
i
=
0
;
i
<
xpathobj
->
nodesetval
->
nodeNr
;
i
++
)
{
Datum
elem
;
bool
elemisnull
=
false
;
elem
=
PointerGetDatum
(
xml_xmlnodetoxmltype
(
xpathobj
->
nodesetval
->
nodeTab
[
i
]));
astate
=
accumArrayResult
(
astate
,
elem
,
elemisnull
,
XMLOID
,
CurrentMemoryContext
);
*
astate
=
accumArrayResult
(
*
astate
,
elem
,
elemisnull
,
XMLOID
,
CurrentMemoryContext
);
}
}
}
...
...
@@ -3485,6 +3488,28 @@ xpath(PG_FUNCTION_ARGS)
xmlXPathFreeContext
(
xpathctx
);
xmlFreeDoc
(
doc
);
xmlFreeParserCtxt
(
ctxt
);
}
#endif
/* USE_LIBXML */
/*
* Evaluate XPath expression and return array of XML values.
*
* As we have no support of XQuery sequences yet, this function seems
* to be the most useful one (array of XML functions plays a role of
* some kind of substitution for XQuery sequences).
*/
Datum
xpath
(
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
;
ArrayBuildState
*
astate
;
xpath_internal
(
xpath_expr_text
,
data
,
namespaces
,
&
res_nitems
,
&
astate
);
if
(
res_nitems
==
0
)
PG_RETURN_ARRAYTYPE_P
(
construct_empty_array
(
XMLOID
));
...
...
@@ -3495,3 +3520,24 @@ xpath(PG_FUNCTION_ARGS)
return
0
;
#endif
}
/*
* Determines if the node specified by the supplied XPath exists
* in a given XML document, returning a boolean.
*/
Datum
xmlexists
(
PG_FUNCTION_ARGS
)
{
#ifdef USE_LIBXML
text
*
xpath_expr_text
=
PG_GETARG_TEXT_P
(
0
);
xmltype
*
data
=
PG_GETARG_XML_P
(
1
);
int
res_nitems
;
xpath_internal
(
xpath_expr_text
,
data
,
NULL
,
&
res_nitems
,
NULL
);
PG_RETURN_BOOL
(
res_nitems
>
0
);
#else
NO_XML_SUPPORT
();
return
0
;
#endif
}
src/include/catalog/catversion.h
View file @
641459f2
...
...
@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.58
8 2010/07/16 02:15:54 tgl
Exp $
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.58
9 2010/08/05 04:21:54 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 20100
71
51
#define CATALOG_VERSION_NO 20100
80
51
#endif
src/include/catalog/pg_proc.h
View file @
641459f2
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.57
3 2010/07/29 20:09:25 tgl
Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.57
4 2010/08/05 04:21:54 petere
Exp $
*
* NOTES
* The script catalog/genbki.pl reads this file and generates .bki
...
...
@@ -4391,6 +4391,9 @@ DESCR("evaluate XPath expression, with namespaces support");
DATA
(
insert
OID
=
2932
(
xpath
PGNSP
PGUID
14
1
0
0
f
f
f
t
f
i
2
0
143
"25 142"
_null_
_null_
_null_
_null_
"select pg_catalog.xpath($1, $2, ''{}''::pg_catalog.text[])"
_null_
_null_
_null_
));
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_
));
DESCR
(
"test XML value against XPath expression"
);
/* 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_
));
DESCR
(
"I/O"
);
...
...
src/include/parser/kwlist.h
View file @
641459f2
...
...
@@ -11,7 +11,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/include/parser/kwlist.h,v 1.1
2 2010/02/12 17:33:21 tgl
Exp $
* $PostgreSQL: pgsql/src/include/parser/kwlist.h,v 1.1
3 2010/08/05 04:21:54 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -280,6 +280,7 @@ PG_KEYWORD("owner", OWNER, UNRESERVED_KEYWORD)
PG_KEYWORD
(
"parser"
,
PARSER
,
UNRESERVED_KEYWORD
)
PG_KEYWORD
(
"partial"
,
PARTIAL
,
UNRESERVED_KEYWORD
)
PG_KEYWORD
(
"partition"
,
PARTITION
,
UNRESERVED_KEYWORD
)
PG_KEYWORD
(
"passing"
,
PASSING
,
UNRESERVED_KEYWORD
)
PG_KEYWORD
(
"password"
,
PASSWORD
,
UNRESERVED_KEYWORD
)
PG_KEYWORD
(
"placing"
,
PLACING
,
RESERVED_KEYWORD
)
PG_KEYWORD
(
"plans"
,
PLANS
,
UNRESERVED_KEYWORD
)
...
...
@@ -301,6 +302,7 @@ PG_KEYWORD("real", REAL, COL_NAME_KEYWORD)
PG_KEYWORD
(
"reassign"
,
REASSIGN
,
UNRESERVED_KEYWORD
)
PG_KEYWORD
(
"recheck"
,
RECHECK
,
UNRESERVED_KEYWORD
)
PG_KEYWORD
(
"recursive"
,
RECURSIVE
,
UNRESERVED_KEYWORD
)
PG_KEYWORD
(
"ref"
,
REF
,
UNRESERVED_KEYWORD
)
PG_KEYWORD
(
"references"
,
REFERENCES
,
RESERVED_KEYWORD
)
PG_KEYWORD
(
"reindex"
,
REINDEX
,
UNRESERVED_KEYWORD
)
PG_KEYWORD
(
"relative"
,
RELATIVE_P
,
UNRESERVED_KEYWORD
)
...
...
@@ -413,6 +415,7 @@ PG_KEYWORD("xml", XML_P, UNRESERVED_KEYWORD)
PG_KEYWORD
(
"xmlattributes"
,
XMLATTRIBUTES
,
COL_NAME_KEYWORD
)
PG_KEYWORD
(
"xmlconcat"
,
XMLCONCAT
,
COL_NAME_KEYWORD
)
PG_KEYWORD
(
"xmlelement"
,
XMLELEMENT
,
COL_NAME_KEYWORD
)
PG_KEYWORD
(
"xmlexists"
,
XMLEXISTS
,
COL_NAME_KEYWORD
)
PG_KEYWORD
(
"xmlforest"
,
XMLFOREST
,
COL_NAME_KEYWORD
)
PG_KEYWORD
(
"xmlparse"
,
XMLPARSE
,
COL_NAME_KEYWORD
)
PG_KEYWORD
(
"xmlpi"
,
XMLPI
,
COL_NAME_KEYWORD
)
...
...
src/include/utils/xml.h
View file @
641459f2
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.3
1 2010/03/03 17:29:45 tgl
Exp $
* $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.3
2 2010/08/05 04:21:54 petere
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -37,6 +37,7 @@ extern Datum texttoxml(PG_FUNCTION_ARGS);
extern
Datum
xmltotext
(
PG_FUNCTION_ARGS
);
extern
Datum
xmlvalidate
(
PG_FUNCTION_ARGS
);
extern
Datum
xpath
(
PG_FUNCTION_ARGS
);
extern
Datum
xmlexists
(
PG_FUNCTION_ARGS
);
extern
Datum
table_to_xml
(
PG_FUNCTION_ARGS
);
extern
Datum
query_to_xml
(
PG_FUNCTION_ARGS
);
...
...
src/test/regress/expected/xml.out
View file @
641459f2
...
...
@@ -502,3 +502,52 @@ SELECT xpath('//b', '<a>one <b>two</b> three <b>etc</b></a>');
{<b>two</b>,<b>etc</b>}
(1 row)
-- Test xmlexists evaluation
SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF '<towns><town>Bidford-on-Avon</town><town>Cwmbran</town><town>Bristol</town></towns>');
xmlexists
-----------
f
(1 row)
SELECT xmlexists('//town[text() = ''Cwmbran'']' PASSING BY REF '<towns><town>Bidford-on-Avon</town><town>Cwmbran</town><town>Bristol</town></towns>');
xmlexists
-----------
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 (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 (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);
count
-------
0
(1 row)
SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beer' PASSING BY REF data BY REF);
count
-------
0
(1 row)
SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beers' PASSING BY REF data);
count
-------
2
(1 row)
SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beers/name[text() = ''Molson'']' PASSING BY REF data);
count
-------
1
(1 row)
CREATE TABLE query ( expr TEXT );
INSERT INTO query VALUES ('/menu/beers/cost[text() = ''lots'']');
SELECT COUNT(id) FROM xmltest, query WHERE xmlexists(expr PASSING BY REF data);
count
-------
2
(1 row)
src/test/regress/expected/xml_1.out
View file @
641459f2
...
...
@@ -456,3 +456,72 @@ 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.
HINT: You need to rebuild PostgreSQL using --with-libxml.
-- Test xmlexists evaluation
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
LINE 1: ...sts('//town[text() = ''Toronto'']' PASSING BY REF '<towns><t...
^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT xmlexists('//town[text() = ''Cwmbran'']' PASSING BY REF '<towns><town>Bidford-on-Avon</town><town>Cwmbran</town><town>Bristol</town></towns>');
ERROR: unsupported XML feature
LINE 1: ...sts('//town[text() = ''Cwmbran'']' PASSING BY REF '<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);
ERROR: unsupported XML feature
LINE 1: INSERT INTO xmltest VALUES (4, '<menu><beers><name>Budvar</n...
^
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 (5, '<menu><beers><name>Molson</name><cost>free</cost><name>Carling</name><cost>lots</cost></beers></menu>'::xml);
ERROR: unsupported XML feature
LINE 1: INSERT INTO xmltest VALUES (5, '<menu><beers><name>Molson</n...
^
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 (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);
ERROR: unsupported XML feature
LINE 1: INSERT INTO xmltest VALUES (6, '<myns:menu xmlns:myns="http:...
^
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 (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);
ERROR: unsupported XML feature
LINE 1: INSERT INTO xmltest VALUES (7, '<myns:menu xmlns:myns="http:...
^
DETAIL: This functionality requires the server to be built with libxml support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beer' PASSING data);
count
-------
0
(1 row)
SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beer' PASSING BY REF data BY REF);
count
-------
0
(1 row)
SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beers' PASSING BY REF data);
count
-------
0
(1 row)
SELECT COUNT(id) FROM xmltest WHERE xmlexists('/menu/beers/name[text() = ''Molson'']' PASSING BY REF data);
count
-------
0
(1 row)
CREATE TABLE query ( expr TEXT );
INSERT INTO query VALUES ('/menu/beers/cost[text() = ''lots'']');
SELECT COUNT(id) FROM xmltest, query WHERE xmlexists(expr PASSING BY REF data);
count
-------
0
(1 row)
src/test/regress/sql/xml.sql
View file @
641459f2
...
...
@@ -163,3 +163,22 @@ SELECT xpath('', '<!-- error -->');
SELECT
xpath
(
'//text()'
,
'<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>'
);
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>'
);
-- Test xmlexists evaluation
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>'
);
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
(
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
);
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/beers'
PASSING
BY
REF
data
);
SELECT
COUNT
(
id
)
FROM
xmltest
WHERE
xmlexists
(
'/menu/beers/name[text() =
''
Molson
''
]'
PASSING
BY
REF
data
);
CREATE
TABLE
query
(
expr
TEXT
);
INSERT
INTO
query
VALUES
(
'/menu/beers/cost[text() =
''
lots
''
]'
);
SELECT
COUNT
(
id
)
FROM
xmltest
,
query
WHERE
xmlexists
(
expr
PASSING
BY
REF
data
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment