mirror of https://github.com/postgres/postgres
Add XMLText function (SQL/XML X038)
This function implements the standard XMLTest function, which converts text into xml text nodes. It uses the libxml2 function xmlEncodeSpecialChars to escape predefined entities (&"<>), so that those do not cause any conflict when concatenating the text node output with existing xml documents. This also adds a note in features.sgml about not supporting XML(SEQUENCE). The SQL specification defines a RETURNING clause to a set of XML functions, where RETURNING CONTENT or RETURNING SEQUENCE can be defined. Since PostgreSQL doesn't support XML(SEQUENCE) all of these functions operate with an implicit RETURNING CONTENT. Author: Jim Jones <jim.jones@uni-muenster.de> Reviewed-by: Vik Fearing <vik@postgresfriends.org> Discussion: https://postgr.es/m/86617a66-ec95-581f-8d54-08059cca8885@uni-muenster.de
This commit is contained in:
parent
7b5275eec3
commit
526fe0d799
|
@ -199,6 +199,15 @@
|
|||
standard.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
<productname>PostgreSQL</productname> does not support the
|
||||
<literal>RETURNING CONTENT</literal> or <literal>RETURNING SEQUENCE</literal>
|
||||
clauses, functions which are defined to have these in the specification
|
||||
are implicitly returning content.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
|
|
|
@ -14180,6 +14180,36 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
|
|||
documents for processing in client applications.
|
||||
</para>
|
||||
|
||||
<sect3 id="functions-producing-xml-xmltext">
|
||||
<title><literal>xmltext</literal></title>
|
||||
|
||||
<indexterm>
|
||||
<primary>xmltext</primary>
|
||||
</indexterm>
|
||||
|
||||
<synopsis>
|
||||
<function>xmltext</function> ( <type>text</type> ) <returnvalue>xml</returnvalue>
|
||||
</synopsis>
|
||||
|
||||
<para>
|
||||
The function <function>xmltext</function> returns an XML value with a single
|
||||
text node containing the input argument as its content. Predefined entities
|
||||
like ampersand (<literal><![CDATA[&]]></literal>), left and right angle brackets
|
||||
(<literal><![CDATA[< >]]></literal>), and quotation marks (<literal><![CDATA[""]]></literal>)
|
||||
are escaped.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Example:
|
||||
<screen><![CDATA[
|
||||
SELECT xmltext('< foo & bar >');
|
||||
xmltext
|
||||
-------------------------
|
||||
< foo & bar >
|
||||
]]></screen>
|
||||
</para>
|
||||
</sect3>
|
||||
|
||||
<sect3 id="functions-producing-xml-xmlcomment">
|
||||
<title><literal>xmlcomment</literal></title>
|
||||
|
||||
|
|
|
@ -633,7 +633,7 @@ X034 XMLAgg YES
|
|||
X035 XMLAgg: ORDER BY option YES
|
||||
X036 XMLComment YES
|
||||
X037 XMLPI YES
|
||||
X038 XMLText NO
|
||||
X038 XMLText YES supported except for RETURNING
|
||||
X040 Basic table mapping YES
|
||||
X041 Basic table mapping: null absent YES
|
||||
X042 Basic table mapping: null as nil YES
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
|
||||
#ifdef USE_LIBXML
|
||||
#include <libxml/chvalid.h>
|
||||
#include <libxml/entities.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/parserInternals.h>
|
||||
#include <libxml/tree.h>
|
||||
|
@ -513,6 +514,27 @@ xmlcomment(PG_FUNCTION_ARGS)
|
|||
}
|
||||
|
||||
|
||||
Datum
|
||||
xmltext(PG_FUNCTION_ARGS)
|
||||
{
|
||||
#ifdef USE_LIBXML
|
||||
text *arg = PG_GETARG_TEXT_PP(0);
|
||||
text *result;
|
||||
xmlChar *xmlbuf = NULL;
|
||||
|
||||
xmlbuf = xmlEncodeSpecialChars(NULL, xml_text2xmlChar(arg));
|
||||
|
||||
Assert(xmlbuf);
|
||||
|
||||
result = cstring_to_text_with_len((const char *) xmlbuf, xmlStrlen(xmlbuf));
|
||||
xmlFree(xmlbuf);
|
||||
PG_RETURN_XML_P(result);
|
||||
#else
|
||||
NO_XML_SUPPORT();
|
||||
return 0;
|
||||
#endif /* not USE_LIBXML */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* TODO: xmlconcat needs to merge the notations and unparsed entities
|
||||
|
|
|
@ -8793,6 +8793,9 @@
|
|||
{ oid => '2922', descr => 'serialize an XML value to a character string',
|
||||
proname => 'text', prorettype => 'text', proargtypes => 'xml',
|
||||
prosrc => 'xmltotext' },
|
||||
{ oid => '3813', descr => 'generate XML text node',
|
||||
proname => 'xmltext', proisstrict => 't', prorettype => 'xml',
|
||||
proargtypes => 'text', prosrc => 'xmltext' },
|
||||
|
||||
{ oid => '2923', descr => 'map table contents to XML',
|
||||
proname => 'table_to_xml', procost => '100', provolatile => 's',
|
||||
|
|
|
@ -1785,3 +1785,39 @@ SELECT * FROM XMLTABLE('.' PASSING XMLELEMENT(NAME a) columns a varchar(20) PATH
|
|||
<foo/> | <foo/>
|
||||
(1 row)
|
||||
|
||||
SELECT xmltext(NULL);
|
||||
xmltext
|
||||
---------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT xmltext('');
|
||||
xmltext
|
||||
---------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT xmltext(' ');
|
||||
xmltext
|
||||
---------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT xmltext('foo `$_-+?=*^%!|/\()[]{}');
|
||||
xmltext
|
||||
--------------------------
|
||||
foo `$_-+?=*^%!|/\()[]{}
|
||||
(1 row)
|
||||
|
||||
SELECT xmltext('foo & <"bar">');
|
||||
xmltext
|
||||
-----------------------------------
|
||||
foo & <"bar">
|
||||
(1 row)
|
||||
|
||||
SELECT xmltext('x'|| '<P>73</P>'::xml || .42 || true || 'j'::char);
|
||||
xmltext
|
||||
---------------------------------
|
||||
x<P>73</P>0.42truej
|
||||
(1 row)
|
||||
|
||||
|
|
|
@ -1402,3 +1402,26 @@ DETAIL: This functionality requires the server to be built with libxml support.
|
|||
SELECT * FROM XMLTABLE('.' PASSING XMLELEMENT(NAME a) columns a varchar(20) PATH '"<foo/>"', b xml PATH '"<foo/>"');
|
||||
ERROR: unsupported XML feature
|
||||
DETAIL: This functionality requires the server to be built with libxml support.
|
||||
SELECT xmltext(NULL);
|
||||
xmltext
|
||||
---------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT xmltext('');
|
||||
ERROR: unsupported XML feature
|
||||
DETAIL: This functionality requires the server to be built with libxml support.
|
||||
SELECT xmltext(' ');
|
||||
ERROR: unsupported XML feature
|
||||
DETAIL: This functionality requires the server to be built with libxml support.
|
||||
SELECT xmltext('foo `$_-+?=*^%!|/\()[]{}');
|
||||
ERROR: unsupported XML feature
|
||||
DETAIL: This functionality requires the server to be built with libxml support.
|
||||
SELECT xmltext('foo & <"bar">');
|
||||
ERROR: unsupported XML feature
|
||||
DETAIL: This functionality requires the server to be built with libxml support.
|
||||
SELECT xmltext('x'|| '<P>73</P>'::xml || .42 || true || 'j'::char);
|
||||
ERROR: unsupported XML feature
|
||||
LINE 1: SELECT xmltext('x'|| '<P>73</P>'::xml || .42 || true || 'j':...
|
||||
^
|
||||
DETAIL: This functionality requires the server to be built with libxml support.
|
||||
|
|
|
@ -1765,3 +1765,39 @@ SELECT * FROM XMLTABLE('.' PASSING XMLELEMENT(NAME a) columns a varchar(20) PATH
|
|||
<foo/> | <foo/>
|
||||
(1 row)
|
||||
|
||||
SELECT xmltext(NULL);
|
||||
xmltext
|
||||
---------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT xmltext('');
|
||||
xmltext
|
||||
---------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT xmltext(' ');
|
||||
xmltext
|
||||
---------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT xmltext('foo `$_-+?=*^%!|/\()[]{}');
|
||||
xmltext
|
||||
--------------------------
|
||||
foo `$_-+?=*^%!|/\()[]{}
|
||||
(1 row)
|
||||
|
||||
SELECT xmltext('foo & <"bar">');
|
||||
xmltext
|
||||
-----------------------------------
|
||||
foo & <"bar">
|
||||
(1 row)
|
||||
|
||||
SELECT xmltext('x'|| '<P>73</P>'::xml || .42 || true || 'j'::char);
|
||||
xmltext
|
||||
---------------------------------
|
||||
x<P>73</P>0.42truej
|
||||
(1 row)
|
||||
|
||||
|
|
|
@ -660,3 +660,10 @@ SELECT * FROM XMLTABLE('*' PASSING '<e>pre<!--c1--><?pi arg?><![CDATA[&ent1]]><n
|
|||
\x
|
||||
|
||||
SELECT * FROM XMLTABLE('.' PASSING XMLELEMENT(NAME a) columns a varchar(20) PATH '"<foo/>"', b xml PATH '"<foo/>"');
|
||||
|
||||
SELECT xmltext(NULL);
|
||||
SELECT xmltext('');
|
||||
SELECT xmltext(' ');
|
||||
SELECT xmltext('foo `$_-+?=*^%!|/\()[]{}');
|
||||
SELECT xmltext('foo & <"bar">');
|
||||
SELECT xmltext('x'|| '<P>73</P>'::xml || .42 || true || 'j'::char);
|
Loading…
Reference in New Issue